From a530f65ada3f3bbe13ce55336b915a3784efede8 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Fri, 30 Jul 2021 18:52:44 +0200 Subject: [PATCH] fix(@desktop/communities): `joinedCommunities` doesn't update underlying community Counting mentions for community seems was not developed yet. That's added here in this commit, but instead of using "mentionsCount" we introduced on the side of nim, I found that we're receiving "unviewedMentionsCount", but only for new messages. I used it for this fix. Counting mentions and requests per community added. Fixes: #2972 --- src/app/chat/event_handling.nim | 2 - src/app/chat/views/channels_list.nim | 15 +---- src/app/chat/views/communities.nim | 40 +++--------- src/app/chat/views/community_item.nim | 11 ++++ src/app/chat/views/community_list.nim | 93 +++++++++++++++++++-------- src/status/chat/chat.nim | 19 +++++- src/status/signals/messages.nim | 1 + ui/app/AppMain.qml | 3 +- 8 files changed, 110 insertions(+), 74 deletions(-) diff --git a/src/app/chat/event_handling.nim b/src/app/chat/event_handling.nim index cc2b6add40..72b4e91e38 100644 --- a/src/app/chat/event_handling.nim +++ b/src/app/chat/event_handling.nim @@ -28,7 +28,6 @@ proc handleChatEvents(self: ChatController) = self.status.events.on("activityCenterNotificationsLoaded") do(e:Args): let notifications = ActivityCenterNotificationsArgs(e).activityCenterNotifications self.view.pushActivityCenterNotifications(notifications) - self.view.communities.updateNotifications(notifications) self.status.events.on("contactBlocked") do(e: Args): var evArgs = ContactBlockedArgs(e) @@ -86,7 +85,6 @@ proc handleChatEvents(self: ChatController) = self.view.refreshPinnedMessages(evArgs.pinnedMessages) if (evArgs.activityCenterNotifications.len > 0): self.view.addActivityCenterNotification(evArgs.activityCenterNotifications) - self.view.communities.updateNotifications(evArgs.activityCenterNotifications) if (evArgs.deletedMessages.len > 0): for messageId in evArgs.deletedMessages: diff --git a/src/app/chat/views/channels_list.nim b/src/app/chat/views/channels_list.nim index 0bd0b4d88f..e10b475301 100644 --- a/src/app/chat/views/channels_list.nim +++ b/src/app/chat/views/channels_list.nim @@ -181,6 +181,7 @@ QtObject: let index = self.createIndex(idx, 0, nil) self.chats[idx].unviewedMessagesCount = 0 + self.chats[idx].unviewedMentionsCount = 0 self.dataChanged(index, index, @[ChannelsRoles.UnreadMessages.int]) @@ -191,6 +192,7 @@ QtObject: let index = self.createIndex(idx, 0, nil) self.chats[idx].mentionsCount = 0 + self.chats[idx].unviewedMentionsCount = 0 self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int]) @@ -205,18 +207,7 @@ QtObject: let index = self.createIndex(idx, 0, nil) self.chats[idx].mentionsCount.dec - - self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int]) - - proc incrementMentions*(self: ChannelsList, channelId: string) : bool = - result = false - let idx = self.chats.findIndexById(channelId) - if idx == -1: - return - - let index = self.createIndex(idx, 0, nil) - self.chats[idx].mentionsCount.inc - result = true + self.chats[idx].unviewedMentionsCount.dec self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int]) diff --git a/src/app/chat/views/communities.nim b/src/app/chat/views/communities.nim index 7d145189ac..86c76e910b 100644 --- a/src/app/chat/views/communities.nim +++ b/src/app/chat/views/communities.nim @@ -24,7 +24,6 @@ proc mergeChat(community: var Community, chat: Chat): bool = if (c.id == chat.id): chat.canPost = community.chats[i].canPost chat.categoryId = community.chats[i].categoryId - chat.mentionsCount = community.chats[i].mentionsCount community.chats[i] = chat return true @@ -73,13 +72,6 @@ QtObject: self.importingCommunityState = state self.importingCommunityStateChanged(state.int, communityImportingProcessId) - proc calculateUnreadMessages*(self: CommunitiesView, community: var Community) = - var unreadTotal = 0 - for chatItem in community.chats: - unreadTotal = unreadTotal + chatItem.unviewedMessagesCount - if unreadTotal != community.unviewedMessagesCount: - community.unviewedMessagesCount = unreadTotal - proc updateMemberVisibility*(self: CommunitiesView, statusUpdate: StatusUpdate) = self.joinedCommunityList.updateMemberVisibility(statusUpdate) self.activeCommunity.setCommunityItem(self.joinedCommunityList.getCommunityById(self.activeCommunity.communityItem.id)) @@ -109,7 +101,6 @@ QtObject: if (not found): community.chats.add(newChat) - self.calculateUnreadMessages(community) self.joinedCommunityList.replaceCommunity(community) if (self.activeCommunity.active and self.activeCommunity.communityItem.id == community.id): self.activeCommunity.changeChats(community.chats) @@ -164,6 +155,8 @@ QtObject: var communities = self.status.chat.getJoinedComunities() communities = self.populateChats(communities) self.joinedCommunityList.setNewData(communities) + for c in communities: + self.addMembershipRequests(self.pendingRequestsToJoinForCommunity(c.id)) self.joinedCommunityList.fetched = true # Also fetch requests @@ -200,7 +193,6 @@ QtObject: proc setActiveCommunity*(self: CommunitiesView, communityId: string) {.slot.} = if(communityId == ""): return - self.addMembershipRequests(self.pendingRequestsToJoinForCommunity(communityId)) self.activeCommunity.setCommunityItem(self.joinedCommunityList.getCommunityById(communityId)) self.activeCommunity.setActive(true) self.activeCommunityChanged() @@ -219,7 +211,8 @@ QtObject: if (not self.userCanJoin(communityId) or self.isUserMemberOfCommunity(communityId)): return self.status.chat.joinCommunity(communityId) - self.joinedCommunityList.addCommunityItemToList(self.communityList.getCommunityById(communityId)) + var community = self.communityList.getCommunityById(communityId) + self.joinedCommunityList.addCommunityItemToList(community) if (setActive): self.setActiveCommunity(communityId) except Exception as e: @@ -284,7 +277,7 @@ QtObject: result = "" try: var image = image_utils.formatImagePath(imagePath) - let community = self.status.chat.createCommunity(name, description, access, ensOnly, color, image, aX, aY, bX, bY) + var community = self.status.chat.createCommunity(name, description, access, ensOnly, color, image, aX, aY, bX, bY) if (community.id == ""): return "Community was not created. Please try again later" @@ -527,7 +520,7 @@ QtObject: of ActivityCenterNotificationType.NewPrivateGroupChat: debug "Clear all private group chat notifications" of ActivityCenterNotificationType.Mention: - self.activeCommunity.chats.clearAllMentionsFromAllChannels() + self.activeCommunity.clearAllMentions() for c in self.joinedCommunityList.communities: # We don't need to update channels from the currently active community. @@ -549,7 +542,8 @@ QtObject: debug "Clear private group chat notification" of ActivityCenterNotificationType.Mention: if (markAsReadProps.communityId == self.activeCommunity.communityItem.id): - self.activeCommunity.chats.decrementMentions(markAsReadProps.channelId) + self.activeCommunity.decrementMentions(markAsReadProps.channelId) + self.joinedCommunityList.updateMentions(markAsReadProps.communityId) else: for c in self.joinedCommunityList.communities: # We don't need to update channels from the currently active community. @@ -560,21 +554,3 @@ QtObject: debug "Clear reply notification" else: debug "Unknown notification" - - proc updateNotifications*(self: CommunitiesView, notifications: seq[ActivityCenterNotification]) = - for n in notifications: - if (not n.read): - case n.notificationType: - of ActivityCenterNotificationType.NewOneToOne: - debug "Update one to one notification" - of ActivityCenterNotificationType.NewPrivateGroupChat: - debug "Update private group chat notification" - of ActivityCenterNotificationType.Mention: - let incremented = self.activeCommunity.chats.incrementMentions(n.chatId) - if (not incremented): - self.joinedCommunityList.incrementMentions(n.chatId) - - of ActivityCenterNotificationType.Reply: - debug "Update reply notification" - else: - debug "Unknown notification" diff --git a/src/app/chat/views/community_item.nim b/src/app/chat/views/community_item.nim index 3910bcb468..b8cae81214 100644 --- a/src/app/chat/views/community_item.nim +++ b/src/app/chat/views/community_item.nim @@ -249,3 +249,14 @@ QtObject: categoryItemView.setCategoryItem(category) self.categoryItemViews[id] = categoryItemView return categoryItemView + + proc clearAllMentions*(self: CommunityItemView) = + self.chats.clearAllMentionsFromAllChannels() + self.communityItem.unviewedMentionsCount = 0 + self.chatsChanged() + + proc decrementMentions*(self: CommunityItemView, channelId: string) = + self.chats.decrementMentions(channelId) + self.communityItem.unviewedMentionsCount -= 1 + self.chatsChanged() + diff --git a/src/app/chat/views/community_list.nim b/src/app/chat/views/community_list.nim index 72145b7d96..8d8c565e3f 100644 --- a/src/app/chat/views/community_list.nim +++ b/src/app/chat/views/community_list.nim @@ -10,23 +10,25 @@ import # status-desktop libs type CommunityRoles {.pure.} = enum Id = UserRole + 1, - Name = UserRole + 2 - Description = UserRole + 3 - Access = UserRole + 4 - Admin = UserRole + 5 - Joined = UserRole + 6 - Verified = UserRole + 7 - NumMembers = UserRole + 8 - ThumbnailImage = UserRole + 9 - LargeImage = UserRole + 10 - EnsOnly = UserRole + 11 - CanRequestAccess = UserRole + 12 - CanManageUsers = UserRole + 13 - CanJoin = UserRole + 14 - IsMember = UserRole + 15 - UnviewedMessagesCount = UserRole + 16 - CommunityColor = UserRole + 17 - Muted = UserRole + 18 + Name + Description + Access + Admin + Joined + Verified + NumMembers + ThumbnailImage + LargeImage + EnsOnly + CanRequestAccess + CanManageUsers + CanJoin + IsMember + UnviewedMessagesCount + UnviewedMentionsCount + RequestsCount + CommunityColor + Muted QtObject: type @@ -75,6 +77,8 @@ QtObject: of "isMember": result = $community.isMember of "nbMembers": result = $community.members.len of "unviewedMessagesCount": result = $community.unviewedMessagesCount + of "unviewedMentionsCount": result = $community.unviewedMentionsCount + of "requestsCount": result = $community.membershipRequests.len of "thumbnailImage": if (not community.communityImage.isNil): result = community.communityImage.thumbnail @@ -111,6 +115,8 @@ QtObject: of CommunityRoles.IsMember: result = newQVariant(communityItem.isMember.bool) of CommunityRoles.NumMembers: result = newQVariant(communityItem.members.len) of CommunityRoles.UnviewedMessagesCount: result = newQVariant(communityItem.unviewedMessagesCount) + of CommunityRoles.UnviewedMentionsCount: result = newQVariant(communityItem.unviewedMentionsCount) + of CommunityRoles.RequestsCount: result = newQVariant(communityItem.membershipRequests.len) of CommunityRoles.ThumbnailImage: if (not communityItem.communityImage.isNil): result = newQVariant(communityItem.communityImage.thumbnail) @@ -145,17 +151,26 @@ QtObject: CommunityRoles.Muted.int: "muted", CommunityRoles.NumMembers.int: "nbMembers", CommunityRoles.UnviewedMessagesCount.int: "unviewedMessagesCount", + CommunityRoles.UnviewedMentionsCount.int: "unviewedMentionsCount", + CommunityRoles.RequestsCount.int: "requestsCount", CommunityRoles.ThumbnailImage.int:"thumbnailImage", CommunityRoles.LargeImage.int:"largeImage", CommunityRoles.CommunityColor.int:"communityColor" }.toTable - proc setNewData*(self: CommunityList, communityList: seq[Community]) = + proc setNewData*(self: CommunityList, communityList: var seq[Community]) = + for c in communityList.mitems: + c.recalculateUnviewedMessages() + c.recalculateMentions() + self.beginResetModel() self.communities = communityList self.endResetModel() - proc addCommunityItemToList*(self: CommunityList, community: Community) = + proc addCommunityItemToList*(self: CommunityList, community: var Community) = + community.recalculateUnviewedMessages() + community.recalculateMentions() + self.beginInsertRows(newQModelIndex(), self.communities.len, self.communities.len) self.communities.add(community) self.endInsertRows() @@ -218,8 +233,16 @@ QtObject: let bottomRight = self.createIndex(index, index, nil) var oldCommunity = self.communities[index] community.memberStatus = oldCommunity.memberStatus + + community.recalculateUnviewedMessages() + community.recalculateMentions() + self.communities[index] = community - self.dataChanged(topLeft, bottomRight, @[CommunityRoles.Name.int, CommunityRoles.Description.int, CommunityRoles.UnviewedMessagesCount.int, CommunityRoles.ThumbnailImage.int]) + self.dataChanged(topLeft, bottomRight, @[CommunityRoles.Name.int, + CommunityRoles.Description.int, + CommunityRoles.UnviewedMessagesCount.int, + CommunityRoles.UnviewedMentionsCount.int, + CommunityRoles.ThumbnailImage.int]) proc removeCategoryFromCommunity*(self: CommunityList, communityId: string, categoryId:string) = var community = self.getCommunityById(communityId) @@ -238,11 +261,14 @@ QtObject: # Clear unread messages for each channel in community. for c in self.communities[idx].chats: c.unviewedMessagesCount = 0 + c.unviewedMentionsCount = 0 let index = self.createIndex(idx, 0, nil) self.communities[idx].unviewedMessagesCount = 0 + self.communities[idx].unviewedMentionsCount = 0 - self.dataChanged(index, index, @[CommunityRoles.UnviewedMessagesCount.int]) + self.dataChanged(index, index, @[CommunityRoles.UnviewedMessagesCount.int, + CommunityRoles.UnviewedMentionsCount.int]) proc clearAllMentions*(self: CommunityList, communityId: string, clearFromChannels : bool) = let idx = self.communities.findIndexById(communityId) @@ -254,6 +280,13 @@ QtObject: # as mentins are not exposed to qml using roles from this model. for c in self.communities[idx].chats: c.mentionsCount = 0 + c.unviewedMentionsCount = 0 + + self.communities[idx].unviewedMentionsCount = 0 + + let index = self.createIndex(idx, 0, nil) + self.dataChanged(index, index, @[CommunityRoles.UnviewedMentionsCount.int, + CommunityRoles.ThumbnailImage.int]) # If we decide in one moment to expose mention role we should do that here. @@ -267,9 +300,17 @@ QtObject: return self.communities[comIndex].chats[chatIndex].mentionsCount.dec + self.communities[comIndex].chats[chatIndex].unviewedMentionsCount.dec - proc incrementMentions*(self: CommunityList, channelId : string) = - for c in self.communities: - let chatIndex = c.chats.findIndexById(channelId) - if (chatIndex != -1): - c.chats[chatIndex].mentionsCount.inc \ No newline at end of file + self.communities[comIndex].unviewedMentionsCount.dec + + let index = self.createIndex(comIndex, 0, nil) + self.dataChanged(index, index, @[CommunityRoles.UnviewedMentionsCount.int]) + + proc updateMentions*(self: CommunityList, communityId : string) = + let comIndex = self.communities.findIndexById(communityId) + if (comIndex == -1): + return + self.communities[comIndex].recalculateMentions() + let index = self.createIndex(comIndex, 0, nil) + self.dataChanged(index, index, @[CommunityRoles.UnviewedMentionsCount.int]) \ No newline at end of file diff --git a/src/status/chat/chat.nim b/src/status/chat/chat.nim index c6c3bd2c32..bf524455e7 100644 --- a/src/status/chat/chat.nim +++ b/src/status/chat/chat.nim @@ -80,10 +80,11 @@ type Chat* = ref object lastClockValue*: int64 # indicates the last clock value to be used when sending messages deletedAtClockValue*: int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded unviewedMessagesCount*: int + unviewedMentionsCount*: int lastMessage*: Message members*: seq[ChatMember] membershipUpdateEvents*: seq[ChatMembershipEvent] - mentionsCount*: int + mentionsCount*: int # Using this is not a good approach, we should instead use unviewedMentionsCount and refer to it always. muted*: bool canPost*: bool ensName*: string @@ -128,6 +129,7 @@ type Community* = object members*: seq[string] access*: int unviewedMessagesCount*: int + unviewedMentionsCount*: int admin*: bool joined*: bool verified*: bool @@ -235,3 +237,18 @@ proc isAdmin*(self: Chat, pubKey: string): bool = if member.id == pubKey: return member.joined and member.admin return false + +proc recalculateUnviewedMessages*(community: var Community) = + var total = 0 + for chat in community.chats: + total += chat.unviewedMessagesCount + + community.unviewedMessagesCount = total + +proc recalculateMentions*(community: var Community) = + echo "(recalculateMentions) chatId: ", community.id, " before: ", community.unviewedMentionsCount + var total = 0 + for chat in community.chats: + total += chat.unviewedMentionsCount + + community.unviewedMentionsCount = total diff --git a/src/status/signals/messages.nim b/src/status/signals/messages.nim index 2a4939ee69..c30e3e8cc9 100644 --- a/src/status/signals/messages.nim +++ b/src/status/signals/messages.nim @@ -174,6 +174,7 @@ proc toChat*(jsonChat: JsonNode): Chat = lastClockValue: jsonChat{"lastClockValue"}.getBiggestInt, deletedAtClockValue: jsonChat{"deletedAtClockValue"}.getBiggestInt, unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt, + unviewedMentionsCount: jsonChat{"unviewedMentionsCount"}.getInt, mentionsCount: 0, muted: false, ensName: "", diff --git a/ui/app/AppMain.qml b/ui/app/AppMain.qml index 2d252a0983..1541d5b821 100644 --- a/ui/app/AppMain.qml +++ b/ui/app/AppMain.qml @@ -171,7 +171,8 @@ StatusAppLayout { icon.color: model.communityColor icon.source: model.thumbnailImage - badge.visible: !checked && model.unviewedMessagesCount > 0 + badge.value: model.unviewedMentionsCount + model.requestsCount + badge.visible: badge.value > 0 || (!checked && model.unviewedMessagesCount > 0) badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor badge.border.width: 2 badge.anchors.rightMargin: 4