From aeed9303cdd50fc4bec422b4cf9039f186ca35d6 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Wed, 2 Feb 2022 18:54:28 +0100 Subject: [PATCH] fix(@desktop/communities): community import has some issues Fixes #4206 --- .../modules/main/communities/controller.nim | 9 +- src/app/modules/main/communities/module.nim | 16 +++- .../module_access_interface.nim | 3 - .../module_controller_delegate_interface.nim | 9 ++ src/app/modules/main/communities/view.nim | 4 + src/app/modules/main/controller.nim | 16 ++++ src/app_service/service/community/service.nim | 45 +++++++++- src/app_service/service/message/service.nim | 16 ++-- .../AccessExistingCommunityPopup.qml | 42 +++------ ui/app/AppLayouts/Chat/stores/RootStore.qml | 4 + .../Chat/views/ContactsColumnView.qml | 89 +++++++++---------- 11 files changed, 159 insertions(+), 94 deletions(-) diff --git a/src/app/modules/main/communities/controller.nim b/src/app/modules/main/communities/controller.nim index 69c46723e2..8248d7086f 100644 --- a/src/app/modules/main/communities/controller.nim +++ b/src/app/modules/main/communities/controller.nim @@ -34,7 +34,14 @@ method delete*(self: Controller) = method init*(self: Controller) = self.events.on(SIGNAL_COMMUNITY_CREATED) do(e:Args): let args = CommunityArgs(e) - self.delegate.addCommunity(args.community) + self.delegate.communityAdded(args.community) + + self.events.on(SIGNAL_COMMUNITY_IMPORTED) do(e:Args): + let args = CommunityArgs(e) + if(args.error.len > 0): + self.delegate.onImportCommunityErrorOccured(args.error) + else: + self.delegate.communityImported(args.community) self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e:Args): let args = CommunitiesArgs(e) diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index a85097aa78..319f94ed17 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -12,6 +12,12 @@ import ../../../../app_service/service/contacts/service as contacts_service export io_interface +type + ImportCommunityState {.pure.} = enum + Imported = 0 + ImportingInProgress + ImportingError + type Module* = ref object of io_interface.AccessInterface delegate: delegate_interface.AccessInterface @@ -91,7 +97,7 @@ method setAllCommunities*(self: Module, communities: seq[CommunityDto]) = for community in communities: self.view.addItem(self.getCommunityItem(community)) -method addCommunity*(self: Module, community: CommunityDto) = +method communityAdded*(self: Module, community: CommunityDto) = self.view.addItem(self.getCommunityItem(community)) method joinCommunity*(self: Module, communityId: string): string = @@ -160,5 +166,13 @@ method requestCommunityInfo*(self: Module, communityId: string) = method deleteCommunityChat*(self: Module, communityId: string, channelId: string) = self.controller.deleteCommunityChat(communityId, channelId) +method communityImported*(self: Module, community: CommunityDto) = + self.view.addItem(self.getCommunityItem(community)) + self.view.emitImportingCommunityStateChangedSignal(ImportCommunityState.Imported.int, "") + method importCommunity*(self: Module, communityKey: string) = + self.view.emitImportingCommunityStateChangedSignal(ImportCommunityState.ImportingInProgress.int, "") self.controller.importCommunity(communityKey) + +method onImportCommunityErrorOccured*(self: Module, error: string) = + self.view.emitImportingCommunityStateChangedSignal(ImportCommunityState.ImportingError.int, error) \ No newline at end of file diff --git a/src/app/modules/main/communities/private_interfaces/module_access_interface.nim b/src/app/modules/main/communities/private_interfaces/module_access_interface.nim index 2ab4c5af88..6d97f16133 100644 --- a/src/app/modules/main/communities/private_interfaces/module_access_interface.nim +++ b/src/app/modules/main/communities/private_interfaces/module_access_interface.nim @@ -16,9 +16,6 @@ method setAllCommunities*(self: AccessInterface, communities: seq[CommunityDto]) method getCommunityItem*(self: AccessInterface, community: CommunityDto): SectionItem {.base.} = raise newException(ValueError, "No implementation available") -method addCommunity*(self: AccessInterface, community: CommunityDto) {.base.} = - raise newException(ValueError, "No implementation available") - method joinCommunity*(self: AccessInterface, communityId: string): string {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/communities/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/main/communities/private_interfaces/module_controller_delegate_interface.nim index 46a441949d..d139ed711d 100644 --- a/src/app/modules/main/communities/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/main/communities/private_interfaces/module_controller_delegate_interface.nim @@ -21,4 +21,13 @@ method communityCategoryDeleted*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} = + raise newException(ValueError, "No implementation available") + +method communityAdded*(self: AccessInterface, community: CommunityDto) {.base.} = + raise newException(ValueError, "No implementation available") + +method communityImported*(self: AccessInterface, community: CommunityDto) {.base.} = + raise newException(ValueError, "No implementation available") + +method onImportCommunityErrorOccured*(self: AccessInterface, error: string) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/main/communities/view.nim b/src/app/modules/main/communities/view.nim index 6220a0a98f..f362812091 100644 --- a/src/app/modules/main/communities/view.nim +++ b/src/app/modules/main/communities/view.nim @@ -96,3 +96,7 @@ QtObject: proc importCommunity*(self: View, communityKey: string) {.slot.} = self.delegate.importCommunity(communityKey) + + proc importingCommunityStateChanged*(self:View, state: int, errorMsg: string) {.signal.} + proc emitImportingCommunityStateChangedSignal*(self: View, state: int, errorMsg: string) = + self.importingCommunityStateChanged(state, errorMsg) \ No newline at end of file diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim index fb0eef4e94..7508ac5cc6 100644 --- a/src/app/modules/main/controller.nim +++ b/src/app/modules/main/controller.nim @@ -120,6 +120,22 @@ method init*(self: Controller) = self.mailserversService ) + self.events.on(SIGNAL_COMMUNITY_IMPORTED) do(e:Args): + let args = CommunityArgs(e) + if(args.error.len > 0): + return + self.delegate.communityJoined( + args.community, + self.events, + self.settingsService, + self.contactsService, + self.chatService, + self.communityService, + self.messageService, + self.gifService, + self.mailserversService + ) + self.events.on(SIGNAL_COMMUNITY_LEFT) do(e:Args): let args = CommunityIdArgs(e) self.delegate.communityLeft(args.communityId) diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index 39138d55b8..aaf63c0aa8 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -14,9 +14,12 @@ export community_dto logScope: topics = "community-service" +include ../../common/json_utils + type CommunityArgs* = ref object of Args community*: CommunityDto + error*: string CommunitiesArgs* = ref object of Args communities*: seq[CommunityDto] @@ -54,6 +57,7 @@ const SIGNAL_COMMUNITY_JOINED* = "communityJoined" const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded" const SIGNAL_COMMUNITY_LEFT* = "communityLeft" const SIGNAL_COMMUNITY_CREATED* = "communityCreated" +const SIGNAL_COMMUNITY_IMPORTED* = "communityImported" const SIGNAL_COMMUNITY_EDITED* = "communityEdited" const SIGNAL_COMMUNITIES_UPDATE* = "communityUpdated" const SIGNAL_COMMUNITY_CHANNEL_CREATED* = "communityChannelCreated" @@ -635,11 +639,48 @@ QtObject: proc importCommunity*(self: Service, communityKey: string) = try: let response = status_go.importCommunity(communityKey) + ## after `importCommunity` call everything should be handled in a slot cnnected to `SignalType.CommunityFound.event` + ## but because of insufficient data (chats details are missing) sent as a payload of that signal we're unable to do + ## that until `status-go` part gets improved in ragards of that. + if (response.error != nil): let error = Json.decode($response.error, RpcError) - raise newException(RpcException, fmt"Error importing the community: {error.message}") + raise newException(RpcException, fmt"community id `{communityKey}` err: {error.message}") + + if response.result == nil or response.result.kind != JObject: + raise newException(RpcException, fmt"response is empty or not an json object, community id `{communityKey}`") + + var communityJArr: JsonNode + if(not response.result.getProp("communities", communityJArr)): + raise newException(RpcException, fmt"there is no `communities` key in the response for community id: {communityKey}") + + if(communityJArr.len == 0): + raise newException(RpcException, fmt"`communities` array is empty in the response for community id: {communityKey}") + + var chatsJArr: JsonNode + if(not response.result.getProp("chats", chatsJArr)): + raise newException(RpcException, fmt"there is no `chats` key in the response for community id: {communityKey}") + + let communityDto = communityJArr[0].toCommunityDto() + self.joinedCommunities[communityDto.id] = communityDto + + for chatObj in chatsJArr: + let chatDto = chatObj.toChatDto() + self.chatService.updateOrAddChat(chatDto) # we have to update chats stored in the chat service. + + for chat in communityDto.chats: + let fullChatId = communityDto.id & chat.id + var chatDetails = self.chatService.getChatById(fullChatId) + chatDetails.updateMissingFields(chat) + self.chatService.updateOrAddChat(chatDetails) # we have to update chats stored in the chat service. + + self.events.emit(SIGNAL_COMMUNITY_IMPORTED, CommunityArgs(community: communityDto)) + except Exception as e: - error "Error requesting community info", msg = e.msg + error "Error importing the community: ", msg = e.msg + # We should apply some notification mechanism on the application level which will deal with errors and + # notify user about them. Till then we're using this way. + self.events.emit(SIGNAL_COMMUNITY_IMPORTED, CommunityArgs(error: e.msg)) proc exportCommunity*(self: Service, communityId: string): string = try: diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim index 9df006f237..4a967a4af7 100644 --- a/src/app_service/service/message/service.nim +++ b/src/app_service/service/message/service.nim @@ -160,14 +160,19 @@ QtObject: ) self.events.emit(SIGNAL_NEW_MESSAGE_RECEIVED, data) + proc getNumOfPinnedMessages*(self: Service, chatId: string): int = + if(self.numOfPinnedMessagesPerChat.hasKey(chatId)): + return self.numOfPinnedMessagesPerChat[chatId] + return 0 + proc handlePinnedMessagesUpdate(self: Service, pinnedMessages: seq[PinnedMessageUpdateDto]) = for pm in pinnedMessages: let data = MessagePinUnpinArgs(chatId: pm.chatId, messageId: pm.messageId, actionInitiatedBy: pm.pinnedBy) if(pm.pinned): - self.numOfPinnedMessagesPerChat[pm.chatId] = self.numOfPinnedMessagesPerChat[pm.chatId] + 1 + self.numOfPinnedMessagesPerChat[pm.chatId] = self.getNumOfPinnedMessages(pm.chatId) + 1 self.events.emit(SIGNAL_MESSAGE_PINNED, data) else: - self.numOfPinnedMessagesPerChat[pm.chatId] = self.numOfPinnedMessagesPerChat[pm.chatId] - 1 + self.numOfPinnedMessagesPerChat[pm.chatId] = self.getNumOfPinnedMessages(pm.chatId) - 1 self.events.emit(SIGNAL_MESSAGE_UNPINNED, data) proc handleDeletedMessagesUpdate(self: Service, deletedMessages: seq[RemovedMessageDto]) = @@ -370,11 +375,11 @@ QtObject: var pinned = false if(pinMessageObj.getProp("pinned", pinned)): if(pinned and pin): - self.numOfPinnedMessagesPerChat[chatId] = self.numOfPinnedMessagesPerChat[chatId] + 1 + self.numOfPinnedMessagesPerChat[chatId] = self.getNumOfPinnedMessages(chatId) + 1 self.events.emit(SIGNAL_MESSAGE_PINNED, data) else: if(not pinned and not pin): - self.numOfPinnedMessagesPerChat[chatId] = self.numOfPinnedMessagesPerChat[chatId] - 1 + self.numOfPinnedMessagesPerChat[chatId] = self.getNumOfPinnedMessages(chatId) - 1 self.events.emit(SIGNAL_MESSAGE_UNPINNED, data) except Exception as e: @@ -538,9 +543,6 @@ QtObject: self.threadpool.start(arg) - proc getNumOfPinnedMessages*(self: Service, chatId: string): int = - return self.numOfPinnedMessagesPerChat[chatId] - proc onAsyncGetLinkPreviewData*(self: Service, response: string) {.slot.} = self.events.emit(SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED, LinkPreviewDataArgs(response: response)) diff --git a/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml b/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml index ea26e5ef38..de8368d620 100644 --- a/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml @@ -17,19 +17,9 @@ StatusModal { height: 400 property var store - property string error: "" - property string keyValidationError: "" - property string communityKey: "" - function validate() { - keyValidationError = ""; - - if (keyInput.text.trim() === "") { - //% "You need to enter a key" - keyValidationError = qsTrId("you-need-to-enter-a-key"); - } - - return !keyValidationError; + function validate(communityKey) { + return communityKey.trim() !== "" } //% "Access existing community" @@ -55,6 +45,10 @@ StatusModal { customHeight: 110 anchors.left: parent.left anchors.right: parent.right + + onTextChanged: { + importButton.enabled = root.validate(keyInput.text) + } } StatusBaseText { @@ -72,35 +66,19 @@ StatusModal { rightButtons: [ StatusQControls.StatusButton { + id: importButton + enabled: false //% "Import" text: qsTrId("import") onClicked: { - if (!validate()) { - return; - } - - communityKey = keyInput.text.trim(); + let communityKey = keyInput.text.trim(); if (!communityKey.startsWith("0x")) { communityKey = "0x" + communityKey; } - - root.error = root.store.chatsModelInst.communities.importCommunity(communityKey, Utils.uuid()) - if (!!root.error) { - creatingError.text = error; - return creatingError.open(); - } - + root.store.importCommunity(communityKey); root.close(); } - - MessageDialog { - id: creatingError - //% "Error importing the community" - title: qsTrId("error-importing-the-community") - icon: StandardIcon.Critical - standardButtons: StandardButton.Ok - } } ] } diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index 76ed391079..ba4b657361 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -146,6 +146,10 @@ QtObject { communitiesModuleInst.createCommunity(communityName, communityDescription, checkedMembership, ensOnlySwitchChecked, communityColor, communityImage, imageCropperModalaX, imageCropperModalaY, imageCropperModalbX, imageCropperModalbY); } + function importCommunity(communityKey) { + root.communitiesModuleInst.importCommunity(communityKey); + } + function createCommunityCategory(categoryName, channels) { chatCommunitySectionModule.createCommunityCategory(categoryName, channels) } diff --git a/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml b/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml index c54bc1cebe..6e2dd2c7a9 100644 --- a/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml @@ -363,7 +363,7 @@ Item { id: communitiesPopupComponent CommunitiesPopup { anchors.centerIn: parent - communitiesList: root.store.communitiesList + communitiesList: root.store.communitiesList onSetActiveCommunity: { root.store.setActiveCommunity(id) } @@ -391,8 +391,7 @@ Item { id: importCommunitiesPopupComponent AccessExistingCommunityPopup { anchors.centerIn: parent - // Not Refactored Yet -// error: root.store.chatsModelInst.communities.importCommunity(communityKey, Utils.uuid()) + store: root.store onClosed: { destroy() } @@ -420,52 +419,46 @@ Item { } } - // Not Refactored Yet -// Connections { -// target: root.store.chatsModelInst.communities -// onImportingCommunityStateChanged: { -// if (state !== Constants.communityImported && -// state !== Constants.communityImportingInProgress && -// state !== Constants.communityImportingError) -// { -// return -// } + Connections { + target: root.store.communitiesModuleInst + onImportingCommunityStateChanged: { + if (state !== Constants.communityImported && + state !== Constants.communityImportingInProgress && + state !== Constants.communityImportingError) + { + return + } -// if (state === Constants.communityImported) -// { -// if (Global.toastMessage.uuid !== communityImportingProcessId) -// return + Global.toastMessage.close() -// Global.toastMessage.close() + if (state === Constants.communityImported) + { + //% "Community imported" + Global.toastMessage.title = qsTrId("community-imported") + Global.toastMessage.source = "" + Global.toastMessage.iconRotates = false + Global.toastMessage.dissapearInMs = 4000 + } + else if (state === Constants.communityImportingInProgress) + { + //% "Importing community is in progress" + Global.toastMessage.title = qsTrId("importing-community-is-in-progress") + Global.toastMessage.source = Style.svg("loading") + Global.toastMessage.iconRotates = true + Global.toastMessage.dissapearInMs = -1 + } + else if (state === Constants.communityImportingError) + { + Global.toastMessage.title = errorMsg + Global.toastMessage.source = "" + Global.toastMessage.iconRotates = false + Global.toastMessage.dissapearInMs = 4000 + } -// //% "Community imported" -// Global.toastMessage.title = qsTrId("community-imported") -// Global.toastMessage.source = "" -// Global.toastMessage.iconRotates = false -// Global.toastMessage.dissapearInMs = 4000 -// } -// else if (state === Constants.communityImportingInProgress) -// { -// Global.toastMessage.uuid = communityImportingProcessId -// //% "Importing community is in progress" -// Global.toastMessage.title = qsTrId("importing-community-is-in-progress") -// Global.toastMessage.source = Style.svg("loading") -// Global.toastMessage.iconRotates = true -// Global.toastMessage.dissapearInMs = -1 -// } -// else if (state === Constants.communityImportingError) -// { -// if (Global.toastMessage.uuid !== communityImportingProcessId) -// return - -// Global.toastMessage.close() -// return -// } - -// Global.toastMessage.displayCloseButton = false -// Global.toastMessage.displayLink = false -// Global.toastMessage.iconColor = Style.current.primary -// Global.toastMessage.open() -// } -// } + Global.toastMessage.displayCloseButton = false + Global.toastMessage.displayLink = false + Global.toastMessage.iconColor = Style.current.primary + Global.toastMessage.open() + } + } }