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:
parent
c675aff0f8
commit
a69c2aea73
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*##^##
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue