diff --git a/src/app/modules/main/chat_section/base_item.nim b/src/app/modules/main/chat_section/base_item.nim index 5757f07fee..e96db76e76 100644 --- a/src/app/modules/main/chat_section/base_item.nim +++ b/src/app/modules/main/chat_section/base_item.nim @@ -15,6 +15,7 @@ type emoji: string colorHash: color_hash_model.Model description: string + lastMessageTimestamp: int hasUnreadMessages: bool notificationsCount: int muted: bool @@ -26,7 +27,7 @@ type trustStatus: TrustStatus proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: string, - `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, + `type`: int, amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string = "", colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false, trustStatus: TrustStatus = TrustStatus.Unknown) = @@ -41,6 +42,7 @@ proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: s self.colorHash.setItems(map(colorHash, x => color_hash_item.initItem(x.len, x.colorIdx))) self.description = description self.`type` = `type` + self.lastMessageTimestamp = lastMessageTimestamp self.hasUnreadMessages = hasUnreadMessages self.notificationsCount = notificationsCount self.muted = muted @@ -52,11 +54,11 @@ proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: s self.trustStatus = trustStatus proc initBaseItem*(id, name, icon: string, color, emoji, description: string, `type`: int, - amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, + amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string = "", colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false, trustStatus: TrustStatus = TrustStatus.Unknown): BaseItem = result = BaseItem() - result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, + result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight, trustStatus) @@ -114,6 +116,12 @@ method hasUnreadMessages*(self: BaseItem): bool {.inline base.} = method `hasUnreadMessages=`*(self: var BaseItem, value: bool) {.inline base.} = self.hasUnreadMessages = value +method lastMessageTimestamp*(self: BaseItem): int {.inline base.} = + self.lastMessageTimestamp + +method `lastMessageTimestamp=`*(self: var BaseItem, value: int) {.inline base.} = + self.lastMessageTimestamp = value + method notificationsCount*(self: BaseItem): int {.inline base.} = self.notificationsCount diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 51391eb211..c472040eb6 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -65,8 +65,8 @@ proc init*(self: Controller) = let args = MessagesArgs(e) if (self.sectionId != args.sectionId or args.messages.len == 0): return - self.delegate.onNewMessagesReceived(args.sectionId, args.chatId, args.chatType, args.unviewedMessagesCount, - args.unviewedMentionsCount, args.messages[0]) + self.delegate.onNewMessagesReceived(args.sectionId, args.chatId, args.chatType, args.lastMessageTimestamp, + args.unviewedMessagesCount, args.unviewedMentionsCount, args.messages[0]) self.events.on(message_service.SIGNAL_MENTIONED_IN_EDITED_MESSAGE) do(e: Args): let args = MessageEditedArgs(e) diff --git a/src/app/modules/main/chat_section/io_interface.nim b/src/app/modules/main/chat_section/io_interface.nim index 89a649cd93..7b266014a8 100644 --- a/src/app/modules/main/chat_section/io_interface.nim +++ b/src/app/modules/main/chat_section/io_interface.nim @@ -82,7 +82,7 @@ method addChatIfDontExist*(self: AccessInterface, raise newException(ValueError, "No implementation available") method onNewMessagesReceived*(self: AccessInterface, sectionIdMsgBelongsTo: string, chatIdMsgBelongsTo: string, - chatTypeMsgBelongsTo: ChatType, unviewedMessagesCount: int, unviewedMentionsCount: int, message: MessageDto) {.base.} = + chatTypeMsgBelongsTo: ChatType, lastMessageTimestamp: int, unviewedMessagesCount: int, unviewedMentionsCount: int, message: MessageDto) {.base.} = raise newException(ValueError, "No implementation available") method onChatMuted*(self: AccessInterface, chatId: string) {.base.} = diff --git a/src/app/modules/main/chat_section/item.nim b/src/app/modules/main/chat_section/item.nim index 232eacd5c0..369a1d673c 100644 --- a/src/app/modules/main/chat_section/item.nim +++ b/src/app/modules/main/chat_section/item.nim @@ -7,10 +7,10 @@ type subItems: SubModel proc initItem*(id, name, icon: string, color, emoji, description: string, - `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, + `type`: int, amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int, categoryId: string, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false): Item = result = Item() - result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, hasUnreadMessages, + result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight) result.subItems = newSubModel() @@ -31,6 +31,7 @@ proc `$`*(self: Item): string = emoji: {self.emoji}, description: {self.description}, type: {self.`type`}, + lastMessageTimestamp: {self.lastMessageTimestamp}, hasUnreadMessages: {self.hasUnreadMessages}, notificationsCount: {self.notificationsCount}, muted: {self.muted}, @@ -54,6 +55,7 @@ proc toJsonNode*(self: Item): JsonNode = "emoji": self.emoji, "description": self.description, "type": self.`type`, + "lastMessageTimestamp": self.lastMessageTimestamp, "hasUnreadMessages": self.hasUnreadMessages, "notificationsCount": self.notificationsCount, "muted": self.muted, diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index 87413c528c..bea2da563e 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -15,6 +15,7 @@ type ColorHash Description Type + LastMessageTimestamp HasUnreadMessages NotificationsCount Muted @@ -79,6 +80,7 @@ QtObject: ModelRole.ColorHash.int:"colorHash", ModelRole.Description.int:"description", ModelRole.Type.int:"type", + ModelRole.LastMessageTimestamp.int:"lastMessageTimestamp", ModelRole.HasUnreadMessages.int:"hasUnreadMessages", ModelRole.NotificationsCount.int:"notificationsCount", ModelRole.Muted.int:"muted", @@ -123,6 +125,8 @@ QtObject: result = newQVariant(item.description) of ModelRole.Type: result = newQVariant(item.`type`) + of ModelRole.LastMessageTimestamp: + result = newQVariant(item.lastMessageTimestamp) of ModelRole.HasUnreadMessages: result = newQVariant(item.hasUnreadMessages) of ModelRole.NotificationsCount: @@ -236,7 +240,7 @@ QtObject: if self.items[i].subItems.muteUnmuteItemById(id, mute): self.items[i].BaseItem.muted = self.items[i].subItems.isAllMuted() return - + proc muteUnmuteItemsOrSubItemsByCategoryId*(self: Model, categoryId: string, mute: bool) = for i in 0 ..< self.items.len: if(self.items[i].categoryId == categoryId): @@ -314,6 +318,14 @@ QtObject: if self.items[i].subItems.updateNotificationsForItemById(id, hasUnreadMessages, notificationsCount): return + proc updateLastMessageTimestampForItemById*(self: Model, id: string, lastMessageTimestamp: 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.lastMessageTimestamp = lastMessageTimestamp + self.dataChanged(index, index, @[ModelRole.LastMessageTimestamp.int]) + return + proc getAllNotifications*(self: Model): tuple[hasNotifications: bool, notificationsCount: int] = result.hasNotifications = false result.notificationsCount = 0 diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 7fcc76d136..633790a8f0 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -154,7 +154,7 @@ proc buildChatSectionUI( amIChatAdmin = amIChatAdmin or channelGroup.admin let channelItem = initItem(chatDto.id, chatName, chatImage, chatDto.color, - chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, + chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked, chatDto.active, chatDto.position, chatDto.categoryId, colorId, colorHash) self.view.chatsModel().appendItem(channelItem) @@ -184,7 +184,7 @@ proc buildChatSectionUI( let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.icon, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, - amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, blocked=false, + amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, chatDto.position) categoryChannels.add(channelItem) self.addSubmodule(chatDto.id, belongToCommunity=true, isUsersListAvailable=true, events, @@ -198,7 +198,7 @@ proc buildChatSectionUI( selectedSubItemId = channelItem.id var categoryItem = initItem(cat.id, cat.name, icon="", color="", emoji="", - description="", ChatType.Unknown.int, amIChatAdmin=false, hasNotificationPerCategory, + description="", ChatType.Unknown.int, amIChatAdmin=false, lastMessageTimestamp=(-1), hasNotificationPerCategory, notificationsCountPerCategory, muted=false, blocked=false, active=false, cat.position, cat.id) categoryItem.appendSubItems(categoryChannels) @@ -363,6 +363,9 @@ proc updateBadgeNotifications(self: Module, chatId: string, hasUnreadMessages: b # update parent module self.updateParentBadgeNotifications() +proc updateLastMessageTimestamp(self: Module, chatId: string, lastMessageTimestamp: int) = + self.view.chatsModel().updateLastMessageTimestampForItemById(chatId, lastMessageTimestamp) + method onActiveSectionChange*(self: Module, sectionId: string) = if(sectionId != self.controller.getMySectionId()): return @@ -418,7 +421,7 @@ method addNewChat*( if chatDto.categoryId.len == 0: let item = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji, - chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, + chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorId, colorHash, chatDto.highlight) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -434,7 +437,7 @@ method addNewChat*( let channelItem = initSubItem(chatDto.id, chatDto.categoryId, chatDto.name, chatDto.icon, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, - amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, + amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, chatDto.position) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -460,7 +463,7 @@ method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatD if (self.doesCatOrChatExist(cat.id)): return var categoryItem = initItem(cat.id, cat.name, icon="", color="", emoji="", - description="", ChatType.Unknown.int, amIChatAdmin=false, hasUnreadMessages=false, + description="", ChatType.Unknown.int, amIChatAdmin=false, lastMessageTimestamp=(-1), hasUnreadMessages=false, notificationsCount=0, muted=false, blocked=false, active=false, cat.position, cat.id) var categoryChannels: seq[SubItem] for chatDto in chats: @@ -468,7 +471,7 @@ method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatD let notificationsCount = chatDto.unviewedMentionsCount let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.icon, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, - amIChatAdmin=true, hasNotification, notificationsCount, chatDto.muted, blocked=false, + amIChatAdmin=true, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, chatDto.position) # Important: @@ -491,7 +494,7 @@ method onCommunityCategoryDeleted*(self: Module, cat: Category) = let notificationsCount = chatDto.unviewedMentionsCount let amIChatAdmin = self.controller.getMyCommunity().admin let channelItem = initItem(chatDto.id, chatDto.name, chatDto.icon, - chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, + chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, false, active = false, chatDto.position, categoryId="") self.view.chatsModel().removeItemById(c.id) @@ -532,13 +535,13 @@ method onCommunityCategoryEdited*(self: Module, cat: Category, chats: seq[ChatDt if chatDto.categoryId == cat.id: let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.icon, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, - amIChatAdmin=true, hasNotification, notificationsCount, chatDto.muted, blocked=false, + amIChatAdmin=true, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active=false, chatDto.position) categoryItem.appendSubItem(channelItem) else: let channelItem = initItem(chatDto.id, chatDto.name, chatDto.icon, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, - hasNotification, notificationsCount, chatDto.muted, blocked=false, active = false, + chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked=false, active = false, chatDto.position, categoryId="") self.view.chatsModel().appendItem(channelItem) @@ -676,7 +679,9 @@ method onContactDetailsUpdated*(self: Module, publicKey: string) = self.view.chatsModel().updateItemDetails(publicKey, chatName, chatImage, trustStatus) method onNewMessagesReceived*(self: Module, sectionIdMsgBelongsTo: string, chatIdMsgBelongsTo: string, - chatTypeMsgBelongsTo: ChatType, unviewedMessagesCount: int, unviewedMentionsCount: int, message: MessageDto) = + chatTypeMsgBelongsTo: ChatType, lastMessageTimestamp: int, unviewedMessagesCount: int, unviewedMentionsCount: int, message: MessageDto) = + self.updateLastMessageTimestamp(chatIdMsgBelongsTo, lastMessageTimestamp) + let messageBelongsToActiveSection = sectionIdMsgBelongsTo == self.controller.getMySectionId() and self.controller.getMySectionId() == self.delegate.getActiveSectionId() let messageBelongsToActiveChat = self.controller.getActiveChatId() == chatIdMsgBelongsTo @@ -802,14 +807,14 @@ method prepareEditCategoryModel*(self: Module, categoryId: string) = for chat in chats: let c = self.controller.getChatDetails(chat.id) let item = initItem(c.id, c.name, icon="", c.color, c.emoji, c.description, - c.chatType.int, amIChatAdmin=false, hasUnreadMessages=false, notificationsCount=0, c.muted, + c.chatType.int, amIChatAdmin=false, lastMessageTimestamp=(-1), hasUnreadMessages=false, notificationsCount=0, c.muted, blocked=false, active=false, c.position, categoryId="") self.view.editCategoryChannelsModel().appendItem(item) let catChats = self.controller.getChats(communityId, categoryId) for chat in catChats: let c = self.controller.getChatDetails(chat.id) let item = initItem(c.id, c.name, icon="", c.color, c.emoji, c.description, - c.chatType.int, amIChatAdmin=false, hasUnreadMessages=false, notificationsCount=0, c.muted, + c.chatType.int, amIChatAdmin=false, lastMessageTimestamp=(-1), hasUnreadMessages=false, notificationsCount=0, c.muted, blocked=false, active=false, c.position, categoryId) self.view.editCategoryChannelsModel().appendItem(item) diff --git a/src/app/modules/main/chat_section/sub_item.nim b/src/app/modules/main/chat_section/sub_item.nim index f92e7653af..f29cba5c11 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, color, emoji, description: string, - `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, + `type`: int, amIChatAdmin: bool, lastMessageTimestamp: int, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, position: int): SubItem = result = SubItem() - result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, + result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages, notificationsCount, muted, blocked, active, position) result.parentId = parentId @@ -32,6 +32,7 @@ proc `$`*(self: SubItem): string = emoji: {self.emoji}, description: {self.description}, type: {self.`type`}, + lastMessageTimestamp: {self.lastMessageTimestamp}, hasUnreadMessages: {self.hasUnreadMessages}, notificationsCount: {self.notificationsCount}, muted: {self.muted}, @@ -50,6 +51,7 @@ proc toJsonNode*(self: SubItem): JsonNode = "emoji": self.emoji, "description": self.description, "type": self.`type`, + "lastMessageTimestamp": self.lastMessageTimestamp, "hasUnreadMessages": self.hasUnreadMessages, "notificationsCount": self.notificationsCount, "muted": self.muted, diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim index 3ee3f8dfe3..9a535694a9 100644 --- a/src/app_service/service/message/service.nim +++ b/src/app_service/service/message/service.nim @@ -60,6 +60,7 @@ type sectionId*: string chatId*: string chatType*: ChatType + lastMessageTimestamp*: int unviewedMessagesCount*: int unviewedMentionsCount*: int messages*: seq[MessageDto] @@ -186,6 +187,7 @@ QtObject: sectionId: chats[i].communityId, chatId: chats[i].id, chatType: chats[i].chatType, + lastMessageTimestamp: chats[i].timestamp.int, unviewedMessagesCount: chats[i].unviewedMessagesCount, unviewedMentionsCount: chats[i].unviewedMentionsCount, messages: chatMessages