Skip to content

Commit

Permalink
fix(unread): fix badge disappearing because of wrong calculation
Browse files Browse the repository at this point in the history
Fixes #10058

We were calling `updateParentBadgeNotifications` with wrong values, so we basically removed the badge all the time by accident.
Now, we calculate the unread messages and messages from the service's cache.
Also, we still called `updateParentBadgeNotifications` when a contact is updated, as if the contact requests still went in the old contact request popup.
  • Loading branch information
jrainville committed Mar 30, 2023
1 parent f360a9c commit 44b9522
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 44 deletions.
19 changes: 13 additions & 6 deletions src/app/modules/main/chat_section/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ proc init*(self: Controller) =
let args = message_service.MessagesMarkedAsReadArgs(e)
# update chat entity in chat service
var chat = self.chatService.getChatById(args.chatId)
if ((self.isCommunitySection and chat.communityId != self.sectionId) or
(not self.isCommunitySection and chat.communityId != "")):
return
chat.unviewedMessagesCount = 0
chat.unviewedMentionsCount = 0
self.chatService.updateOrAddChat(chat)
Expand Down Expand Up @@ -181,14 +184,14 @@ proc init*(self: Controller) =
var args = ChatUpdateArgs(e)
for chat in args.chats:
let belongsToCommunity = chat.communityId.len > 0
self.delegate.addChatIfDontExist(chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = false)

self.events.on(SIGNAL_CHAT_CREATED) do(e: Args):
var args = CreatedChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0
self.delegate.addChatIfDontExist(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = true)

Expand All @@ -203,7 +206,7 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args):
let args = CommunityChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0
self.delegate.addChatIfDontExist(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = true)

