refactor(@desktop/chat): reading a channel message does not mark it as read
- non active chats/channels are made bold if there are new messages inside them a dot badge is added to the chat/community section if it's needed in that case - for non active chats/channels count badge is added if there are new mentions inside them, a count badge is added to the chat/community section if it's needed in that case - selecting chat/channel marks messages from it as read and update its displaying and dot/count badge of chat/community section accordingly Fixes #4403
This commit is contained in:
parent
f0ca1a4cc3
commit
46211c38ee
|
@ -253,4 +253,7 @@ method onContactDetailsUpdated*(self: Module, contactId: string) =
|
|||
self.view.pinnedModel().updateSenderDetails(contactId, updatedContact.displayName, updatedContact.details.localNickname,
|
||||
updatedContact.icon, updatedContact.isIdenticon)
|
||||
if(self.controller.getMyChatId() == contactId):
|
||||
self.view.updateChatDetails(updatedContact.displayName, updatedContact.icon, updatedContact.isIdenticon)
|
||||
self.view.updateChatDetailsNameAndIcon(updatedContact.displayName, updatedContact.icon, updatedContact.isIdenticon)
|
||||
|
||||
method onNotificationsUpdated*(self: Module, hasUnreadMessages: bool, notificationCount: int) =
|
||||
self.view.updateChatDetailsNotifications(hasUnreadMessages, notificationCount)
|
||||
|
|
|
@ -10,4 +10,7 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
|
|||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onNotificationsUpdated*(self: AccessInterface, hasUnreadMessages: bool, notificationCount: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -94,10 +94,14 @@ QtObject:
|
|||
proc setMuted*(self: View, muted: bool) =
|
||||
self.chatDetails.setMuted(muted)
|
||||
|
||||
proc updateChatDetails*(self: View, name, icon: string, isIdenticon: bool) =
|
||||
proc updateChatDetailsNameAndIcon*(self: View, name, icon: string, isIdenticon: bool) =
|
||||
self.chatDetails.setName(name)
|
||||
self.chatDetails.setIcon(icon, isIdenticon)
|
||||
|
||||
proc updateChatDetailsNotifications*(self: View, hasUnreadMessages: bool, notificationCount: int) =
|
||||
self.chatDetails.setHasUnreadMessages(hasUnreadMessages)
|
||||
self.chatDetails.setNotificationCount(notificationCount)
|
||||
|
||||
proc getChatDetails(self: View): QVariant {.slot.} =
|
||||
return self.chatDetailsVariant
|
||||
QtProperty[QVariant] chatDetails:
|
||||
|
|
|
@ -46,6 +46,14 @@ method delete*(self: Controller) =
|
|||
discard
|
||||
|
||||
method init*(self: Controller) =
|
||||
self.events.on(SIGNAL_NEW_MESSAGE_RECEIVED) do(e: Args):
|
||||
let args = MessagesArgs(e)
|
||||
if(self.isCommunitySection and args.chatType != ChatType.CommunityChat or
|
||||
not self.isCommunitySection and args.chatType == ChatType.CommunityChat):
|
||||
return
|
||||
self.delegate.onNewMessagesReceived(args.chatId, args.unviewedMessagesCount, args.unviewedMentionsCount,
|
||||
args.messages)
|
||||
|
||||
self.events.on(chat_service.SIGNAL_CHAT_MUTED) do(e:Args):
|
||||
let args = chat_service.ChatArgs(e)
|
||||
self.delegate.onChatMuted(args.chatId)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import NimQml, Tables, strutils, strformat, json
|
||||
|
||||
import item, base_item, sub_model
|
||||
from ../../../../app_service/service/chat/dto/chat import ChatType
|
||||
import item, sub_item, base_item, sub_model
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
|
@ -161,6 +161,12 @@ QtObject:
|
|||
if(it.id == id):
|
||||
return it
|
||||
|
||||
proc getSubItemById*(self: Model, id: string): SubItem =
|
||||
for it in self.items:
|
||||
let item = it.subItems.getItemById(id)
|
||||
if(not item.isNil):
|
||||
return item
|
||||
|
||||
proc setActiveItemSubItem*(self: Model, id: string, subItemId: string) =
|
||||
for i in 0 ..< self.items.len:
|
||||
self.items[i].setActiveSubItem(subItemId)
|
||||
|
@ -193,19 +199,11 @@ QtObject:
|
|||
self.dataChanged(index, index, @[ModelRole.Muted.int])
|
||||
return
|
||||
|
||||
var found = false
|
||||
if self.items[i].subItems.muteUnmuteItemById(id, mute):
|
||||
return
|
||||
|
||||
proc setHasUnreadMessage*(self: Model, id: string, value: 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.hasUnreadMessages = value
|
||||
self.dataChanged(index, index, @[ModelRole.HasUnreadMessages.int])
|
||||
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:
|
||||
if(self.items[i].id == id):
|
||||
self.items[i].BaseItem.name = name
|
||||
|
@ -213,4 +211,29 @@ QtObject:
|
|||
self.items[i].BaseItem.isIdenticon = isIdenticon
|
||||
let index = self.createIndex(i, 0, nil)
|
||||
self.dataChanged(index, index, @[ModelRole.Name.int, ModelRole.Icon.int, ModelRole.IsIdenticon.int])
|
||||
return
|
||||
return
|
||||
|
||||
proc updateNotificationsForItemOrSubItemById*(self: Model, id: string, hasUnreadMessages: bool,
|
||||
notificationsCount: int) =
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].id == id):
|
||||
let index = self.createIndex(i, 0, nil)
|
||||
self.items[i].BaseItem.hasUnreadMessages = hasUnreadMessages
|
||||
self.items[i].BaseItem.notificationsCount = notificationsCount
|
||||
self.dataChanged(index, index, @[ModelRole.HasUnreadMessages.int, ModelRole.NotificationsCount.int])
|
||||
return
|
||||
|
||||
if self.items[i].subItems.updateNotificationsForItemById(id, hasUnreadMessages, notificationsCount):
|
||||
return
|
||||
|
||||
proc getAllNotifications*(self: Model): tuple[hasNotifications: bool, notificationsCount: int] =
|
||||
result.hasNotifications = false
|
||||
result.notificationsCount = 0
|
||||
for i in 0 ..< self.items.len:
|
||||
# if it's category item type is set to `ChatType.Unknown`
|
||||
# (in one point of time we may start maintaining notifications per category as well)
|
||||
if(self.items[i].BaseItem.`type` == ChatType.Unknown.int):
|
||||
continue
|
||||
|
||||
result.hasNotifications = result.hasNotifications or self.items[i].BaseItem.hasUnreadMessages
|
||||
result.notificationsCount = result.notificationsCount + self.items[i].BaseItem.notificationsCount
|
|
@ -108,7 +108,7 @@ proc buildChatUI(self: Module, events: EventEmitter,
|
|||
|
||||
let item = initItem(c.id, chatName, chatImage, isIdenticon, c.color, c.description, c.chatType.int, amIChatAdmin,
|
||||
hasNotification, notificationsCount, c.muted, false, 0)
|
||||
self.view.appendItem(item)
|
||||
self.view.chatsModel().appendItem(item)
|
||||
self.addSubmodule(c.id, false, isUsersListAvailable, events, settingsService, contactService, chatService,
|
||||
communityService, messageService)
|
||||
|
||||
|
@ -141,7 +141,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, false, c.position)
|
||||
self.view.appendItem(channelItem)
|
||||
self.view.chatsModel().appendItem(channelItem)
|
||||
self.addSubmodule(chatDto.id, true, true, events, settingsService, contactService, chatService, communityService,
|
||||
messageService)
|
||||
|
||||
|
@ -184,7 +184,7 @@ proc buildCommunityUI(self: Module, events: EventEmitter,
|
|||
var categoryItem = initItem(cat.id, cat.name, "", false, "", "", ChatType.Unknown.int, false,
|
||||
hasNotificationPerCategory, notificationsCountPerCategory, false, false, cat.position)
|
||||
categoryItem.prependSubItems(categoryChannels)
|
||||
self.view.appendItem(categoryItem)
|
||||
self.view.chatsModel().appendItem(categoryItem)
|
||||
|
||||
self.setActiveItemSubItem(selectedItemId, selectedSubItemId)
|
||||
|
||||
|
@ -260,10 +260,13 @@ method activeItemSubItemSet*(self: Module, itemId: string, subItemId: string) =
|
|||
# to any category have empty `subItemId`
|
||||
let subItem = item.subItems.getItemById(subItemId)
|
||||
|
||||
# update view maintained by this module
|
||||
self.view.chatsModel().setActiveItemSubItem(itemId, subItemId)
|
||||
self.view.activeItemSubItemSet(item, subItem)
|
||||
|
||||
# notify parent module about active chat/channel
|
||||
self.delegate.onActiveChatChange(self.controller.getMySectionId(), self.controller.getActiveChatId())
|
||||
# update notifications caused by setting active chat/channel
|
||||
self.controller.markAllMessagesRead(self.controller.getActiveChatId())
|
||||
|
||||
method getModuleAsVariant*(self: Module): QVariant =
|
||||
return self.viewVariant
|
||||
|
@ -316,7 +319,7 @@ method addNewChat*(
|
|||
self.addSubmodule(chatDto.id, false, isUsersListAvailable, events, settingsService, contactService, chatService,
|
||||
communityService, messageService)
|
||||
self.chatContentModules[chatDto.id].load()
|
||||
self.view.appendItem(item)
|
||||
self.view.chatsModel().appendItem(item)
|
||||
|
||||
# make new added chat active one
|
||||
self.setActiveItemSubItem(item.id, "")
|
||||
|
@ -325,7 +328,7 @@ method removeChat*(self: Module, chatId: string) =
|
|||
if(not self.chatContentModules.contains(chatId)):
|
||||
return
|
||||
|
||||
self.view.removeItem(chatId)
|
||||
self.view.chatsModel().removeItemById(chatId)
|
||||
self.removeSubmodule(chatId)
|
||||
|
||||
# remove active state form the removed chat (if applicable)
|
||||
|
@ -342,6 +345,16 @@ method createOneToOneChat*(self: Module, chatId: string, ensName: string) =
|
|||
|
||||
self.controller.createOneToOneChat(chatId, ensName)
|
||||
|
||||
proc updateNotifications(self: Module, chatId: string, unviewedMessagesCount: int, unviewedMentionsCount: int) =
|
||||
let hasUnreadMessages = unviewedMessagesCount > 0
|
||||
# update model of this module (appropriate chat from the chats list (chats model))
|
||||
self.view.chatsModel().updateNotificationsForItemOrSubItemById(chatId, hasUnreadMessages, unviewedMentionsCount)
|
||||
# update child module
|
||||
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount)
|
||||
# update parent module
|
||||
let (sectionHasUnreadMessages, sectionNotificationCount) = self.view.chatsModel().getAllNotifications()
|
||||
self.delegate.onNotificationsUpdated(self.controller.getMySectionId(), sectionHasUnreadMessages, sectionNotificationCount)
|
||||
|
||||
method leaveChat*(self: Module, chatId: string) =
|
||||
self.controller.leaveChat(chatId)
|
||||
|
||||
|
@ -358,7 +371,7 @@ method onChatUnmuted*(self: Module, chatId: string) =
|
|||
self.view.chatsModel().muteUnmuteItemOrSubItemById(chatId, false)
|
||||
|
||||
method onMarkAllMessagesRead*(self: Module, chatId: string) =
|
||||
self.view.chatsModel().setHasUnreadMessage(chatId, value=false)
|
||||
self.updateNotifications(chatId, unviewedMessagesCount=0, unviewedMentionsCount=0)
|
||||
|
||||
method markAllMessagesRead*(self: Module, chatId: string) =
|
||||
self.controller.markAllMessagesRead(chatId)
|
||||
|
@ -399,4 +412,12 @@ method onContactBlocked*(self: Module, publicKey: string) =
|
|||
|
||||
method onContactDetailsUpdated*(self: Module, publicKey: string) =
|
||||
let (chatName, chatImage, isIdenticon) = self.controller.getOneToOneChatNameAndImage(publicKey)
|
||||
self.view.chatsModel().updateItemDetails(publicKey, chatName, chatImage, isIdenticon)
|
||||
self.view.chatsModel().updateItemDetails(publicKey, chatName, chatImage, isIdenticon)
|
||||
|
||||
method onNewMessagesReceived*(self: Module, chatId: string, unviewedMessagesCount: int, unviewedMentionsCount: int,
|
||||
messages: seq[MessageDto]) =
|
||||
let activeChatId = self.controller.getActiveChatId()
|
||||
if(activeChatId == chatId):
|
||||
self.controller.markAllMessagesRead(chatId)
|
||||
else:
|
||||
self.updateNotifications(chatId, unviewedMessagesCount, unviewedMentionsCount)
|
|
@ -7,6 +7,10 @@ method addNewChat*(self: AccessInterface, chatDto: ChatDto, events: EventEmitter
|
|||
messageService: message_service.Service) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onNewMessagesReceived*(self: AccessInterface, chatId: string, unviewedMessagesCount: int,
|
||||
unviewedMentionsCount: int, messages: seq[MessageDto]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onChatMuted*(self: AccessInterface, chatId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -189,5 +189,15 @@ QtObject:
|
|||
self.items[i].BaseItem.muted = mute
|
||||
self.dataChanged(index, index, @[ModelRole.Muted.int])
|
||||
return true
|
||||
return false
|
||||
|
||||
proc updateNotificationsForItemById*(self: SubModel, id: string, hasUnreadMessages: bool,
|
||||
notificationsCount: int): 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.hasUnreadMessages = hasUnreadMessages
|
||||
self.items[i].BaseItem.notificationsCount = notificationsCount
|
||||
self.dataChanged(index, index, @[ModelRole.HasUnreadMessages.int, ModelRole.NotificationsCount.int])
|
||||
return true
|
||||
return false
|
|
@ -58,15 +58,6 @@ QtObject:
|
|||
QtProperty[QVariant] contactRequestsModel:
|
||||
read = getContactRequestsModel
|
||||
|
||||
proc appendItem*(self: View, item: Item) =
|
||||
self.model.appendItem(item)
|
||||
|
||||
proc removeItem*(self: View, id: string) =
|
||||
self.model.removeItemById(id)
|
||||
|
||||
proc prependItem*(self: View, item: Item) =
|
||||
self.model.prependItem(item)
|
||||
|
||||
proc activeItemChanged*(self:View) {.signal.}
|
||||
|
||||
proc getActiveItem(self: View): QVariant {.slot.} =
|
||||
|
|
|
@ -480,6 +480,10 @@ method getCommunitySectionModule*[T](self: Module[T], communityId: string): QVar
|
|||
method onActiveChatChange*[T](self: Module[T], sectionId: string, chatId: string) =
|
||||
self.appSearchModule.onActiveChatChange(sectionId, chatId)
|
||||
|
||||
method onNotificationsUpdated[T](self: Module[T], sectionId: string, sectionHasUnreadMessages: bool,
|
||||
sectionNotificationCount: int) =
|
||||
self.view.model().udpateNotifications(sectionId, sectionHasUnreadMessages, sectionNotificationCount)
|
||||
|
||||
method getAppSearchModule*[T](self: Module[T]): QVariant =
|
||||
self.appSearchModule.getModuleAsVariant()
|
||||
|
||||
|
|
|
@ -5,4 +5,8 @@ method communitySectionDidLoad*(self: AccessInterface) {.base.} =
|
|||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onActiveChatChange*(self: AccessInterface, sectionId: string, chatId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onNotificationsUpdated*(self: AccessInterface, sectionId: string, sectionHasUnreadMessages: bool,
|
||||
sectionNotificationCount: int) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -213,3 +213,12 @@ QtObject:
|
|||
|
||||
proc disableSection*(self: SectionModel, sectionType: SectionType) =
|
||||
self.enableDisableSection(sectionType, false)
|
||||
|
||||
proc udpateNotifications*(self: SectionModel, id: string, hasNotification: bool, notificationsCount: int) =
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].id == id):
|
||||
let index = self.createIndex(i, 0, nil)
|
||||
self.items[i].hasNotification = hasNotification
|
||||
self.items[i].notificationsCount = notificationsCount
|
||||
self.dataChanged(index, index, @[ModelRole.HasNotification.int, ModelRole.NotificationsCount.int])
|
||||
return
|
|
@ -35,6 +35,9 @@ include async_tasks
|
|||
type
|
||||
MessagesArgs* = ref object of Args
|
||||
chatId*: string
|
||||
chatType*: ChatType
|
||||
unviewedMessagesCount*: int
|
||||
unviewedMentionsCount*: int
|
||||
messages*: seq[MessageDto]
|
||||
|
||||
MessagesLoadedArgs* = ref object of Args
|
||||
|
@ -98,6 +101,12 @@ QtObject:
|
|||
# The first element from the `receivedData.chats` array contains details about the chat a messages received in
|
||||
# `receivedData.messages` refer to.
|
||||
let chatId = receivedData.chats[0].id
|
||||
let chatType = receivedData.chats[0].chatType
|
||||
let unviewedMessagesCount = receivedData.chats[0].unviewedMessagesCount
|
||||
let unviewedMentionsCount = receivedData.chats[0].unviewedMentionsCount
|
||||
if(chatType == ChatType.Unknown):
|
||||
error "error: new message with an unknown chat type received for chat id ", chatId
|
||||
return
|
||||
|
||||
# In case of reply to a message we're receiving 2 messages in the `receivedData.messages` array (replied message
|
||||
# and a message one replied to) but we actually need only a new replied message, that's why we need to filter
|
||||
|
@ -113,7 +122,12 @@ QtObject:
|
|||
for msgId in messagesOneRepliedTo:
|
||||
removeMessageWithId(receivedData.messages, msgId)
|
||||
|
||||
let data = MessagesArgs(chatId: chatId, messages: receivedData.messages)
|
||||
let data = MessagesArgs(chatId: chatId,
|
||||
chatType: chatType,
|
||||
unviewedMessagesCount: unviewedMessagesCount,
|
||||
unviewedMentionsCount: unviewedMentionsCount,
|
||||
messages: receivedData.messages
|
||||
)
|
||||
self.events.emit(SIGNAL_NEW_MESSAGE_RECEIVED, data)
|
||||
# Handling pinned messages updates
|
||||
if (receivedData.pinnedMessages.len > 0):
|
||||
|
|
Loading…
Reference in New Issue