refactor(Chat, Communities): replace `TopBar` with `StatusChatToolBar`

This commit replaces the `TopBar` components with StatusQ's `StatusChatToolBar`
and touches a few other things as part of this refactoring, namely:

1. `ChannelContextMenu` has been renamed to `ChatContextMenu` and is now a `StatusPopupMenu`
2. Leftover components have been removed: `StatusChatInfo`, `StatusChatInfoButton` and `TopBar`
3 `ActivityCenter` has been moved into `ChatColumn.qml` because `StatusChatToolBar` doesn't provide it
4. `Share chat` option in `ChatContextMenu` has been removed as it wasn't doing anything.

Closes #2746
This commit is contained in:
Pascal Precht 2021-07-06 11:42:51 +02:00 committed by Iuri Matias
parent c675aff0f8
commit a69c2aea73
10 changed files with 219 additions and 774 deletions

View File

@ -2,6 +2,12 @@ import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.0
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import "../../../shared"
import "../../../shared/status"
import "../../../imports"
@ -222,11 +228,79 @@ StackLayout {
ColumnLayout {
spacing: 0
TopBar {
StatusChatToolBar {
id: topBar
z: 60
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
Layout.fillWidth: true
property string chatId: chatsModel.channelView.activeChannel.id
property string profileImage: appMain.getProfileImage(chatId) || ""
chatInfoButton.title: {
if (chatsModel.channelView.activeChannel.chatType === Constants.chatTypeOneToOne) {
return Utils.removeStatusEns(chatsModel.userNameOrAlias(chatsModel.channelView.activeChannel.id))
}
return chatsModel.channelView.activeChannel.name
}
chatInfoButton.subTitle: {
switch (chatsModel.channelView.activeChannel.chatType) {
case Constants.chatTypeOneToOne:
return (profileModel.contacts.isAdded(topBar.chatId) ?
profileModel.contacts.contactRequestReceived(topBar.chatId) ?
qsTr("Contact") :
qsTr("Contact request pending") :
qsTr("Not a contact"))
break;
case Constants.chatTypePublic:
return qsTr("Public chat")
case Constants.chatTypePrivateGroupChat:
let cnt = chatsModel.channelView.activeChannel.members.rowCount();
if(cnt > 1) return qsTr("%1 members").arg(cnt);
return qsTr("1 member");
break;
case Constants.chatTypeCommunity:
default:
return ""
break;
}
}
chatInfoButton.image.source: profileImage || chatsModel.channelView.activeChannel.identicon
chatInfoButton.image.isIdenticon: !!!profileImage && chatsModel.channelView.activeChannel.identicon
chatInfoButton.icon.color: chatsModel.channelView.activeChannel.color
chatInfoButton.type: chatsModel.channelView.activeChannel.chatType
chatInfoButton.pinnedMessagesCount: chatsModel.messageView.pinnedMessagesList.count
chatInfoButton.muted: chatsModel.channelView.activeChannel.muted
chatInfoButton.onPinnedMessagesCountClicked: openPopup(pinnedMessagesPopupComponent)
chatInfoButton.onUnmute: chatsModel.channelView.unmuteChatItem(chatsModel.channelView.activeChannel.id)
chatInfoButton.sensor.enabled: chatsModel.channelView.activeChannel.chatType !== Constants.chatTypePublic &&
chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeCommunity
chatInfoButton.onClicked: {
switch (chatsModel.channelView.activeChannel.chatType) {
case Constants.chatTypePrivateGroupChat:
openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ActiveChannel})
break;
case Constants.chatTypeOneToOne:
openProfilePopup(chatsModel.userNameOrAlias(chatsModel.channelView.activeChannel.id),
chatsModel.channelView.activeChannel.id, profileImage || chatsModel.channelView.activeChannel.identicon,
"", chatsModel.channelView.activeChannel.nickname)
break;
}
}
searchButton.visible: false
membersButton.visible: appSettings.showOnlineUsers && chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne
notificationButton.visible: appSettings.isActivityCenterEnabled
notificationCount: chatsModel.activityNotificationList.unreadCount
onMembersButtonClicked: showUsers = !showUsers
onNotificationButtonClicked: activityCenter.open()
popupMenu: ChatContextMenu {
openHandler: {
chatItem = chatsModel.channelView.activeChannel
}
}
}
Rectangle {
@ -527,6 +601,12 @@ StackLayout {
selectRecipient.selectedType: RecipientSelector.Type.Contact
}
}
ActivityCenter {
id: activityCenter
height: chatColumnLayout.height - (topBar.height * 2) // TODO get screen size
y: topBar.height
}
}
/*##^##

View File

@ -31,12 +31,10 @@ Popup {
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
parent: Overlay.overlay
width: 560
height: chatColumnLayout.height - (chatTopBarContent.height * 2) // TODO get screen size
background: Rectangle {
color: Style.current.background
radius: Style.current.radius
}
y: chatTopBarContent.height
x: applicationWindow.width - activityCenter.width - Style.current.halfPadding
onOpened: {
popupOpened = true

View File

@ -1,212 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../../shared"
import "../../../../shared/status"
import "../../../../imports"
import "../components"
Item {
property int iconSize: 16
id: chatTopBarContent
height: 56
Loader {
property bool isGroupChatOrOneToOne: (chatsModel.channelView.activeChannel.chatType === Constants.chatTypePrivateGroupChat ||
chatsModel.channelView.activeChannel.chatType === Constants.chatTypeOneToOne)
anchors.left: parent.left
anchors.leftMargin: this.isGroupChatOrOneToOne ? Style.current.padding : Style.current.padding + 4
anchors.top: parent.top
anchors.topMargin: 4
sourceComponent: this.isGroupChatOrOneToOne ? chatInfoButton : chatInfo
}
Component {
id: chatInfoButton
StatusChatInfoButton {
chatId: chatsModel.channelView.activeChannel.id
chatName: {
if (chatsModel.channelView.activeChannel.chatType === Constants.chatTypePrivateGroupChat) {
return chatsModel.channelView.activeChannel.name
}
chatsModel.userNameOrAlias(chatsModel.channelView.activeChannel.id)
}
chatType: chatsModel.channelView.activeChannel.chatType
identicon: chatsModel.channelView.activeChannel.identicon
muted: chatsModel.channelView.activeChannel.muted
identiconSize: 36
onClicked: {
switch (chatsModel.channelView.activeChannel.chatType) {
case Constants.chatTypePrivateGroupChat:
openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ActiveChannel})
break;
case Constants.chatTypeOneToOne:
const profileImage = appMain.getProfileImage(chatsModel.channelView.activeChannel.id)
openProfilePopup(chatsModel.userNameOrAlias(chatsModel.channelView.activeChannel.id),
chatsModel.channelView.activeChannel.id, profileImage || chatsModel.channelView.activeChannel.identicon,
"", chatsModel.channelView.activeChannel.nickname)
break;
}
}
}
}
Component {
id: chatInfo
StatusChatInfo {
identiconSize: 36
chatId: chatsModel.channelView.activeChannel.id
chatName: chatsModel.channelView.activeChannel.name
chatType: chatsModel.channelView.activeChannel.chatType
identicon: chatsModel.channelView.activeChannel.identicon
muted: chatsModel.channelView.activeChannel.muted
}
}
Row {
height: parent.height
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
spacing: 12
StatusIconButton {
id: showUsersBtn
anchors.verticalCenter: parent.verticalCenter
icon.name: "channel-icon-group"
iconColor: showUsers ? Style.current.contextMenuButtonForegroundColor : Style.current.contextMenuButtonBackgroundHoverColor
hoveredIconColor: Style.current.contextMenuButtonForegroundColor
highlightedBackgroundColor: Style.current.contextMenuButtonBackgroundHoverColor
onClicked: {
showUsers = !showUsers
}
visible: appSettings.showOnlineUsers && chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne
}
StatusContextMenuButton {
id: moreActionsBtn
anchors.verticalCenter: parent.verticalCenter
onClicked: {
var menu = chatContextMenu;
var isPrivateGroupChat = chatsModel.channelView.activeChannel.chatType === Constants.chatTypePrivateGroupChat
if(isPrivateGroupChat){
menu = groupContextMenu
}
if (menu.opened) {
return menu.close()
}
if (isPrivateGroupChat) {
menu.popup(moreActionsBtn.x, moreActionsBtn.height)
} else {
menu.openMenu(chatsModel.channelView.activeChannel, chatsModel.channelView.getActiveChannelIdx(),
moreActionsBtn.x - chatContextMenu.width + moreActionsBtn.width + 4,
moreActionsBtn.height - 4)
}
}
ChannelContextMenu {
id: chatContextMenu
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
}
PopupMenu {
id: groupContextMenu
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
Action {
icon.source: "../../../img/group_chat.svg"
icon.width: chatTopBarContent.iconSize
icon.height: chatTopBarContent.iconSize
//% "Group Information"
text: qsTrId("group-information")
onTriggered: openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ActiveChannel })
}
Action {
icon.source: "../../../img/close.svg"
icon.width: chatTopBarContent.iconSize
icon.height: chatTopBarContent.iconSize
//% "Clear History"
text: qsTrId("clear-history")
onTriggered: chatsModel.channelView.clearChatHistory(chatsModel.channelView.activeChannel.id)
}
Action {
icon.source: "../../../img/leave_chat.svg"
icon.width: chatTopBarContent.iconSize
icon.height: chatTopBarContent.iconSize
//% "Leave group"
text: qsTrId("leave-group")
onTriggered: {
//% "Leave group"
deleteChatConfirmationDialog.title = qsTrId("leave-group")
//% "Leave group"
deleteChatConfirmationDialog.confirmButtonLabel = qsTrId("leave-group")
//% "Are you sure you want to leave this chat?"
deleteChatConfirmationDialog.confirmationText = qsTrId("are-you-sure-you-want-to-leave-this-chat-")
deleteChatConfirmationDialog.open()
}
}
}
}
Rectangle {
id: separator
visible: activityCenterBtn.visible
width: 1
height: 24
color: Style.current.separator
anchors.verticalCenter: parent.verticalCenter
}
StatusIconButton {
id: activityCenterBtn
visible: appSettings.isActivityCenterEnabled
icon.name: "bell"
iconColor: Style.current.contextMenuButtonForegroundColor
hoveredIconColor: Style.current.contextMenuButtonForegroundColor
highlightedBackgroundColor: Style.current.contextMenuButtonBackgroundHoverColor
anchors.verticalCenter: parent.verticalCenter
onClicked: activityCenter.open()
Rectangle {
property int nbUnseenNotifs: chatsModel.activityNotificationList.unreadCount
id: badge
visible: nbUnseenNotifs > 0
anchors.top: parent.top
anchors.topMargin: -2
anchors.left: parent.right
anchors.leftMargin: -17
radius: height / 2
color: Style.current.blue
border.color: activityCenterBtn.hovered ? Style.current.secondaryBackground : Style.current.background
border.width: 2
width: badge.nbUnseenNotifs < 10 ? 18 : badgeText.width + 14
height: 18
Text {
id: badgeText
font.pixelSize: 12
color: Style.current.white
anchors.centerIn: parent
text: badge.nbUnseenNotifs
}
}
}
}
ActivityCenter {
id: activityCenter
}
ConfirmationDialog {
id: deleteChatConfirmationDialog
btnType: "warn"
onConfirmButtonClicked: {
chatsModel.channelView.leaveActiveChat()
deleteChatConfirmationDialog.close()
}
}
}

View File

@ -10,6 +10,7 @@ import StatusQ.Popups 0.1
import "../../../imports"
import "../../../shared"
import "../../../shared/status"
import "./components"
import "./CommunityComponents"
@ -196,48 +197,10 @@ Item {
}
}
chatListPopupMenu: StatusPopupMenu {
property var chatItem
chatListPopupMenu: ChatContextMenu {
openHandler: function (id) {
chatItem = chatsModel.channelView.getChatItemById(id)
}
StatusMenuItem {
text: chatItem && chatItem.muted ?
qsTr("Unmute chat") :
qsTr("Mute chat")
icon.name: "notification"
onTriggered: {
if (chatItem && chatItem.muted) {
return chatsModel.channelView.unmuteChatItem(chatItem.id)
}
chatsModel.channelView.muteChatItem(chatItem.id)
}
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
onTriggered: chatsModel.channelView.markChatItemAsRead(chatItem.id)
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
onTriggered: chatsModel.channelView.clearChatHistory(chatItem.id)
}
StatusMenuItem {
text: qsTr("Edit Channel")
icon.name: "edit"
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: openPopup(editChannelPopup, {
communityId: chatsModel.communities.activeCommunity.id,
channel: chatItem
})
}
}
}

View File

@ -141,91 +141,10 @@ Item {
onChatItemSelected: chatsModel.channelView.setActiveChannel(id)
onChatItemUnmuted: chatsModel.channelView.unmuteChatItem(id)
popupMenu: StatusPopupMenu {
id: chatListContextMenu
property var chatItem
popupMenu: ChatContextMenu {
openHandler: function (id) {
chatItem = chatsModel.channelView.getChatItemById(id)
}
StatusMenuItem {
id: viewProfileMenuItem
text: {
if (chatItem) {
switch (chatItem.chatType) {
case Constants.chatTypeOneToOne:
return qsTr("View Profile")
break;
case Constants.chatTypePrivateGroupChat:
return qsTr("View Group")
break;
default:
return qsTr("Share Chat")
break;
}
}
return ""
}
icon.name: "group-chat"
enabled: chatItem && chatItem.chatType !== Constants.chatTypePublic
onTriggered: {
if (chatItem.chatType === Constants.chatTypeOneToOne) {
const userProfileImage = appMain.getProfileImage(chatItem.id)
return openProfilePopup(
chatItem.name,
chatItem.id,
userProfileImage || chatItem.identicon
)
}
if (chatItem.chatType === Constants.chatTypePrivateGroupChat) {
return openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ContextChannel})
}
}
}
StatusMenuSeparator {
visible: viewProfileMenuItem.enabled
}
StatusMenuItem {
text: chatItem && chatItem.muted ?
qsTr("Unmute chat") :
qsTr("Mute chat")
icon.name: "notification"
onTriggered: {
if (chatItem && chatItem.muted) {
return chatsModel.channelView.unmuteChatItem(chatItem.id)
}
chatsModel.channelView.muteChatItem(chatItem.id)
}
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
onTriggered: chatsModel.channelView.markChatItemAsRead(chatItem.id)
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
onTriggered: chatsModel.channelView.clearChatHistory(chatItem.id)
}
StatusMenuSeparator {}
StatusMenuItem {
text: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? "Delete chat" : "Leave chat"
icon.name: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? "delete" : "arrow-right"
icon.width: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? 18 : 14
iconRotation: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? 0 : 180
type: StatusMenuItem.Type.Danger
onTriggered: openPopup(deleteChatConfirmationDialogComponent, { chatId: chatItem.id })
}
}
}
@ -309,23 +228,6 @@ Item {
}
}
}
Component {
id: deleteChatConfirmationDialogComponent
ConfirmationDialog {
property string chatId
btnType: "warn"
confirmationText: qsTr("Are you sure you want to leave this chat?")
onClosed: {
destroy()
}
onConfirmButtonClicked: {
chatsModel.channelView.leaveChat(chatId)
close();
}
}
}
}
/*##^##

View File

@ -1,164 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "./"
import "../../../../shared"
import "../../../../imports"
PopupMenu {
property int channelIndex
property var contextChannel: ({})
id: channelContextMenu
width: 175
subMenuIcons: [
/* { */
/* source: Qt.resolvedUrl("../../../img/bell.svg"), */
/* width: 16, */
/* height: 16 */
/* }, */
{
source: Qt.resolvedUrl("../../../img/fetch.svg"),
width: 16,
height: 16
}
]
function openMenu(channel, index, x, y) {
channelContextMenu.contextChannel = channel
if (index !== undefined) {
channelContextMenu.channelIndex = index
}
channelContextMenu.popup(x, y)
}
Action {
id: viewProfileButton
enabled: channelContextMenu.contextChannel.chatType !== Constants.chatTypePublic
text: {
if (channelContextMenu.contextChannel.chatType === Constants.chatTypeOneToOne) {
//% "View Profile"
return qsTrId("view-profile")
}
if (channelContextMenu.contextChannel.chatType === Constants.chatTypePrivateGroupChat) {
//% "View Group"
return qsTrId("view-group")
}
//% "Share Chat"
return qsTrId("share-chat")
}
icon.source: "../../../img/group.svg"
icon.width: 16
icon.height: 16
onTriggered: {
if (channelContextMenu.contextChannel.chatType === Constants.chatTypeOneToOne) {
const userProfileImage = appMain.getProfileImage(channelContextMenu.contextChannel.id)
return openProfilePopup(
channelContextMenu.contextChannel.name,
channelContextMenu.contextChannel.id,
userProfileImage || channelContextMenu.contextChannel.identicon
)
}
if (channelContextMenu.contextChannel.chatType === Constants.chatTypePrivateGroupChat) {
return openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ContextChannel})
}
}
}
Separator {
visible: viewProfileButton.enabled
}
Action {
text: channelContextMenu.contextChannel.muted ?
//% "Unmute chat"
qsTrId("unmute-chat") :
//% "Mute chat"
qsTrId("mute-chat")
icon.source: "../../../img/bell.svg"
icon.width: 16
icon.height: 16
onTriggered: {
if (chatsModel.channelView.channelIsMuted(channelContextMenu.channelIndex)) {
chatsModel.channelView.unmuteChannel(channelContextMenu.channelIndex)
return
}
chatsModel.channelView.muteChannel(channelContextMenu.channelIndex)
}
}
Action {
//% "Mark as Read"
text: qsTrId("mark-as-read")
icon.source: "../../../img/check-circle.svg"
icon.width: 16
icon.height: 16
onTriggered: {
chatsModel.channelView.markAllChannelMessagesReadByIndex(channelContextMenu.channelIndex)
}
}
// FetchMoreMessages {} // TODO: disabling it temporarily because wakuext_syncChatFromSyncedFrom does not support specifying a date range
Action {
//% "Clear History"
text: qsTrId("clear-history")
icon.source: "../../../img/close.svg"
icon.width: 16
icon.height: 16
onTriggered: chatsModel.channelView.clearChatHistoryByIndex(channelContextMenu.channelIndex)
}
Action {
enabled: chatsModel.communities.activeCommunity.active && chatsModel.communities.activeCommunity.admin
text: qsTr("Edit Channel")
icon.source: "../../../img/edit.svg"
icon.width: 16
icon.height: 16
onTriggered: openPopup(editChannelPopup, {communityId: chatsModel.communities.activeCommunity.id, channel: chatsModel.channelView.activeChannel})
}
Separator {
visible: deleteAction.enabled
}
Action {
id: deleteAction
text: {
if (channelContextMenu.contextChannel.chatType === Constants.chatTypeOneToOne) {
//% "Delete chat"
return qsTrId("delete-chat")
}
if (channelContextMenu.contextChannel.chatType === Constants.chatTypePrivateGroupChat) {
//% "Leave group"
return qsTrId("leave-group")
}
//% "Leave chat"
return qsTrId("leave-chat")
}
icon.source: {
if (channelContextMenu.contextChannel.chatType === Constants.chatTypeOneToOne) {
return "../../../img/delete.svg"
}
return "../../../img/leave_chat.svg"
}
icon.width: 16
icon.height: 16
icon.color: Style.current.red
onTriggered: openPopup(deleteChatConfirmationDialogComponent)
enabled: !chatsModel.communities.activeCommunity.active
}
Component {
id: deleteChatConfirmationDialogComponent
ConfirmationDialog {
btnType: "warn"
confirmationText: qsTr("Are you sure you want to leave this chat?")
onClosed: {
destroy()
}
onConfirmButtonClicked: {
chatsModel.channelView.leaveChatByIndex(channelContextMenu.channelIndex)
close();
}
}
}
}