Expand Down Expand Up @@ -392,6 +395,10 @@ proc getChats*(self: Controller, communityId: string, categoryId: string): seq[C
proc getAllChats*(self: Controller, communityId: string): seq[ChatDto] =
return self.communityService.getAllChats(communityId)

proc sectionUnreadMessagesAndMentionsCount*(self: Controller, communityId: string):
tuple[unviewedMessagesCount: int, unviewedMentionsCount: int] =
return self.chatService.sectionUnreadMessagesAndMentionsCount(communityId)

proc asyncGetChats*(self: Controller) =
self.chatService.asyncGetChatsByChannelGroupId(self.sectionId)

Expand Down Expand Up @@ -431,7 +438,7 @@ proc getOneToOneChatNameAndImage*(self: Controller, chatId: string):
proc createOneToOneChat*(self: Controller, communityID: string, chatId: string, ensName: string) =
let response = self.chatService.createOneToOneChat(communityID, chatId, ensName)
if(response.success):
self.delegate.addChatIfDontExist(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService)

Expand Down Expand Up @@ -501,14 +508,14 @@ proc makeAdmin*(self: Controller, communityID: string, chatId: string, pubKey: s
proc createGroupChat*(self: Controller, communityID: string, groupName: string, pubKeys: seq[string]) =
let response = self.chatService.createGroupChat(communityID, groupName, pubKeys)
if(response.success):
self.delegate.addChatIfDontExist(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService)

proc joinGroupChatFromInvitation*(self: Controller, groupName: string, chatId: string, adminPK: string) =
let response = self.chatService.createGroupChatFromInvitation(groupName, chatId, adminPK)
if(response.success):
self.delegate.addChatIfDontExist(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService)

Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/main/chat_section/io_interface.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ method doesCatOrChatExist*(self: AccessInterface, chatId: string): bool {.base.}
method doesTopLevelChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
raise newException(ValueError, "No implementation available")

method addChatIfDontExist*(self: AccessInterface,
method addOrUpdateChat*(self: AccessInterface,
chat: ChatDto,
belongsToCommunity: bool,
events: UniqueUUIDEventEmitter,
Expand Down
14 changes: 7 additions & 7 deletions src/app/modules/main/chat_section/model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,13 @@ QtObject:
let modelIndex = self.createIndex(index, 0, nil)
self.dataChanged(modelIndex, modelIndex, @[ModelRole.HasUnreadMessages.int, ModelRole.NotificationsCount.int])

proc incrementNotificationsForItemByIdAndGetNotificationCount*(self: Model, id: string): int =
let index = self.getItemIdxById(id)
if index == -1:
return 0
self.updateNotificationsForItemById(id, hasUnreadMessages = true, self.items[index].notificationsCount + 1)
return self.items[index].notificationsCount

proc updateLastMessageTimestampOnItemById*(self: Model, id: string, lastMessageTimestamp: int) =
let index = self.getItemIdxById(id)
if index == -1:
Expand All @@ -454,13 +461,6 @@ QtObject:
let modelIndex = self.createIndex(index, 0, nil)
self.dataChanged(modelIndex, modelIndex, @[ModelRole.LastMessageTimestamp.int])

proc getAllNotifications*(self: Model): tuple[hasNotifications: bool, notificationsCount: int] =
result.hasNotifications = false
result.notificationsCount = 0
for i in 0 ..< self.items.len:
result.hasNotifications = result.hasNotifications or self.items[i].hasUnreadMessages
result.notificationsCount = result.notificationsCount + self.items[i].notificationsCount

proc reorderChatById*(
self: Model,
chatId: string,
Expand Down
62 changes: 39 additions & 23 deletions src/app/modules/main/chat_section/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ proc buildChatSectionUI(self: Module,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service)

proc addChatIfDontExist(self: Module,
proc addOrUpdateChat(self: Module,
chat: ChatDto,
channelGroup: ChannelGroupDto,
belongsToCommunity: bool,
Expand Down Expand Up @@ -221,7 +221,7 @@ proc buildChatSectionUI(
categoryPosition = category.position
break

self.addChatIfDontExist(
self.addOrUpdateChat(
chatDto,
channelGroup,
belongsToCommunity = chatDto.communityId.len > 0,
Expand Down Expand Up @@ -472,21 +472,36 @@ method getChatContentModule*(self: Module, chatId: string): QVariant =

return self.chatContentModules[chatId].getModuleAsVariant()

proc updateParentBadgeNotifications(self: Module, sectionHasUnreadMessagesArg: bool = false, unviewedMentionsCountArg: int = 0) =
proc updateParentBadgeNotifications(self: Module) =
let (unviewedMessagesCount, unviewedMentionsCount) = self.controller.sectionUnreadMessagesAndMentionsCount(
self.controller.getMySectionId()
)
self.delegate.onNotificationsUpdated(
self.controller.getMySectionId(),
sectionHasUnreadMessagesArg,
unviewedMentionsCountArg
unviewedMessagesCount > 0,
unviewedMentionsCount
)

proc incrementParentBadgeNotifications(self: Module) =
self.delegate.onNotificationsIncremented(self.controller.getMySectionId())

proc updateBadgeNotifications(self: Module, chatId: string, hasUnreadMessages: bool, unviewedMentionsCount: int) =
# update model of this module (appropriate chat from the chats list (chats model))
self.view.chatsModel().updateNotificationsForItemById(chatId, hasUnreadMessages, unviewedMentionsCount)
# update child module
if (self.chatContentModules.contains(chatId)):
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount)
# update parent module
self.updateParentBadgeNotifications(hasUnreadMessages, unviewedMentionsCount)
self.updateParentBadgeNotifications()

proc incrementBadgeNotifications(self: Module, chatId: string) =
if self.chatsLoaded:
let notificationCount = self.view.chatsModel().incrementNotificationsForItemByIdAndGetNotificationCount(chatId)
# update child module
if (self.chatContentModules.contains(chatId)):
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages = true, notificationCount)
# update parent module
self.incrementParentBadgeNotifications()

method updateLastMessageTimestamp*(self: Module, chatId: string, lastMessageTimestamp: int) =
self.view.chatsModel().updateLastMessageTimestampOnItemById(chatId, lastMessageTimestamp)
Expand Down Expand Up @@ -850,8 +865,6 @@ method onContactAdded*(self: Module, publicKey: string) =
if (contact.isContact):
self.switchToOrCreateOneToOneChat(publicKey)

self.updateParentBadgeNotifications()

method acceptAllContactRequests*(self: Module) =
let pubKeys = self.view.contactRequestsModel().getItemIds()
for pk in pubKeys:
Expand All @@ -862,7 +875,6 @@ method dismissContactRequest*(self: Module, publicKey: string) =

method onContactRejected*(self: Module, publicKey: string) =
self.view.contactRequestsModel().removeItemById(publicKey)
self.updateParentBadgeNotifications()

method dismissAllContactRequests*(self: Module) =
let pubKeys = self.view.contactRequestsModel().getItemIds()
Expand All @@ -875,7 +887,6 @@ method blockContact*(self: Module, publicKey: string) =
method onContactBlocked*(self: Module, publicKey: string) =
self.view.contactRequestsModel().removeItemById(publicKey)
self.view.chatsModel().changeBlockedOnItemById(publicKey, blocked=true)
self.updateParentBadgeNotifications()

method onContactUnblocked*(self: Module, publicKey: string) =
self.view.chatsModel().changeBlockedOnItemById(publicKey, blocked=false)
Expand All @@ -891,7 +902,6 @@ method onContactDetailsUpdated*(self: Module, publicKey: string) =
not self.view.contactRequestsModel().isContactWithIdAdded(publicKey)):
let item = self.createItemFromPublicKey(publicKey)
self.view.contactRequestsModel().addItem(item)
self.updateParentBadgeNotifications()
singletonInstance.globalEvents.showNewContactRequestNotification("New Contact Request",
fmt "{contactDetails.defaultDisplayName} added you as contact",
singletonInstance.userProfile.getPubKey())
Expand All @@ -914,10 +924,6 @@ method onNewMessagesReceived*(self: Module, sectionIdMsgBelongsTo: string, chatI

let chatDetails = self.controller.getChatDetails(chatIdMsgBelongsTo)

# Badge notification
let showBadge = (not chatDetails.muted and unviewedMessagesCount > 0) or unviewedMentionsCount > 0
self.updateBadgeNotifications(chatIdMsgBelongsTo, showBadge, unviewedMentionsCount)

if (chatDetails.muted):
# No need to send a notification
return
Expand Down Expand Up @@ -965,8 +971,8 @@ method onMeMentionedInEditedMessage*(self: Module, chatId: string, editedMessage
(editedMessage.communityId.len > 0 and
self.controller.getMySectionId() != editedMessage.communityId)):
return
var (sectionHasUnreadMessages, sectionNotificationCount) = self.view.chatsModel().getAllNotifications()
self.updateBadgeNotifications(chatId, sectionHasUnreadMessages, sectionNotificationCount + 1)

self.incrementBadgeNotifications(chatId)

method addGroupMembers*(self: Module, chatId: string, pubKeys: string) =
self.controller.addGroupMembers(chatId, self.convertPubKeysToJson(pubKeys))
Expand Down Expand Up @@ -1117,7 +1123,7 @@ method reorderCommunityChat*(self: Module, categoryId: string, chatId: string, p
method setLoadingHistoryMessagesInProgress*(self: Module, isLoading: bool) =
self.view.setLoadingHistoryMessagesInProgress(isLoading)

proc addChatIfDontExist(self: Module,
proc addOrUpdateChat(self: Module,
chat: ChatDto,
channelGroup: ChannelGroupDto,
belongsToCommunity: bool,
Expand All @@ -1131,15 +1137,25 @@ proc addChatIfDontExist(self: Module,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
setChatAsActive: bool = true) =
if not self.chatsLoaded:
return

let sectionId = self.controller.getMySectionId()
if(belongsToCommunity and sectionId != chat.communityId or
not belongsToCommunity and sectionId != singletonInstance.userProfile.getPubKey()):
return

if self.doesCatOrChatExist(chat.id):
let chatExists = self.doesCatOrChatExist(chat.id)

if not self.chatsLoaded or chatExists:
# Update badges
var hasUnreadMessages = false
if not chat.muted:
hasUnreadMessages = chat.unviewedMessagesCount > 0
self.updateBadgeNotifications(chat.id, hasUnreadMessages, chat.unviewedMentionsCount)

if not self.chatsLoaded:
return

if chatExists:
if (chat.chatType == ChatType.PrivateGroupChat):
self.onGroupChatDetailsUpdated(chat.id, chat.name, chat.color, chat.icon)
elif (chat.chatType != ChatType.OneToOne):
Expand All @@ -1162,7 +1178,7 @@ proc addChatIfDontExist(self: Module,
setChatAsActive,
)

method addChatIfDontExist*(self: Module,
method addOrUpdateChat*(self: Module,
chat: ChatDto,
belongsToCommunity: bool,
events: UniqueUUIDEventEmitter,
Expand All @@ -1175,7 +1191,7 @@ method addChatIfDontExist*(self: Module,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
setChatAsActive: bool = true) =
self.addChatIfDontExist(
self.addOrUpdateChat(
chat,
ChannelGroupDto(),
belongsToCommunity,
Expand Down
3 changes: 3 additions & 0 deletions src/app/modules/main/io_interface.nim
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ method onNotificationsUpdated*(self: AccessInterface, sectionId: string, section
sectionNotificationCount: int) {.base.} =
raise newException(ValueError, "No implementation available")

method onNotificationsIncremented*(self: AccessInterface, sectionId: string) {.base.} =
raise newException(ValueError, "No implementation available")

method onNotificationsIncreased*(self: AccessInterface, sectionId: string, addedSectionNotificationCount: bool,
sectionNotificationCount: int) {.base.} =
raise newException(ValueError, "No implementation available")
Expand Down
3 changes: 3 additions & 0 deletions src/app/modules/main/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,9 @@ method onNotificationsUpdated[T](self: Module[T], sectionId: string, sectionHasU
sectionNotificationCount: int) =
self.view.model().updateNotifications(sectionId, sectionHasUnreadMessages, sectionNotificationCount)

method onNotificationsIncremented[T](self: Module[T], sectionId: string) =
self.view.model().incrementNotifications(sectionId)

method onNetworkConnected[T](self: Module[T]) =
self.view.setConnected(true)

Expand Down
23 changes: 21 additions & 2 deletions src/app/modules/shared_models/section_model.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import NimQml, Tables, strutils, strformat

import json, json_serialization
import json

import section_item, member_model
import ../main/communities/tokens/models/token_item


type
ModelRole {.pure.} = enum
Id = UserRole + 1
Expand Down Expand Up @@ -261,6 +260,7 @@ QtObject:

self.items[index].muted = muted
let dataIndex = self.createIndex(index, 0, nil)
defer: dataIndex.delete
self.dataChanged(dataIndex, dataIndex, @[ModelRole.Muted.int])


Expand All @@ -271,6 +271,7 @@ QtObject:

self.items[index] = item
let dataIndex = self.createIndex(index, 0, nil)
defer: dataIndex.delete
self.dataChanged(dataIndex, dataIndex, @[
ModelRole.Name.int,
ModelRole.Description.int,
Expand Down Expand Up @@ -330,11 +331,13 @@ QtObject:
for i in 0 ..< self.items.len:
if(self.items[i].active):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].active = false
self.dataChanged(index, index, @[ModelRole.Active.int])

if(self.items[i].id == id):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].active = true
self.items[i].loaderActive = true

Expand All @@ -349,6 +352,7 @@ QtObject:
for i in 0 ..< self.items.len:
if(self.items[i].sectionType == sectionType):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].enabled = value
self.dataChanged(index, index, @[ModelRole.Enabled.int])
else:
Expand Down Expand Up @@ -386,16 +390,30 @@ QtObject:
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].hasNotification = hasNotification
self.items[i].notificationsCount = notificationsCount
self.dataChanged(index, index, @[ModelRole.HasNotification.int, ModelRole.NotificationsCount.int])
self.notificationsCountChanged()
return

proc incrementNotifications*(self: SectionModel, id: string) =
let index = self.getItemIndex(id)
if (index == -1):
return

self.items[index].hasNotification = true
self.items[index].notificationsCount = self.items[index].notificationsCount + 1
let modelIndex = self.createIndex(index, 0, nil)
defer: modelIndex.delete
self.dataChanged(modelIndex, modelIndex, @[ModelRole.HasNotification.int, ModelRole.NotificationsCount.int])
self.notificationsCountChanged()

proc appendCommunityToken*(self: SectionModel, id: string, item: TokenItem) =
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].appendCommunityToken(item)
self.dataChanged(index, index, @[ModelRole.CommunityTokensModel.int])
return
Expand Down Expand Up @@ -443,5 +461,6 @@ QtObject:
for i in 0 ..< self.items.len:
if(self.items[i].id == sectionId):
let index = self.createIndex(i, 0, nil)
defer: index.delete
self.items[i].loaderActive = false
self.dataChanged(index, index, @[ModelRole.LoaderActive.int])
Loading

0 comments on commit 44b9522

Please sign in to comment.