diff --git a/src/app/modules/main/chat_section/active_item.nim b/src/app/modules/main/chat_section/active_item.nim index 621f5467a0..cdc19b830b 100644 --- a/src/app/modules/main/chat_section/active_item.nim +++ b/src/app/modules/main/chat_section/active_item.nim @@ -125,10 +125,16 @@ QtObject: if(self.item.isNil): return false return self.item.muted - QtProperty[bool] muted: read = getMuted + proc getBlocked(self: ActiveItem): bool {.slot.} = + if(self.item.isNil): + return false + return self.item.blocked + QtProperty[bool] blocked: + read = getBlocked + proc getPosition(self: ActiveItem): int {.slot.} = if(self.item.isNil): return 0 diff --git a/src/app/modules/main/chat_section/active_sub_item.nim b/src/app/modules/main/chat_section/active_sub_item.nim index faa8ba3d08..e799bbfe31 100644 --- a/src/app/modules/main/chat_section/active_sub_item.nim +++ b/src/app/modules/main/chat_section/active_sub_item.nim @@ -94,10 +94,16 @@ QtObject: if(self.item.isNil): return false return self.item.muted - QtProperty[bool] muted: read = getMuted + proc getBlocked(self: ActiveSubItem): bool {.slot.} = + if(self.item.isNil): + return false + return self.item.blocked + QtProperty[bool] blocked: + read = getBlocked + proc getPosition(self: ActiveSubItem): int {.slot.} = if(self.item.isNil): return 0 diff --git a/src/app/modules/main/chat_section/base_item.nim b/src/app/modules/main/chat_section/base_item.nim index 07d0c14e3b..8eeb913a8c 100644 --- a/src/app/modules/main/chat_section/base_item.nim +++ b/src/app/modules/main/chat_section/base_item.nim @@ -11,12 +11,13 @@ type hasUnreadMessages: bool notificationsCount: int muted: bool + blocked: bool active: bool position: int categoryId: string proc setup*(self: BaseItem, id, name, icon: string, isIdenticon: bool, color, description: string, - `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, active: bool, + `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string = "") = self.id = id self.name = name @@ -29,16 +30,17 @@ proc setup*(self: BaseItem, id, name, icon: string, isIdenticon: bool, color, de self.hasUnreadMessages = hasUnreadMessages self.notificationsCount = notificationsCount self.muted = muted + self.blocked = blocked self.active = active self.position = position self.categoryId = categoryId proc initBaseItem*(id, name, icon: string, isIdenticon: bool, color, description: string, `type`: int, - amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, active: bool, + amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string = ""): BaseItem = result = BaseItem() result.setup(id, name, icon, isIdenticon, color, description, `type`, amIChatAdmin, hasUnreadMessages, - notificationsCount, muted, active, position, categoryId) + notificationsCount, muted, blocked, active, position, categoryId) proc delete*(self: BaseItem) = discard @@ -97,6 +99,12 @@ method muted*(self: BaseItem): bool {.inline base.} = method `muted=`*(self: var BaseItem, value: bool) {.inline base.} = self.muted = value +method blocked*(self: BaseItem): bool {.inline base.} = + self.blocked + +method `blocked=`*(self: var BaseItem, value: bool) {.inline base.} = + self.blocked = value + method active*(self: BaseItem): bool {.inline base.} = self.active diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index ee5a4b8d32..c28b6bfed6 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -89,6 +89,10 @@ method init*(self: Controller) = var args = ContactArgs(e) self.delegate.onContactBlocked(args.contactId) + self.events.on(SIGNAL_CONTACT_UNBLOCKED) do(e: Args): + var args = ContactArgs(e) + self.delegate.onContactUnblocked(args.contactId) + if (self.isCommunitySection): self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args): let args = CommunityChatArgs(e) diff --git a/src/app/modules/main/chat_section/item.nim b/src/app/modules/main/chat_section/item.nim index 4538b9ee0b..e208eeea66 100644 --- a/src/app/modules/main/chat_section/item.nim +++ b/src/app/modules/main/chat_section/item.nim @@ -6,10 +6,10 @@ type subItems: SubModel proc initItem*(id, name, icon: string, isIdenticon: bool, color, description: string, `type`: int, amIChatAdmin: bool, - hasUnreadMessages: bool, notificationsCount: int, muted, active: bool, position: int, categoryId: string): Item = + hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string): Item = result = Item() result.setup(id, name, icon, isIdenticon, color, description, `type`, amIChatAdmin, hasUnreadMessages, - notificationsCount, muted, active, position, categoryId) + notificationsCount, muted, blocked, active, position, categoryId) result.subItems = newSubModel() proc delete*(self: Item) = @@ -32,6 +32,7 @@ proc `$`*(self: Item): string = hasUnreadMessages: {self.hasUnreadMessages}, notificationsCount: {self.notificationsCount}, muted: {self.muted}, + blocked: {self.blocked}, active: {self.active}, position: {self.position}, categoryId: {self.categoryId}, @@ -52,6 +53,7 @@ proc toJsonNode*(self: Item): JsonNode = "hasUnreadMessages": self.hasUnreadMessages, "notificationsCount": self.notificationsCount, "muted": self.muted, + "blocked": self.blocked, "active": self.active, "position": self.position, "categoryId": self.categoryId diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index cab30e18ad..0f7a6b4449 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -15,6 +15,7 @@ type HasUnreadMessages NotificationsCount Muted + Blocked Active Position SubItems @@ -75,6 +76,7 @@ QtObject: ModelRole.HasUnreadMessages.int:"hasUnreadMessages", ModelRole.NotificationsCount.int:"notificationsCount", ModelRole.Muted.int:"muted", + ModelRole.Blocked.int:"blocked", ModelRole.Active.int:"active", ModelRole.Position.int:"position", ModelRole.SubItems.int:"subItems", @@ -114,7 +116,9 @@ QtObject: result = newQVariant(item.notificationsCount) of ModelRole.Muted: result = newQVariant(item.muted) - of ModelRole.Active: + of ModelRole.Blocked: + result = newQVariant(item.blocked) + of ModelRole.Active: result = newQVariant(item.active) of ModelRole.Position: result = newQVariant(item.position) @@ -217,6 +221,17 @@ QtObject: if self.items[i].subItems.muteUnmuteItemById(id, mute): return + proc blockUnblockItemOrSubItemById*(self: Model, id: string, blocked: bool) = + for i in 0 ..< self.items.len: + if(self.items[i].id == id): + let index = self.createIndex(i, 0, nil) + self.items[i].BaseItem.blocked = blocked + self.dataChanged(index, index, @[ModelRole.Blocked.int]) + return + + if self.items[i].subItems.blockUnblockItemById(id, blocked): + return + proc updateItemDetails*(self: Model, id, name, icon: string, isIdenticon: bool) = ## This updates only first level items, it doesn't update subitems, since subitems cannot have custom icon. for i in 0 ..< self.items.len: diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index fd202cbbf4..3e92c0f372 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -108,14 +108,19 @@ proc buildChatUI(self: Module, events: EventEmitter, var chatImage = c.identicon var isIdenticon = false var isUsersListAvailable = true + var blocked = false if(c.chatType == ChatType.OneToOne): isUsersListAvailable = false - (chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(c.id) + let contactDetails = self.controller.getContactDetails(c.id) + chatName = contactDetails.displayName + chatImage = contactDetails.icon + isIdenticon = contactDetails.isIdenticon + blocked = contactDetails.details.isBlocked() let amIChatAdmin = self.amIMarkedAsAdminUser(c.members) let item = initItem(c.id, chatName, chatImage, isIdenticon, c.color, c.description, c.chatType.int, amIChatAdmin, - hasNotification, notificationsCount, c.muted, active = false, c.position, c.categoryId) + hasNotification, notificationsCount, c.muted, blocked, active=false, c.position, c.categoryId) self.view.chatsModel().appendItem(item) self.addSubmodule(c.id, false, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -151,7 +156,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter, let amIChatAdmin = comm.admin let channelItem = initItem(chatDto.id, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, - chatDto.muted, active = false, c.position, c.categoryId) + chatDto.muted, blocked=false, active = false, c.position, c.categoryId) self.view.chatsModel().appendItem(channelItem) self.addSubmodule(chatDto.id, true, true, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -181,7 +186,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter, let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, - false, c.position) + blocked=false, active=false, c.position) categoryChannels.add(channelItem) self.addSubmodule(chatDto.id, true, true, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -193,7 +198,8 @@ proc buildCommunityUI(self: Module, events: EventEmitter, selectedSubItemId = channelItem.id var categoryItem = initItem(cat.id, cat.name, "", false, "", "", ChatType.Unknown.int, false, - hasNotificationPerCategory, notificationsCountPerCategory, false, false, cat.position, cat.id) + hasNotificationPerCategory, notificationsCountPerCategory, muted=false, blocked=false, active=false, + cat.position, cat.id) categoryItem.prependSubItems(categoryChannels) self.view.chatsModel().appendItem(categoryItem) @@ -390,7 +396,7 @@ method addNewChat*( if chatDto.categoryId == "": let item = initItem(chatDto.id, chatName, chatImage, isIdenticon, chatDto.color, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, - active = false, position = 0, chatDto.categoryId) + blocked=false, active=false, position = 0, chatDto.categoryId) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) self.chatContentModules[chatDto.id].load() @@ -401,7 +407,7 @@ method addNewChat*( let categoryItem = self.view.chatsModel().getItemById(chatDto.categoryId) let channelItem = initSubItem(chatDto.id, chatDto.categoryId, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, - false, chatDto.position) + blocked=false, active=false, chatDto.position) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) self.chatContentModules[chatDto.id].load() @@ -416,14 +422,14 @@ method removeCommunityChat*(self: Module, chatId: string) = method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatDto]) = var categoryItem = initItem(cat.id, cat.name, "", false, "", "", ChatType.Unknown.int, false, - false, 0, false, false, cat.position, cat.id) + false, 0, muted=false, blocked=false, active=false, cat.position, cat.id) var categoryChannels: seq[SubItem] for chatDto in chats: let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0 let notificationsCount = chatDto.unviewedMentionsCount let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description, chatDto.chatType.int, true, hasNotification, notificationsCount, chatDto.muted, - false, chatDto.position) + blocked=false, active=false, chatDto.position) # Important: # Since we're just adding an already added community channel to a certain commuinity, there is no need to call @@ -523,6 +529,10 @@ method blockContact*(self: Module, publicKey: string) = method onContactBlocked*(self: Module, publicKey: string) = self.view.contactRequestsModel().removeItemWithPubKey(publicKey) + self.view.chatsModel().blockUnblockItemOrSubItemById(publicKey, blocked=true) + +method onContactUnblocked*(self: Module, publicKey: string) = + self.view.chatsModel().blockUnblockItemOrSubItemById(publicKey, blocked=false) method onContactDetailsUpdated*(self: Module, publicKey: string) = let contact = self.controller.getContact(publicKey) diff --git a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim index b0ab256c38..908ba70502 100644 --- a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim @@ -33,6 +33,9 @@ method onContactRejected*(self: AccessInterface, publicKey: string) {.base.} = method onContactBlocked*(self: AccessInterface, publicKey: string) {.base.} = raise newException(ValueError, "No implementation available") +method onContactUnblocked*(self: AccessInterface, publicKey: string) {.base.} = + raise newException(ValueError, "No implementation available") + method onContactDetailsUpdated*(self: AccessInterface, contactId: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/sub_item.nim b/src/app/modules/main/chat_section/sub_item.nim index 793b15fc0b..dff256ee2f 100644 --- a/src/app/modules/main/chat_section/sub_item.nim +++ b/src/app/modules/main/chat_section/sub_item.nim @@ -8,10 +8,10 @@ type parentId: string proc initSubItem*(id, parentId, name, icon: string, isIdenticon: bool, color, description: string, `type`: int, - amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, active: bool, position: int): SubItem = + amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int): SubItem = result = SubItem() result.setup(id, name, icon, isIdenticon, color, description, `type`, amIChatAdmin, hasUnreadMessages, - notificationsCount, muted, active, position) + notificationsCount, muted, blocked, active, position) result.parentId = parentId proc delete*(self: SubItem) = @@ -34,6 +34,7 @@ proc `$`*(self: SubItem): string = hasUnreadMessages: {self.hasUnreadMessages}, notificationsCount: {self.notificationsCount}, muted: {self.muted}, + blocked: {self.blocked}, active: {self.active}, position: {self.position}, ]""" @@ -51,6 +52,7 @@ proc toJsonNode*(self: SubItem): JsonNode = "hasUnreadMessages": self.hasUnreadMessages, "notificationsCount": self.notificationsCount, "muted": self.muted, + "blocked": self.blocked, "active": self.active, "position": self.position } \ No newline at end of file diff --git a/src/app/modules/main/chat_section/sub_model.nim b/src/app/modules/main/chat_section/sub_model.nim index 8fcdc94a0c..751996c9ca 100644 --- a/src/app/modules/main/chat_section/sub_model.nim +++ b/src/app/modules/main/chat_section/sub_model.nim @@ -16,6 +16,7 @@ type HasUnreadMessages NotificationsCount Muted + Blocked Active Position @@ -70,6 +71,7 @@ QtObject: ModelRole.HasUnreadMessages.int:"hasUnreadMessages", ModelRole.NotificationsCount.int:"notificationsCount", ModelRole.Muted.int:"muted", + ModelRole.Blocked.int:"blocked", ModelRole.Active.int:"active", ModelRole.Position.int:"position", }.toTable @@ -109,6 +111,8 @@ QtObject: result = newQVariant(item.notificationsCount) of ModelRole.Muted: result = newQVariant(item.muted) + of ModelRole.Blocked: + result = newQVariant(item.blocked) of ModelRole.Active: result = newQVariant(item.active) of ModelRole.Position: @@ -197,6 +201,17 @@ QtObject: return true return false + proc blockUnblockItemById*(self: SubModel, id: string, blocked: bool): bool = + ## even we're not able to block specific channel of community now, this is here more as a predisposition + ## for that feature, which may be added easy later. + for i in 0 ..< self.items.len: + if(self.items[i].id == id): + let index = self.createIndex(i, 0, nil) + self.items[i].BaseItem.blocked = blocked + self.dataChanged(index, index, @[ModelRole.Blocked.int]) + return true + return false + proc updateNotificationsForItemById*(self: SubModel, id: string, hasUnreadMessages: bool, notificationsCount: int): bool = for i in 0 ..< self.items.len: diff --git a/src/app/modules/main/chat_section/view.nim b/src/app/modules/main/chat_section/view.nim index de89d609bc..5316f84a16 100644 --- a/src/app/modules/main/chat_section/view.nim +++ b/src/app/modules/main/chat_section/view.nim @@ -40,7 +40,7 @@ QtObject: result.contactRequestsModel = contacts_model.newModel() result.contactRequestsModelVariant = newQVariant(result.contactRequestsModel) result.listOfMyContacts = contacts_model.newModel() - result.listOfMyContactsVariant = newQVariant(result.listOfMyContacts) + result.listOfMyContactsVariant = newQVariant(result.listOfMyContacts) proc load*(self: View) = self.delegate.viewDidLoad() diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index 481f18231f..68f9c83f76 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -54,7 +54,6 @@ Item { property var userList property var contactDetails: Utils.getContactDetailsAsJson(root.activeChatId) - property bool isBlocked: root.contactDetails.isBlocked property bool isContact: root.contactDetails.isContact property bool contactRequestReceived: root.contactDetails.requestReceived @@ -179,6 +178,7 @@ Item { receiveTransactionModal: cmpReceiveTransaction sendTransactionWithEnsModal: cmpSendTransactionWithEns stickersLoaded: root.stickersLoaded + isBlocked: model.blocked Component.onCompleted: { parentModule.prepareChatContentModuleForChatId(model.itemId) chatContentModule = parentModule.getChatContentModule() @@ -208,6 +208,7 @@ Item { receiveTransactionModal: cmpReceiveTransaction sendTransactionWithEnsModal: cmpSendTransactionWithEns stickersLoaded: root.stickersLoaded + isBlocked: model.blocked Component.onCompleted: { parentModule.prepareChatContentModuleForChatId(itemId) chatContentModule = parentModule.getChatContentModule() diff --git a/ui/app/AppLayouts/Chat/views/ChatContentView.qml b/ui/app/AppLayouts/Chat/views/ChatContentView.qml index ff35b9b6e3..b96bf555fe 100644 --- a/ui/app/AppLayouts/Chat/views/ChatContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContentView.qml @@ -36,6 +36,8 @@ ColumnLayout { property Component receiveTransactionModal property Component sendTransactionWithEnsModal + property bool isBlocked: false + property bool stickersLoaded: false // NOTE: Used this property change as it is the current way used for displaying new channel/chat data of content view. @@ -272,25 +274,11 @@ ColumnLayout { // } } - Item { + StatusBanner { Layout.fillWidth: true - Layout.preferredHeight: 40 - Layout.alignment: Qt.AlignHCenter - visible: isBlocked - - Rectangle { - id: blockedBanner - anchors.fill: parent - color: Style.current.red - opacity: 0.1 - } - - Text { - id: blockedText - anchors.centerIn: blockedBanner - color: Style.current.red - text: qsTr("Blocked") - } + visible: chatContentRoot.isBlocked + type: StatusBanner.Type.Danger + statusText: qsTr("Blocked") } MessageStore { @@ -405,8 +393,8 @@ ColumnLayout { // chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.canPost } messageContextMenu: contextmenu - isContactBlocked: isBlocked - chatInputPlaceholder: isBlocked ? + isContactBlocked: chatContentRoot.isBlocked + chatInputPlaceholder: chatContentRoot.isBlocked ? //% "This user has been blocked." qsTrId("this-user-has-been-blocked-") : //% "Type a message." diff --git a/ui/imports/shared/popups/ProfilePopup.qml b/ui/imports/shared/popups/ProfilePopup.qml index 0b612c92e8..01f05b3a59 100644 --- a/ui/imports/shared/popups/ProfilePopup.qml +++ b/ui/imports/shared/popups/ProfilePopup.qml @@ -96,6 +96,13 @@ StatusModal { anchors.top: parent.top width: parent.width + StatusBanner { + width: parent.width + visible: popup.userIsBlocked + type: StatusBanner.Type.Danger + statusText: qsTr("Blocked") + } + Item { height: 16 width: parent.width @@ -130,11 +137,6 @@ StatusModal { width: parent.width } - StatusModalDivider { - topPadding: 12 - bottomPadding: 16 - } - StatusDescriptionListItem { title: qsTr("Share Profile URL") subTitle: { @@ -167,12 +169,6 @@ StatusModal { width: parent.width } - StatusModalDivider { - visible: !isCurrentUser - topPadding: 8 - bottomPadding: 12 - } - StatusDescriptionListItem { visible: !isCurrentUser title: qsTr("Chat settings")