From ccc2dfc5479f9d5769fa0f02df8ec972213431c6 Mon Sep 17 00:00:00 2001 From: Alex Jbanca Date: Mon, 3 Jun 2024 11:49:35 +0300 Subject: [PATCH] refactor: Adding a users_model holding all contacts Adding a new users_model instance holding all contacts. The users_model is adapted to contain all the user details. This model is temporary until the full refactoring is done. --- .../profile_section/contacts/controller.nim | 14 ++ .../profile_section/contacts/io_interface.nim | 3 + .../main/profile_section/contacts/module.nim | 34 ++++ .../main/profile_section/contacts/view.nim | 16 ++ src/app/modules/shared_models/user_item.nim | 180 +++++++++++++++++- src/app/modules/shared_models/user_model.nim | 54 ++++++ 6 files changed, 296 insertions(+), 5 deletions(-) diff --git a/src/app/modules/main/profile_section/contacts/controller.nim b/src/app/modules/main/profile_section/contacts/controller.nim index e0aea92887..471f37a703 100644 --- a/src/app/modules/main/profile_section/contacts/controller.nim +++ b/src/app/modules/main/profile_section/contacts/controller.nim @@ -62,7 +62,19 @@ proc init*(self: Controller) = self.events.on(SIGNAL_REMOVED_TRUST_STATUS) do(e: Args): var args = TrustArgs(e) self.delegate.contactTrustStatusChanged(args.publicKey, args.isUntrustworthy) + + self.events.on(SIGNAL_CONTACT_VERIFIED) do (e: Args): + var args = ContactArgs(e) + self.delegate.updateContactVerificationStatus(args.contactId) + self.events.on(SIGNAL_CONTACT_VERIFICATION_SENT) do(e: Args): + var args = ContactArgs(e) + self.delegate.updateContactVerificationStatus(args.contactId) + + self.events.on(SIGNAL_CONTACT_VERIFICATION_ACCEPTED) do(e: Args): + var args = VerificationRequestArgs(e) + self.delegate.onVerificationRequestUpdatedOrAdded(args.verificationRequest) + self.events.on(SIGNAL_CONTACT_UPDATED) do(e: Args): var args = ContactArgs(e) self.delegate.contactUpdated(args.contactId) @@ -74,10 +86,12 @@ proc init*(self: Controller) = self.events.on(SIGNAL_CONTACT_VERIFICATION_DECLINED) do(e: Args): var args = ContactArgs(e) self.delegate.onVerificationRequestDeclined(args.contactId) + self.delegate.updateContactVerificationStatus(args.contactId) self.events.on(SIGNAL_CONTACT_VERIFICATION_CANCELLED) do(e: Args): var args = ContactArgs(e) self.delegate.onVerificationRequestCanceled(args.contactId) + self.delegate.updateContactVerificationStatus(args.contactId) self.events.on(SIGNAL_CONTACT_VERIFICATION_ADDED) do(e: Args): var args = VerificationRequestArgs(e) diff --git a/src/app/modules/main/profile_section/contacts/io_interface.nim b/src/app/modules/main/profile_section/contacts/io_interface.nim index a835e04d9b..1cc9159f2a 100644 --- a/src/app/modules/main/profile_section/contacts/io_interface.nim +++ b/src/app/modules/main/profile_section/contacts/io_interface.nim @@ -79,6 +79,9 @@ method contactTrustStatusChanged*(self: AccessInterface, publicKey: string, isUn method contactUpdated*(self: AccessInterface, publicKey: string) {.base.} = raise newException(ValueError, "No implementation available") +method updateContactVerificationStatus*(self: AccessInterface, publicKey: string) {.base.} = + raise newException(ValueError, "No implementation available") + method contactsStatusUpdated*(self: AccessInterface, statusUpdates: seq[StatusUpdateDto]) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/contacts/module.nim b/src/app/modules/main/profile_section/contacts/module.nim index e1239f82f2..da6819a095 100644 --- a/src/app/modules/main/profile_section/contacts/module.nim +++ b/src/app/modules/main/profile_section/contacts/module.nim @@ -71,6 +71,7 @@ method delete*(self: Module) = proc createItemFromPublicKey(self: Module, publicKey: string): UserItem = let contactDetails = self.controller.getContactDetails(publicKey) + let requestStatus = self.controller.getVerificationRequestFrom(publicKey).status return initUserItem( pubKey = contactDetails.dto.id, @@ -87,6 +88,22 @@ proc createItemFromPublicKey(self: Module, publicKey: string): UserItem = isVerified = contactDetails.dto.isContactVerified(), isUntrustworthy = contactDetails.dto.isContactUntrustworthy(), isBlocked = contactDetails.dto.isBlocked(), + isCurrentUser = contactDetails.isCurrentUser, + contactRequest = toContactStatus(contactDetails.dto.contactRequestState), + incomingVerificationStatus = toVerificationRequestStatus(requestStatus), + outgoingVerificationStatus = toVerificationRequestStatus(contactDetails.dto.verificationStatus), + defaultDisplayName = contactDetails.defaultDisplayName, + optionalName = contactDetails.optionalName, + lastUpdated = contactDetails.dto.lastUpdated, + lastUpdatedLocally = contactDetails.dto.lastUpdatedLocally, + bio = contactDetails.dto.bio, + thumbnailImage = contactDetails.dto.image.thumbnail, + largeImage = contactDetails.dto.image.large, + isContactRequestReceived = contactDetails.dto.isContactRequestReceived, + isContactRequestSent = contactDetails.dto.isContactRequestSent, + isSyncing = contactDetails.dto.isSyncing, + isRemoved = contactDetails.dto.removed, + trustStatus = contactDetails.dto.trustStatus, ) proc buildModel(self: Module, model: Model, group: ContactsGroup) = @@ -106,6 +123,7 @@ method isLoaded*(self: Module): bool = return self.moduleLoaded method viewDidLoad*(self: Module) = + self.buildModel(self.view.contactsModel(), ContactsGroup.AllKnownContacts) self.buildModel(self.view.myMutualContactsModel(), ContactsGroup.MyMutualContacts) self.buildModel(self.view.blockedContactsModel(), ContactsGroup.BlockedContacts) self.buildModel(self.view.receivedContactRequestsModel(), ContactsGroup.IncomingPendingContactRequests) @@ -122,6 +140,8 @@ method viewDidLoad*(self: Module) = let contactItem = self.createItemFromPublicKey(receivedVerificationRequest.fromID) contactItem.incomingVerificationStatus = toVerificationRequestStatus(receivedVerificationRequest.status) receivedVerificationRequestItems.add(contactItem) + self.view.contactsModel().updateIncomingRequestStatus(contactItem.pubKey, contactItem.incomingVerificationStatus) + self.view.receivedContactRequestsModel().addItems(receivedVerificationRequestItems) self.moduleLoaded = true @@ -170,6 +190,7 @@ proc addItemToAppropriateModel(self: Module, item: UserItem) = return let contact = self.controller.getContact(item.pubKey()) + self.view.contactsModel().addItem(item) if contact.isBlocked(): self.view.blockedContactsModel().addItem(item) return @@ -185,6 +206,7 @@ proc addItemToAppropriateModel(self: Module, item: UserItem) = return proc removeItemWithPubKeyFromAllModels(self: Module, publicKey: string) = + self.view.contactsModel().removeItemById(publicKey) self.view.myMutualContactsModel().removeItemById(publicKey) self.view.receivedContactRequestsModel().removeItemById(publicKey) self.view.sentContactRequestsModel().removeItemById(publicKey) @@ -217,6 +239,7 @@ method contactsStatusUpdated*(self: Module, statusUpdates: seq[StatusUpdateDto]) for s in statusUpdates: let status = toOnlineStatus(s.statusType) self.view.myMutualContactsModel().setOnlineStatus(s.publicKey, status) + self.view.contactsModel().setOnlineStatus(s.publicKey, status) method contactNicknameChanged*(self: Module, publicKey: string) = let contactDetails = self.controller.getContactDetails(publicKey) @@ -224,6 +247,7 @@ method contactNicknameChanged*(self: Module, publicKey: string) = let ensName = contactDetails.dto.name let localNickname = contactDetails.dto.localNickname + self.view.contactsModel().setName(publicKey, displayName, ensName, localNickname) self.view.myMutualContactsModel().setName(publicKey, displayName, ensName, localNickname) self.view.receivedContactRequestsModel().setName(publicKey, displayName, ensName, localNickname) self.view.sentContactRequestsModel().setName(publicKey, displayName, ensName, localNickname) @@ -235,6 +259,7 @@ method contactNicknameChanged*(self: Module, publicKey: string) = method contactTrustStatusChanged*(self: Module, publicKey: string, isUntrustworthy: bool) = self.view.myMutualContactsModel().updateTrustStatus(publicKey, isUntrustworthy) self.view.blockedContactsModel().updateTrustStatus(publicKey, isUntrustworthy) + self.updateContactVerificationStatus(publicKey) method markAsTrusted*(self: Module, publicKey: string): void = self.controller.markAsTrusted(publicKey) @@ -248,6 +273,11 @@ method removeTrustStatus*(self: Module, publicKey: string): void = method removeTrustVerificationStatus*(self: Module, publicKey: string): void = self.controller.removeTrustVerificationStatus(publicKey) +method updateContactVerificationStatus*(self: Module, publicKey: string) = + let item = self.createItemFromPublicKey(publicKey) + self.view.contactsModel().removeItemById(publicKey) + self.view.contactsModel().addItem(item) + method getSentVerificationDetailsAsJson*(self: Module, publicKey: string): string = let verificationRequest = self.controller.getVerificationRequestSentTo(publicKey) let (name, image, largeImage) = self.controller.getContactNameAndImage(publicKey) @@ -309,6 +339,8 @@ method onVerificationRequestCanceled*(self: Module, publicKey: string) = method onVerificationRequestUpdatedOrAdded*(self: Module, request: VerificationRequest) = let item = self.createItemFromPublicKey(request.fromID) item.incomingVerificationStatus = toVerificationRequestStatus(request.status) + self.view.contactsModel().updateIncomingRequestStatus(item.pubKey, item.incomingVerificationStatus) + if (self.view.receivedContactRequestsModel.containsItemWithPubKey(request.fromID)): if request.status != VerificationStatus.Verifying and request.status != VerificationStatus.Verified: @@ -325,6 +357,8 @@ method requestContactInfo*(self: Module, publicKey: string) = self.controller.requestContactInfo(publicKey) method onContactInfoRequestFinished*(self: Module, publicKey: string, ok: bool) = + if ok: + self.removeIfExistsAndAddToAppropriateModel(publicKey) self.view.onContactInfoRequestFinished(publicKey, ok) method shareUserUrlWithData*(self: Module, pubkey: string): string = diff --git a/src/app/modules/main/profile_section/contacts/view.nim b/src/app/modules/main/profile_section/contacts/view.nim index 9fb7bcb38d..8c0eb36321 100644 --- a/src/app/modules/main/profile_section/contacts/view.nim +++ b/src/app/modules/main/profile_section/contacts/view.nim @@ -11,6 +11,8 @@ QtObject: type View* = ref object of QObject delegate: io_interface.AccessInterface + contactsModel: Model + contactsModelVariant: QVariant myMutualContactsModel: Model myMutualContactsModelVariant: QVariant blockedContactsModel: Model @@ -37,6 +39,8 @@ QtObject: proc delete*(self: View) = + self.contactsModel.delete + self.contactsModelVariant.delete self.myMutualContactsModel.delete self.myMutualContactsModelVariant.delete self.blockedContactsModel.delete @@ -66,6 +70,8 @@ QtObject: new(result, delete) result.QObject.setup result.delegate = delegate + result.contactsModel = newModel() + result.contactsModelVariant = newQVariant(result.contactsModel) result.myMutualContactsModel = newModel() result.myMutualContactsModelVariant = newQVariant(result.myMutualContactsModel) result.blockedContactsModel = newModel() @@ -92,6 +98,9 @@ QtObject: proc load*(self: View) = self.delegate.viewDidLoad() + + proc contactsModel*(self: View): Model = + return self.contactsModel proc myMutualContactsModel*(self: View): Model = return self.myMutualContactsModel @@ -112,6 +121,13 @@ QtObject: # proc sentButRejectedContactRequestsModel*(self: View): Model = # return self.sentButRejectedContactRequestsModel + proc contactsModelChanged(self: View) {.signal.} + proc getContactsModel(self: View): QVariant {.slot.} = + return self.contactsModelVariant + QtProperty[QVariant] contactsModel: + read = getContactsModel + notify = contactsModelChanged + proc myMutualContactsModelChanged(self: View) {.signal.} proc getMyMutualContactsModel(self: View): QVariant {.slot.} = return self.myMutualContactsModelVariant diff --git a/src/app/modules/shared_models/user_item.nim b/src/app/modules/shared_models/user_item.nim index 115a48320b..45ba0ef329 100644 --- a/src/app/modules/shared_models/user_item.nim +++ b/src/app/modules/shared_models/user_item.nim @@ -5,10 +5,10 @@ import ../../../app_service/service/contacts/dto/contacts type ContactRequest* {.pure.} = enum None = 0 - IncomingPending - IncomingRejected - OutgoingPending - OutgoingRejected + Mutual = 1 + Sent = 2 + Received = 3 + Dismissed = 4 VerificationRequestStatus* {.pure.} = enum None = 0 @@ -30,6 +30,16 @@ proc toVerificationRequestStatus*(value: VerificationStatus): VerificationReques of VerificationStatus.Untrustworthy: return VerificationRequestStatus.Untrustworthy else: return VerificationRequestStatus.None +#TODO: #14964 - To check if this is needed +proc toContactStatus*(value: ContactRequestState): ContactRequest = + case value: + of ContactRequestState.None: return ContactRequest.None + of ContactRequestState.Mutual: return ContactRequest.Mutual + of ContactRequestState.Sent: return ContactRequest.Sent + of ContactRequestState.Received: return ContactRequest.Received + of ContactRequestState.Dismissed: return ContactRequest.Dismissed + else: return ContactRequest.None + type UserItem* = ref object of RootObj pubKey: string @@ -49,6 +59,20 @@ type contactRequest: ContactRequest incomingVerificationStatus: VerificationRequestStatus outgoingVerificationStatus: VerificationRequestStatus + #Contact extra details + isCurrentUser: bool + defaultDisplayName: string + optionalName: string + lastUpdated: int64 + lastUpdatedLocally: int64 + bio: string + thumbnailImage: string + largeImage: string + isContactRequestReceived: bool + isContactRequestSent: bool + isSyncing: bool + isRemoved: bool + trustStatus: TrustStatus proc setup*(self: UserItem, pubKey: string, @@ -68,6 +92,20 @@ proc setup*(self: UserItem, contactRequest: ContactRequest, incomingVerificationStatus: VerificationRequestStatus, outgoingVerificationStatus: VerificationRequestStatus, + #TODO: #14964 - remove defaults + isCurrentUser: bool = false, + defaultDisplayName: string = "", + optionalName: string = "", + lastUpdated: int64 = 0, + lastUpdatedLocally: int64 = 0, + bio: string = "", + thumbnailImage: string = "", + largeImage: string = "", + isContactRequestReceived: bool = false, + isContactRequestSent: bool = false, + isSyncing: bool = false, + isRemoved: bool = false, + trustStatus: TrustStatus = TrustStatus.Unknown, ) = self.pubKey = pubKey self.displayName = displayName @@ -86,8 +124,22 @@ proc setup*(self: UserItem, self.contactRequest = contactRequest self.incomingVerificationStatus = incomingVerificationStatus self.outgoingVerificationStatus = outgoingVerificationStatus + self.isCurrentUser = isCurrentUser + self.defaultDisplayName = defaultDisplayName + self.optionalName = optionalName + self.lastUpdated = lastUpdated + self.lastUpdatedLocally = lastUpdatedLocally + self.bio = bio + self.thumbnailImage = thumbnailImage + self.largeImage = largeImage + self.isContactRequestReceived = isContactRequestReceived + self.isContactRequestSent = isContactRequestSent + self.isSyncing = isSyncing + self.isRemoved = isRemoved + self.trustStatus = trustStatus # FIXME: remove defaults +# TODO: #14964 proc initUserItem*( pubKey: string, displayName: string, @@ -106,6 +158,19 @@ proc initUserItem*( contactRequest: ContactRequest = ContactRequest.None, incomingVerificationStatus: VerificationRequestStatus = VerificationRequestStatus.None, outgoingVerificationStatus: VerificationRequestStatus = VerificationRequestStatus.None, + isCurrentUser: bool = false, + defaultDisplayName: string = "", + optionalName: string = "", + lastUpdated: int64 = 0, + lastUpdatedLocally: int64 = 0, + bio: string = "", + thumbnailImage: string = "", + largeImage: string = "", + isContactRequestReceived: bool = false, + isContactRequestSent: bool = false, + isSyncing: bool = false, + isRemoved: bool = false, + trustStatus: TrustStatus = TrustStatus.Unknown, ): UserItem = result = UserItem() result.setup( @@ -125,7 +190,21 @@ proc initUserItem*( isBlocked = isBlocked, contactRequest = contactRequest, incomingVerificationStatus = incomingVerificationStatus, - outgoingVerificationStatus = outgoingVerificationStatus) + isCurrentUser = isCurrentUser, + outgoingVerificationStatus = outgoingVerificationStatus, + defaultDisplayName = defaultDisplayName, + optionalName = optionalName, + lastUpdated = lastUpdated, + lastUpdatedLocally = lastUpdatedLocally, + bio = bio, + thumbnailImage = thumbnailImage, + largeImage = largeImage, + isContactRequestReceived = isContactRequestReceived, + isContactRequestSent = isContactRequestSent, + isSyncing = isSyncing, + isRemoved = isRemoved, + trustStatus = trustStatus, + ) proc `$`*(self: UserItem): string = result = fmt"""User Item( @@ -146,6 +225,19 @@ proc `$`*(self: UserItem): string = contactRequest: {$self.contactRequest.int}, incomingVerificationStatus: {$self.incomingVerificationStatus.int}, outgoingVerificationStatus: {$self.outgoingVerificationStatus.int}, + isCurrentUser: {self.isCurrentUser}, + defaultDisplayName: {self.defaultDisplayName}, + optionalName: {self.optionalName}, + lastUpdated: {self.lastUpdated}, + lastUpdatedLocally: {self.lastUpdatedLocally}, + bio: {self.bio}, + thumbnailImage: {self.thumbnailImage}, + largeImage: {self.largeImage}, + isContactRequestReceived: {self.isContactRequestReceived}, + isContactRequestSent: {self.isContactRequestSent}, + isSyncing: {self.isSyncing}, + isRemoved: {self.isRemoved}, + trustStatus: {$self.trustStatus.int}, ]""" proc pubKey*(self: UserItem): string {.inline.} = @@ -246,3 +338,81 @@ proc outgoingVerificationStatus*(self: UserItem): VerificationRequestStatus {.in proc `outgoingVerificationStatus=`*(self: UserItem, value: VerificationRequestStatus) {.inline.} = self.outgoingVerificationStatus = value + +proc isCurrentUser*(self: UserItem): bool {.inline.} = + self.isCurrentUser + +proc `isCurrentUser=`*(self: UserItem, value: bool) {.inline.} = + self.isCurrentUser = value + +proc defaultDisplayName*(self: UserItem): string {.inline.} = + self.defaultDisplayName + +proc `defaultDisplayName=`*(self: UserItem, value: string) {.inline.} = + self.defaultDisplayName = value + +proc optionalName*(self: UserItem): string {.inline.} = + self.optionalName + +proc `optionalName=`*(self: UserItem, value: string) {.inline.} = + self.optionalName = value + +proc lastUpdated*(self: UserItem): int64 {.inline.} = + self.lastUpdated + +proc `lastUpdated=`*(self: UserItem, value: int64) {.inline.} = + self.lastUpdated = value + +proc lastUpdatedLocally*(self: UserItem): int64 {.inline.} = + self.lastUpdatedLocally + +proc `lastUpdatedLocally=`*(self: UserItem, value: int64) {.inline.} = + self.lastUpdatedLocally = value + +proc bio*(self: UserItem): string {.inline.} = + self.bio + +proc `bio=`*(self: UserItem, value: string) {.inline.} = + self.bio = value + +proc thumbnailImage*(self: UserItem): string {.inline.} = + self.thumbnailImage + +proc `thumbnailImage=`*(self: UserItem, value: string) {.inline.} = + self.thumbnailImage = value + +proc largeImage*(self: UserItem): string {.inline.} = + self.largeImage + +proc `largeImage=`*(self: UserItem, value: string) {.inline.} = + self.largeImage = value + +proc isContactRequestReceived*(self: UserItem): bool {.inline.} = + self.isContactRequestReceived + +proc `isContactRequestReceived=`*(self: UserItem, value: bool) {.inline.} = + self.isContactRequestReceived = value + +proc isContactRequestSent*(self: UserItem): bool {.inline.} = + self.isContactRequestSent + +proc `isContactRequestSent=`*(self: UserItem, value: bool) {.inline.} = + self.isContactRequestSent = value + +proc isSyncing*(self: UserItem): bool {.inline.} = + self.isSyncing + +proc `isSyncing=`*(self: UserItem, value: bool) {.inline.} = + self.isSyncing = value + +proc isRemoved*(self: UserItem): bool {.inline.} = + self.isRemoved + +proc `isRemoved=`*(self: UserItem, value: bool) {.inline.} = + self.isRemoved = value + +proc trustStatus*(self: UserItem): TrustStatus {.inline.} = + self.trustStatus + +proc `trustStatus=`*(self: UserItem, value: TrustStatus) {.inline.} = + self.trustStatus = value diff --git a/src/app/modules/shared_models/user_model.nim b/src/app/modules/shared_models/user_model.nim index 3d16f61397..abe1e3ac0f 100644 --- a/src/app/modules/shared_models/user_model.nim +++ b/src/app/modules/shared_models/user_model.nim @@ -22,6 +22,19 @@ type ContactRequest IncomingVerificationStatus OutgoingVerificationStatus + IsCurrentUser + DefaultDisplayName + OptionalName + LastUpdated + LastUpdatedLocally + Bio + ThumbnailImage + LargeImage + IsContactRequestReceived + IsContactRequestSent + IsSyncing + IsRemoved + TrustStatus QtObject: type @@ -85,6 +98,19 @@ QtObject: ModelRole.ContactRequest.int: "contactRequest", ModelRole.IncomingVerificationStatus.int: "incomingVerificationStatus", ModelRole.OutgoingVerificationStatus.int: "outgoingVerificationStatus", + ModelRole.IsCurrentUser.int: "isCurrentUser", + ModelRole.DefaultDisplayName.int: "defaultDisplayName", + ModelRole.OptionalName.int: "optionalName", + ModelRole.LastUpdated.int: "lastUpdated", + ModelRole.LastUpdatedLocally.int: "lastUpdatedLocally", + ModelRole.Bio.int: "bio", + ModelRole.ThumbnailImage.int: "thumbnailImage", + ModelRole.LargeImage.int: "largeImage", + ModelRole.IsContactRequestReceived.int: "isContactRequestReceived", + ModelRole.IsContactRequestSent.int: "isContactRequestSent", + ModelRole.IsSyncing.int: "isSyncing", + ModelRole.IsRemoved.int: "isRemoved", + ModelRole.TrustStatus.int: "trustStatus", }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -132,6 +158,34 @@ QtObject: result = newQVariant(item.incomingVerificationStatus.int) of ModelRole.OutgoingVerificationStatus: result = newQVariant(item.outgoingVerificationStatus.int) + of ModelRole.IsCurrentUser: + result = newQVariant(item.isCurrentUser) + of ModelRole.DefaultDisplayName: + result = newQVariant(item.defaultDisplayName) + of ModelRole.OptionalName: + result = newQVariant(item.optionalName) + of ModelRole.LastUpdated: + result = newQVariant(item.lastUpdated) + of ModelRole.LastUpdatedLocally: + result = newQVariant(item.lastUpdatedLocally) + of ModelRole.Bio: + result = newQVariant(item.bio) + of ModelRole.ThumbnailImage: + result = newQVariant(item.thumbnailImage) + of ModelRole.LargeImage: + result = newQVariant(item.largeImage) + of ModelRole.IsContactRequestReceived: + result = newQVariant(item.isContactRequestReceived) + of ModelRole.IsContactRequestSent: + result = newQVariant(item.isContactRequestSent) + of ModelRole.IsSyncing: + result = newQVariant(item.isSyncing) + of ModelRole.IsRemoved: + result = newQVariant(item.isRemoved) + of ModelRole.TrustStatus: + result = newQVariant(item.trustStatus.int) + else: + result = newQVariant() proc addItems*(self: Model, items: seq[UserItem]) = if(items.len == 0):