View File

@ -0,0 +1,133 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "./"
import "../../../../shared"
import "../../../../imports"
import StatusQ.Popups 0.1
StatusPopupMenu {
property var chatItem
StatusMenuItem {
id: viewProfileMenuItem
text: {
if (chatItem) {
switch (chatItem.chatType) {
case Constants.chatTypeOneToOne:
return qsTr("View Profile")
break;
case Constants.chatTypePrivateGroupChat:
return qsTr("View Group")
break;
}
}
return ""
}
icon.name: "group-chat"
enabled: chatItem &&
(chatItem.chatType === Constants.chatTypeOneToOne ||
chatItem.chatType === Constants.chatTypePrivateGroupChat)
onTriggered: {
if (chatItem.chatType === Constants.chatTypeOneToOne) {
const userProfileImage = appMain.getProfileImage(chatItem.id)
return openProfilePopup(
chatItem.name,
chatItem.id,
userProfileImage || chatItem.identicon
)
}
if (chatItem.chatType === Constants.chatTypePrivateGroupChat) {
return openPopup(groupInfoPopupComponent, {channelType: GroupInfoPopup.ChannelType.ContextChannel})
}
}
}
StatusMenuSeparator {
visible: viewProfileMenuItem.enabled
}
StatusMenuItem {
text: chatItem && chatItem.muted ?
qsTr("Unmute chat") :
qsTr("Mute chat")
icon.name: "notification"
enabled: chatItem && chatItem.chatType !== Constants.chatTypePrivateGroupChat
onTriggered: {
if (chatItem && chatItem.muted) {
return chatsModel.channelView.unmuteChatItem(chatItem.id)
}
chatsModel.channelView.muteChatItem(chatItem.id)
}
}
StatusMenuItem {
text: qsTr("Mark as Read")
icon.name: "checkmark-circle"
enabled: chatItem && chatItem.chatType !== Constants.chatTypePrivateGroupChat
onTriggered: chatsModel.channelView.markChatItemAsRead(chatItem.id)
}
StatusMenuItem {
text: qsTr("Clear history")
icon.name: "close-circle"
onTriggered: chatsModel.channelView.clearChatHistory(chatItem.id)
}
StatusMenuItem {
text: qsTr("Edit Channel")
icon.name: "edit"
enabled: chatsModel.communities.activeCommunity.active &&
chatsModel.communities.activeCommunity.admin
onTriggered: openPopup(editChannelPopup, {
communityId: chatsModel.communities.activeCommunity.id,
channel: chatItem
})
}
StatusMenuSeparator {
visible: deleteOrLeaveMenuItem.enabled
}
StatusMenuItem {
id: deleteOrLeaveMenuItem
text: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ?
qsTr("Delete chat") :
qsTr("Leave chat")
icon.name: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? "delete" : "arrow-right"
icon.width: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? 18 : 14
iconRotation: chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? 0 : 180
type: StatusMenuItem.Type.Danger
onTriggered: {
let label = chatItem && chatItem.chatType === Constants.chatTypeOneToOne ?
qsTr("Delete chat") :
qsTr("Leave chat")
openPopup(deleteChatConfirmationDialogComponent, {
title: label,
confirmButtonLabel: label,
chatId: chatItem.id
})
}
enabled: !chatsModel.communities.activeCommunity.active
}
Component {
id: deleteChatConfirmationDialogComponent
ConfirmationDialog {
property string chatId
btnType: "warn"
confirmationText: qsTr("Are you sure you want to leave this chat?")
onClosed: {
destroy()
}
onConfirmButtonClicked: {
chatsModel.channelView.leaveChat(chatId)
close();
}
}
}
}

