diff --git a/src/app/chat/view.nim b/src/app/chat/view.nim index a0ae2fe9c4..1ce6573ec9 100644 --- a/src/app/chat/view.nim +++ b/src/app/chat/view.nim @@ -621,16 +621,16 @@ QtObject: if (self.chats.chats.len == 0): return let selectedChannel = self.chats.getChannel(channelIndex) if (selectedChannel == nil): return - self.status.chat.muteChat(selectedChannel.id) selectedChannel.muted = true + self.status.chat.muteChat(selectedChannel) self.chats.updateChat(selectedChannel, false) proc unmuteChannel*(self: ChatsView, channelIndex: int) {.slot.} = if (self.chats.chats.len == 0): return let selectedChannel = self.chats.getChannel(channelIndex) if (selectedChannel == nil): return - self.status.chat.unmuteChat(selectedChannel.id) selectedChannel.muted = false + self.status.chat.unmuteChat(selectedChannel) self.chats.updateChat(selectedChannel, false) proc channelIsMuted*(self: ChatsView, channelIndex: int): bool {.slot.} = diff --git a/src/app/chat/views/channels_list.nim b/src/app/chat/views/channels_list.nim index b38141096b..9c7ac79716 100644 --- a/src/app/chat/views/channels_list.nim +++ b/src/app/chat/views/channels_list.nim @@ -95,6 +95,7 @@ QtObject: proc removeChatItemFromList*(self: ChannelsList, channel: string): int = let idx = self.chats.findIndexById(channel) + if idx == -1: return self.beginRemoveRows(newQModelIndex(), idx, idx) self.chats.delete(idx) self.endRemoveRows() diff --git a/src/app/profile/core.nim b/src/app/profile/core.nim index 00904cfdfb..c41ab2b08f 100644 --- a/src/app/profile/core.nim +++ b/src/app/profile/core.nim @@ -14,6 +14,7 @@ import ../../status/wallet import ../../eventemitter import view import views/ens_manager +import ../chat/views/channels_list import chronicles type ProfileController* = ref object @@ -55,6 +56,30 @@ proc init*(self: ProfileController, account: Account) = self.status.chat.updateContacts(contacts) self.view.setContactList(contacts) + self.status.events.on("channelLoaded") do(e: Args): + var channel = ChannelArgs(e) + if channel.chat.muted: + if channel.chat.chatType.isOneToOne: + discard self.view.mutedContacts.addChatItemToList(channel.chat) + return + discard self.view.mutedChats.addChatItemToList(channel.chat) + + self.status.events.on("channelJoined") do(e: Args): + var channel = ChannelArgs(e) + if channel.chat.muted: + if channel.chat.chatType.isOneToOne: + discard self.view.mutedContacts.addChatItemToList(channel.chat) + return + discard self.view.mutedChats.addChatItemToList(channel.chat) + + self.status.events.on("chatsLoaded") do(e:Args): + self.view.mutedChatsListChanged() + self.view.mutedContactsListChanged() + + self.status.events.on("chatUpdate") do(e: Args): + var evArgs = ChatUpdateArgs(e) + self.view.updateChats(evArgs.chats) + self.status.events.on("contactAdded") do(e: Args): let contacts = self.status.contacts.getContacts() self.view.setContactList(contacts) diff --git a/src/app/profile/view.nim b/src/app/profile/view.nim index 5f76c3bb22..6e19a88c02 100644 --- a/src/app/profile/view.nim +++ b/src/app/profile/view.nim @@ -1,5 +1,6 @@ import NimQml, sequtils, strutils, sugar, os, json import views/[mailservers_list, ens_manager, contact_list, fleets, profile_info, device_list, dapp_list] +import ../chat/views/channels_list import ../../status/profile/[mailserver, profile, devices] import ../../status/profile as status_profile import ../../status/contacts as status_contacts @@ -21,6 +22,8 @@ QtObject: contactList*: ContactList addedContacts*: ContactList blockedContacts*: ContactList + mutedChats*: ChannelsList + mutedContacts*: ChannelsList deviceList*: DeviceList dappList*: DappList fleets*: Fleets @@ -39,6 +42,8 @@ QtObject: if not self.contactList.isNil: self.contactList.delete if not self.addedContacts.isNil: self.addedContacts.delete if not self.blockedContacts.isNil: self.blockedContacts.delete + if not self.mutedChats.isNil: self.mutedChats.delete + if not self.mutedContacts.isNil: self.mutedContacts.delete if not self.deviceList.isNil: self.deviceList.delete if not self.ens.isNil: self.ens.delete if not self.profile.isNil: self.profile.delete @@ -54,6 +59,8 @@ QtObject: result.contactList = newContactList() result.addedContacts = newContactList() result.blockedContacts = newContactList() + result.mutedChats = newChannelsList(status) + result.mutedContacts = newChannelsList(status) result.deviceList = newDeviceList() result.dappList = newDappList(status) result.ens = newEnsManager(status) @@ -339,3 +346,52 @@ QtObject: proc getLinkPreviewWhitelist*(self: ProfileView): string {.slot.} = result = $(self.status.profile.getLinkPreviewWhitelist()) + proc getMutedChatsList(self: ProfileView): QVariant {.slot.} = + newQVariant(self.mutedChats) + + proc getMutedContactsList(self: ProfileView): QVariant {.slot.} = + newQVariant(self.mutedContacts) + + proc mutedChatsListChanged*(self: ProfileView) {.signal.} + + proc mutedContactsListChanged*(self: ProfileView) {.signal.} + + QtProperty[QVariant] mutedChats: + read = getMutedChatsList + notify = mutedChatsListChanged + + QtProperty[QVariant] mutedContacts: + read = getMutedContactsList + notify = mutedContactsListChanged + + proc unmuteChannel*(self: ProfileView, chatId: string) {.slot.} = + if (self.mutedChats.chats.len == 0 and self.mutedContacts.chats.len == 0): return + + var selectedChannel = self.mutedChats.getChannelById(chatId) + if (selectedChannel != nil): + discard self.mutedChats.removeChatItemFromList(chatId) + else: + selectedChannel = self.mutedContacts.getChannelById(chatId) + if (selectedChannel == nil): return + discard self.mutedContacts.removeChatItemFromList(chatId) + + selectedChannel.muted = false + self.status.chat.unmuteChat(selectedChannel) + self.mutedChatsListChanged() + self.mutedContactsListChanged() + + proc updateChats*(self: ProfileView, chats: seq[Chat]) = + for chat in chats: + if not chat.muted: + if chat.chatType.isOneToOne: + discard self.mutedContacts.removeChatItemFromList(chat.id) + else: + discard self.mutedChats.removeChatItemFromList(chat.id) + else: + if chat.chatType.isOneToOne: + discard self.mutedContacts.addChatItemToList(chat) + else: + discard self.mutedChats.addChatItemToList(chat) + self.mutedChatsListChanged() + self.mutedContactsListChanged() + diff --git a/src/status/chat.nim b/src/status/chat.nim index c7e1fbb787..e93033ea68 100644 --- a/src/status/chat.nim +++ b/src/status/chat.nim @@ -302,11 +302,13 @@ proc makeAdmin*(self: ChatModel, chatId: string, pubKey: string) = proc resendMessage*(self: ChatModel, messageId: string) = discard status_chat.reSendChatMessage(messageId) -proc muteChat*(self: ChatModel, chatId: string) = - discard status_chat.muteChat(chatId) +proc muteChat*(self: ChatModel, chat: Chat) = + discard status_chat.muteChat(chat.id) + self.events.emit("chatUpdate", ChatUpdateArgs(messages: @[], chats: @[chat], contacts: @[])) -proc unmuteChat*(self: ChatModel, chatId: string) = - discard status_chat.unmuteChat(chatId) +proc unmuteChat*(self: ChatModel, chat: Chat) = + discard status_chat.unmuteChat(chat.id) + self.events.emit("chatUpdate", ChatUpdateArgs(messages: @[], chats: @[chat], contacts: @[])) proc processUpdateForTransaction*(self: ChatModel, messageId: string, response: string) = var (chats, messages) = self.processMessageUpdateAfterSend(response) diff --git a/ui/app/AppLayouts/Profile/Sections/MutedChatsModal.qml b/ui/app/AppLayouts/Profile/Sections/MutedChatsModal.qml new file mode 100644 index 0000000000..d5dad6bab6 --- /dev/null +++ b/ui/app/AppLayouts/Profile/Sections/MutedChatsModal.qml @@ -0,0 +1,73 @@ +import QtQuick 2.13 +import QtQuick.Controls 2.13 +import QtGraphicalEffects 1.13 +import QtQuick.Layouts 1.13 +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" + +ModalPopup { + id: root + title: qsTr("Muted chats") + property bool showMutedContacts: false + + onClosed: { + root.destroy() + } + + ListView { + id: mutedChatsList + anchors.top: parent.top + visible: true + height: childrenRect.height + anchors.left: parent.left + anchors.right: parent.right + model: root.showMutedContacts ? profileModel.mutedContacts : profileModel.mutedChats + delegate: Rectangle { + height: contactImage.height + Style.current.smallPadding * 2 + color: Style.current.transparent + + StatusIdenticon { + id: contactImage + height: 40 + width: 40 + chatName: model.name + chatType: model.chatType + identicon: model.identicon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + id: contactInfo + text: model.chatType !== Constants.chatTypePublic ? + Emoji.parse(Utils.removeStatusEns(Utils.filterXSS(model.name)), "26x26") : + "#" + Utils.filterXSS(model.name) + anchors.right: unmuteButton.left + anchors.rightMargin: Style.current.smallPadding + elide: Text.ElideRight + font.pixelSize: 17 + anchors.left: contactImage.right + anchors.leftMargin: Style.current.padding + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + id: unmuteButton + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Unmute") + font.pixelSize: 15 + color: Style.current.primary + + MouseArea { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + onClicked: { + profileModel.unmuteChannel(model.id) + } + } + } + } + } +} diff --git a/ui/app/AppLayouts/Profile/Sections/NotificationsContainer.qml b/ui/app/AppLayouts/Profile/Sections/NotificationsContainer.qml index 562ad06f03..e4ffd25fcc 100644 --- a/ui/app/AppLayouts/Profile/Sections/NotificationsContainer.qml +++ b/ui/app/AppLayouts/Profile/Sections/NotificationsContainer.qml @@ -13,7 +13,7 @@ ScrollView { contentHeight: notificationsContainer.height clip: true - Rectangle { + Item { id: notificationsContainer anchors.right: parent.right anchors.rightMargin: contentMargin @@ -21,6 +21,9 @@ ScrollView { anchors.leftMargin: contentMargin height: this.childrenRect.height + 100 + property Component mutedChatsModalComponent: MutedChatsModal {} + + ButtonGroup { id: notificationSetting } @@ -358,7 +361,14 @@ ScrollView { StatusSectionMenuItem { //% "Muted users" label: qsTrId("muted-users") - info: "2" + info: profileModel.mutedContacts.rowCount() > 0 ? profileModel.mutedContacts.rowCount() : qsTr("None") + onClicked: { + const mutedChatsModal = notificationsContainer.mutedChatsModalComponent.createObject(notificationsContainer, { + showMutedContacts: true + }) + mutedChatsModal.title = qsTr("Muted contacts") + mutedChatsModal.open() + } } StatusSectionMenuItem { @@ -366,8 +376,14 @@ ScrollView { label: qsTrId("muted-chats") //% "You can limit what gets shown in notifications" description: qsTrId("you-can-limit-what-gets-shown-in-notifications") - //% "None" - info: qsTrId("none") + info: profileModel.mutedChats.rowCount() > 0 ? profileModel.mutedChats.rowCount() : qsTr("None") + onClicked: { + const mutedChatsModal = notificationsContainer.mutedChatsModalComponent.createObject(notificationsContainer, { + showMutedContacts: false + }) + mutedChatsModal.title = qsTr("Muted chats") + mutedChatsModal.open() + } } }