From ad996d4884d086d161858754074009b80f168211 Mon Sep 17 00:00:00 2001 From: Patryk Osmaczko Date: Fri, 9 Sep 2022 13:30:22 +0200 Subject: [PATCH] feat(@Desktop/chat): extend chat section model with onlineStatus closes: #7279 --- .../modules/main/chat_section/base_item.nim | 16 ++++++++++--- .../modules/main/chat_section/controller.nim | 4 ++++ .../main/chat_section/io_interface.nim | 3 +++ src/app/modules/main/chat_section/item.nim | 10 ++++++-- src/app/modules/main/chat_section/model.nim | 15 ++++++++++++ src/app/modules/main/chat_section/module.nim | 17 ++++++++++++-- src/app/modules/main/communities/module.nim | 1 + src/app/modules/main/module.nim | 2 +- .../main/profile_section/contacts/module.nim | 1 + .../modules/shared_models/active_section.nim | 4 +++- src/app/modules/shared_models/member_item.nim | 2 ++ .../modules/shared_models/member_model.nim | 1 + .../modules/shared_models/section_item.nim | 2 ++ src/app/modules/shared_models/user_item.nim | 10 -------- src/app/modules/shared_models/user_model.nim | 2 ++ src/app_service/common/types.nim | 23 ++++++++++++++----- 16 files changed, 88 insertions(+), 25 deletions(-) diff --git a/src/app/modules/main/chat_section/base_item.nim b/src/app/modules/main/chat_section/base_item.nim index e96db76e76..b7ced7f841 100644 --- a/src/app/modules/main/chat_section/base_item.nim +++ b/src/app/modules/main/chat_section/base_item.nim @@ -1,4 +1,6 @@ import sequtils, sugar + +import ../../../../app_service/common/types import ../../../../app_service/service/contacts/dto/contacts import ../../shared_models/[color_hash_item, color_hash_model] @@ -25,12 +27,13 @@ type categoryId: string highlight: bool trustStatus: TrustStatus + onlineStatus: OnlineStatus proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: string, `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) = + trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive) = self.id = id self.name = name self.amIChatAdmin = amIChatAdmin @@ -52,15 +55,16 @@ proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: s self.categoryId = categoryId self.highlight = highlight self.trustStatus = trustStatus + self.onlineStatus = onlineStatus proc initBaseItem*(id, name, icon: string, color, emoji, description: string, `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): BaseItem = + highlight: bool = false, trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive): BaseItem = result = BaseItem() result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, colorId, - colorHash, highlight, trustStatus) + colorHash, highlight, trustStatus, onlineStatus) proc delete*(self: BaseItem) = discard @@ -169,3 +173,9 @@ method trustStatus*(self: BaseItem): TrustStatus {.inline base.} = method `trustStatus=`*(self: var BaseItem, value: TrustStatus) {.inline base.} = self.trustStatus = value + +method onlineStatus*(self: BaseItem): OnlineStatus {.inline base.} = + self.onlineStatus + +method `onlineStatus=`*(self: var BaseItem, value: OnlineStatus) {.inline base.} = + self.onlineStatus = value diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 2e654c08d7..90a6a38c0e 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -226,6 +226,10 @@ proc init*(self: Controller) = return self.delegate.createOneToOneChat(args.communityId, args.chatId, args.ensName) + self.events.on(SIGNAL_CONTACTS_STATUS_UPDATED) do(e: Args): + let args = ContactsStatusUpdatedArgs(e) + self.delegate.contactsStatusUpdated(args.statusUpdates) + self.events.on(SignalType.HistoryRequestStarted.event) do(e: Args): self.delegate.setLoadingHistoryMessagesInProgress(true) diff --git a/src/app/modules/main/chat_section/io_interface.nim b/src/app/modules/main/chat_section/io_interface.nim index a899df85b3..aca6fa749e 100644 --- a/src/app/modules/main/chat_section/io_interface.nim +++ b/src/app/modules/main/chat_section/io_interface.nim @@ -313,3 +313,6 @@ method downloadMessages*(self: AccessInterface, chatId: string, filePath: string method updateLastMessageTimestamp*(self: AccessInterface, chatId: string, lastMessageTimestamp: int) = raise newException(ValueError, "No implementation available") + +method contactsStatusUpdated*(self: AccessInterface, statusUpdates: seq[StatusUpdateDto]) = + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/item.nim b/src/app/modules/main/chat_section/item.nim index 369a1d673c..1b232d63fd 100644 --- a/src/app/modules/main/chat_section/item.nim +++ b/src/app/modules/main/chat_section/item.nim @@ -2,16 +2,20 @@ import strformat, json import base_item, sub_model, sub_item import ../../shared_models/color_hash_model +import ../../../../app_service/common/types +import ../../../../app_service/service/contacts/dto/contacts + type Item* = ref object of BaseItem subItems: SubModel proc initItem*(id, name, icon: string, color, emoji, description: string, `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 = + blocked, active: bool, position: int, categoryId: string, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false, + trustStatus: TrustStatus = TrustStatus.Unknown, onlineStatus = OnlineStatus.Inactive): Item = result = Item() result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, lastMessageTimestamp, hasUnreadMessages, - notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight) + notificationsCount, muted, blocked, active, position, categoryId, colorId, colorHash, highlight, trustStatus, onlineStatus) result.subItems = newSubModel() proc delete*(self: Item) = @@ -41,6 +45,7 @@ proc `$`*(self: Item): string = categoryId: {self.categoryId}, highlight: {self.highlight}, trustStatus: {self.trustStatus}, + onlineStatus: {self.onlineStatus}, subItems:[ {$self.subItems} ]""" @@ -65,6 +70,7 @@ proc toJsonNode*(self: Item): JsonNode = "categoryId": self.categoryId, "highlight": self.highlight, "trustStatus": self.trustStatus, + "onlineStatus": self.onlineStatus } proc appendSubItems*(self: Item, items: seq[SubItem]) = diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index bea2da563e..4edb987ce8 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -1,4 +1,5 @@ import NimQml, Tables, strutils, strformat, json +import ../../../../app_service/common/types from ../../../../app_service/service/chat/dto/chat import ChatType from ../../../../app_service/service/contacts/dto/contacts import TrustStatus import item, sub_item, base_item, sub_model @@ -27,6 +28,7 @@ type CategoryId Highlight TrustStatus + OnlineStatus QtObject: type @@ -92,6 +94,7 @@ QtObject: ModelRole.CategoryId.int:"categoryId", ModelRole.Highlight.int:"highlight", ModelRole.TrustStatus.int:"trustStatus", + ModelRole.OnlineStatus.int:"onlineStatus", }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -149,6 +152,8 @@ QtObject: result = newQVariant(item.highlight) of ModelRole.TrustStatus: result = newQVariant(item.trustStatus.int) + of ModelRole.OnlineStatus: + result = newQVariant(item.onlineStatus.int) proc appendItem*(self: Model, item: Item) = let parentModelIndex = newQModelIndex() @@ -304,6 +309,16 @@ QtObject: self.dataChanged(index, index, @[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int, ModelRole.Color.int]) return + + proc updateItemOnlineStatus*(self: Model, id: string, onlineStatus: OnlineStatus) = + ## This updates only first level items, it doesn't update subitems, since subitems cannot have onlineStatus. + for i in 0 ..< self.items.len: + if(self.items[i].id == id): + if(self.items[i].onlineStatus != onlineStatus): + self.items[i].BaseItem.onlineStatus = onlineStatus + let index = self.createIndex(i, 0, nil) + self.dataChanged(index, index, @[ModelRole.OnlineStatus.int]) + return proc updateNotificationsForItemOrSubItemById*(self: Model, id: string, hasUnreadMessages: bool, notificationsCount: int) = diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 24f1f74e62..171ce8327e 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -13,6 +13,7 @@ import ../../../global/app_sections_config as conf import ../../../global/global_singleton import ../../../core/eventemitter import ../../../core/notifications/details as notification_details +import ../../../../app_service/common/types import ../../../../app_service/service/settings/service as settings_service import ../../../../app_service/service/contacts/service as contact_service import ../../../../app_service/service/chat/service as chat_service @@ -135,6 +136,7 @@ proc buildChatSectionUI( var chatImage = "" var colorHash: ColorHashDto = @[] var colorId: int = 0 + var onlineStatus = OnlineStatus.Inactive let isUsersListAvailable = (chatDto.chatType != ChatType.OneToOne and chatDto.chatType != ChatType.Public) var blocked = false @@ -146,6 +148,8 @@ proc buildChatSectionUI( blocked = contactDetails.details.isBlocked() colorHash = self.controller.getColorHash(chatDto.id) colorId = self.controller.getColorId(chatDto.id) + onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(chatDto.id).statusType) + elif(chatDto.chatType == ChatType.PrivateGroupChat): chatImage = chatDto.icon @@ -158,7 +162,7 @@ proc buildChatSectionUI( let channelItem = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, chatDto.timestamp.int, hasNotification, notificationsCount, chatDto.muted, blocked, chatDto.active, chatDto.position, - chatDto.categoryId, colorId, colorHash) + chatDto.categoryId, colorId, colorHash, onlineStatus = onlineStatus) self.view.chatsModel().appendItem(channelItem) self.addSubmodule(chatDto.id, belongToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -410,12 +414,15 @@ method addNewChat*( var chatImage = chatDto.icon var colorHash: ColorHashDto = @[] var colorId: int = 0 + var onlineStatus = OnlineStatus.Inactive + var isUsersListAvailable = true if(chatDto.chatType == ChatType.OneToOne): isUsersListAvailable = false (chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id) colorHash = self.controller.getColorHash(chatDto.id) colorId = self.controller.getColorId(chatDto.id) + onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(chatDto.id).statusType) var amIChatAdmin = false if(belongsToCommunity): @@ -426,7 +433,8 @@ method addNewChat*( if chatDto.categoryId.len == 0: let item = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji, 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) + chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorId, colorHash, chatDto.highlight, + onlineStatus = onlineStatus) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) self.chatContentModules[chatDto.id].load() @@ -863,3 +871,8 @@ method downloadMessages*(self: Module, chatId: string, filePath: string) = return self.chatContentModules[chatId].downloadMessages(filePath) + +method contactsStatusUpdated*(self: Module, statusUpdates: seq[StatusUpdateDto]) = + for s in statusUpdates: + let status = toOnlineStatus(s.statusType) + self.view.chatsModel().updateItemOnlineStatus(s.publicKey, status) diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index cd34a1192a..4889bba0ab 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -14,6 +14,7 @@ import ../../shared_models/section_item import ../../shared_models/[member_item, member_model, section_model] import ../../../global/global_singleton import ../../../core/eventemitter +import ../../../../app_service/common/types import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/contacts/service as contacts_service import ../../../../app_service/service/chat/dto/chat diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index fd64fa5f51..20f6674676 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -53,7 +53,7 @@ import ../../../app_service/service/ens/service as ens_service import ../../../app_service/service/network/service as network_service import ../../../app_service/service/general/service as general_service import ../../../app_service/service/keycard/service as keycard_service -from ../../../app_service/common/types import StatusType +import ../../../app_service/common/types import ../../../app_service/common/social_links import ../../core/notifications/details diff --git a/src/app/modules/main/profile_section/contacts/module.nim b/src/app/modules/main/profile_section/contacts/module.nim index 80f4cab37f..dd98373a63 100644 --- a/src/app/modules/main/profile_section/contacts/module.nim +++ b/src/app/modules/main/profile_section/contacts/module.nim @@ -7,6 +7,7 @@ import ../io_interface as delegate_interface import ../../../../global/global_singleton import ../../../../core/eventemitter +import ../../../../../app_service/common/types import ../../../../../app_service/service/contacts/dto/contacts as contacts_dto import ../../../../../app_service/service/contacts/service as contacts_service import ../../../../../app_service/service/chat/service as chat_service diff --git a/src/app/modules/shared_models/active_section.nim b/src/app/modules/shared_models/active_section.nim index 129f129436..75b5f416e9 100644 --- a/src/app/modules/shared_models/active_section.nim +++ b/src/app/modules/shared_models/active_section.nim @@ -1,7 +1,9 @@ import NimQml -import section_item, user_item +import section_item import ../../../app_service/service/contacts/dto/contacts +import ../../../app_service/common/types + QtObject: type ActiveSection* = ref object of QObject item: SectionItem diff --git a/src/app/modules/shared_models/member_item.nim b/src/app/modules/shared_models/member_item.nim index d4f35ed82a..1643890198 100644 --- a/src/app/modules/shared_models/member_item.nim +++ b/src/app/modules/shared_models/member_item.nim @@ -1,6 +1,8 @@ import strformat import user_item +import ../../../app_service/common/types + export user_item type diff --git a/src/app/modules/shared_models/member_model.nim b/src/app/modules/shared_models/member_model.nim index 72981ee66f..c42fa229cc 100644 --- a/src/app/modules/shared_models/member_model.nim +++ b/src/app/modules/shared_models/member_model.nim @@ -2,6 +2,7 @@ import NimQml, Tables, strformat, sequtils, sugar # TODO: use generics to remove duplication between user_model and member_model +import ../../../app_service/common/types import ../../../app_service/service/contacts/dto/contacts import member_item diff --git a/src/app/modules/shared_models/section_item.nim b/src/app/modules/shared_models/section_item.nim index 3ec97c083b..6cd37e0dfb 100644 --- a/src/app/modules/shared_models/section_item.nim +++ b/src/app/modules/shared_models/section_item.nim @@ -2,6 +2,8 @@ import strformat import ./member_model, ./member_item import ../main/communities/models/[pending_request_item, pending_request_model] +import ../../../app_service/common/types + type SectionType* {.pure.} = enum Chat = 0 diff --git a/src/app/modules/shared_models/user_item.nim b/src/app/modules/shared_models/user_item.nim index 01d1f1df9d..4152517cbe 100644 --- a/src/app/modules/shared_models/user_item.nim +++ b/src/app/modules/shared_models/user_item.nim @@ -2,10 +2,6 @@ import strformat import ../../../app_service/common/types type - OnlineStatus* {.pure.} = enum - Inactive = 0 - Online - ContactRequest* {.pure.} = enum None = 0 IncomingPending @@ -113,12 +109,6 @@ proc initUserItem*( incomingVerificationStatus = incomingVerificationStatus, outgoingVerificationStatus = outgoingVerificationStatus) -proc toOnlineStatus*(statusType: StatusType): OnlineStatus = - if(statusType == StatusType.AlwaysOnline or statusType == StatusType.Automatic): - return OnlineStatus.Online - else: - return OnlineStatus.Inactive - proc `$`*(self: UserItem): string = result = fmt"""User Item( pubKey: {self.pubkey}, diff --git a/src/app/modules/shared_models/user_model.nim b/src/app/modules/shared_models/user_model.nim index 59ef993433..08f3fb639e 100644 --- a/src/app/modules/shared_models/user_model.nim +++ b/src/app/modules/shared_models/user_model.nim @@ -1,6 +1,8 @@ import NimQml, Tables, strformat, sequtils, sugar import user_item +import ../../../app_service/common/types + type ModelRole {.pure.} = enum PubKey = UserRole + 1 diff --git a/src/app_service/common/types.nim b/src/app_service/common/types.nim index 491fe80153..a5c49ad1ba 100644 --- a/src/app_service/common/types.nim +++ b/src/app_service/common/types.nim @@ -15,9 +15,20 @@ type Gap = 10 Edit = 11 -type StatusType* {.pure.} = enum - Unknown = 0 - Automatic - DoNotDisturb - AlwaysOnline - Inactive \ No newline at end of file +type + StatusType* {.pure.} = enum + Unknown = 0 + Automatic + DoNotDisturb + AlwaysOnline + Inactive + + OnlineStatus* {.pure.} = enum + Inactive = 0 + Online + +proc toOnlineStatus*(statusType: StatusType): OnlineStatus = + if(statusType == StatusType.AlwaysOnline or statusType == StatusType.Automatic): + return OnlineStatus.Online + else: + return OnlineStatus.Inactive