View File

@ -1,204 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import "../../imports"
import "../../shared"
import "../../shared/status"
Item {
id: root
property string chatId
property string chatName
property int chatType
property int realChatType: {
if (chatType === Constants.chatTypeCommunity) {
// TODO add a check for private community chats once it is created
return Constants.chatTypePublic
}
return chatType
}
property string identicon
property int identiconSize: 40
property bool isCompact: false
property bool muted: false
property string profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : ""
height: 48
Connections {
enabled: realChatType === Constants.chatTypeOneToOne
target: profileModel.contacts.list
onContactChanged: {
if (pubkey === root.chatId) {
root.profileImage = appMain.getProfileImage(root.chatId) || ""
}
}
}
StatusIdenticon {
id: chatIdenticon
chatType: root.realChatType
chatId: root.chatId
chatName: root.chatName
identicon: root.profileImage || root.identicon
width: root.isCompact ? 20 : root.identiconSize
height: root.isCompact ? 20 : root.identiconSize
anchors.verticalCenter: parent.verticalCenter
}
Item {
id: nameAndInfo
height: chatName.height + chatInfo.height
width: parent.width
anchors.verticalCenter: parent.verticalCenter
anchors.left: chatIdenticon.right
anchors.leftMargin: Style.current.smallPadding
StyledText {
id: chatName
text: {
switch(root.realChatType) {
case Constants.chatTypePublic: return "#" + root.chatName;
case Constants.chatTypeOneToOne: return Utils.removeStatusEns(root.chatName)
default: return root.chatName
}
}
font.weight: Font.Medium
font.pixelSize: 15
}
SVGImage {
property bool hovered: false
id: bellImg
visible: root.muted
source: "../../app/img/bell-disabled.svg"
anchors.verticalCenter: chatName.verticalCenter
anchors.left: chatName.right
anchors.leftMargin: 4
width: 12.5
height: 12.5
ColorOverlay {
anchors.fill: parent
source: parent
color: bellImg.hovered ? Style.current.textColor : Style.current.darkGrey
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: bellImg.hovered = true
onExited: bellImg.hovered = false
onClicked: {
chatsModel.channelView.unmuteCurrentChannel()
}
}
}
Connections {
target: profileModel.contacts
onContactChanged: {
if(root.chatId === publicKey){
// Hack warning: Triggering reload to avoid changing the current text binding
var tmp = chatId;
chatId = "";
chatId = tmp;
}
}
}
StyledText {
id: chatInfo
color: Style.current.secondaryText
width: topBar.childrenRect.width - 200
elide: Text.ElideRight
text: {
if (root.chatType === Constants.chatTypeCommunity) {
return chatsModel.channelView.activeChannel.description
}
switch(root.realChatType){
//% "Public chat"
case Constants.chatTypePublic: return qsTrId("public-chat")
case Constants.chatTypeOneToOne: return (profileModel.contacts.isAdded(root.chatId) ?
profileModel.contacts.contactRequestReceived(root.chatId) ?
//% "Contact"
qsTrId("chat-is-a-contact") :
qsTr("Contact request pending") :
//% "Not a contact"
qsTrId("chat-is-not-a-contact"))
case Constants.chatTypePrivateGroupChat:
let cnt = chatsModel.channelView.activeChannel.members.rowCount();
//% "%1 members"
if(cnt > 1) return qsTrId("%1-members").arg(cnt);
//% "1 member"
return qsTrId("1-member");
default: return "...";
}
}
font.pixelSize: 12
anchors.top: chatName.bottom
anchors.topMargin: 2
anchors.left: chatName.left
}
Item {
property bool hovered: false
id: pinnedMessagesGroup
visible: chatType !== Constants.chatTypePublic && chatsModel.messageView.pinnedMessagesList.count > 0
width: childrenRect.width
height: vertiSep.height
anchors.left: chatInfo.right
anchors.leftMargin: 4
anchors.verticalCenter: chatInfo.verticalCenter
Rectangle {
id: vertiSep
height: 12
width: 1
color: Style.current.border
}
SVGImage {
id: pinImg
source: "../../app/img/pin.svg"
height: 14
width: 14
anchors.left: vertiSep.right
anchors.leftMargin: 4
anchors.verticalCenter: vertiSep.verticalCenter
ColorOverlay {
anchors.fill: parent
source: parent
color: pinnedMessagesGroup.hovered ? Style.current.textColor : Style.current.secondaryText
}
}
StyledText {
id: nbPinnedMessagesText
color: pinnedMessagesGroup.hovered ? Style.current.textColor : Style.current.secondaryText
text: chatsModel.messageView.pinnedMessagesList.count
font.pixelSize: 12
font.underline: pinnedMessagesGroup.hovered
anchors.left: pinImg.right
anchors.verticalCenter: vertiSep.verticalCenter
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: pinnedMessagesGroup.hovered = true
onExited: pinnedMessagesGroup.hovered = false
onClicked: openPopup(pinnedMessagesPopupComponent)
}
}
}
}

View File

@ -1,49 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import "../../imports"
import "../../shared"
import "../../shared/status"
Button {
id: control
property string chatId
property string chatName
property int chatType
property string identicon
property int identiconSize: 40
property bool isCompact: false
property bool muted: false
implicitHeight: 48
implicitWidth: content.width + 8
leftPadding: 4
rightPadding: 4
contentItem: StatusChatInfo {
id: content
chatId: control.chatId
chatName: control.chatName
chatType: control.chatType
muted: control.muted
identicon: {
if (control.chatType === Constants.chatTypeOneToOne) {
return appMain.getProfileImage(control.chatId) || control.identicon
}
return control.identicon
}
identiconSize: control.identiconSize
isCompact: control.isCompact
}
background: Rectangle {
color: control.hovered ? Style.current.chatInfoButtonBackgroundHoverColor : "transparent"
radius: Style.current.radius
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onPressed: mouse.accepted = false
}
}

View File

@ -1,8 +1,6 @@
StatusButton 1.0 StatusButton.qml
StatusChatCommandButton 1.0 StatusChatCommandButton.qml
StatusChatCommandPopup 1.0 StatusChatCommandPopup.qml
StatusChatInfo 1.0 StatusChatInfo.qml
StatusChatInfoButton 1.0 StatusChatInfoButton.qml
StatusChatInput 1.0 StatusChatInput.qml
StatusEmojiCategoryButton 1.0 StatusEmojiCategoryButton.qml
StatusEmojiPopup 1.0 StatusEmojiPopup.qml