From 19c283be8b367ba9952aa93ee196b14f90f9568c Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Wed, 20 Mar 2024 13:58:46 -0400 Subject: [PATCH] fix: fix warning and inconsistencies with spectating (#14041) Kinda fixes #13957 --- src/app/modules/main/chat_section/module.nim | 4 +- src/app/modules/main/controller.nim | 3 + src/app/modules/main/module.nim | 10 ++- src/app_service/service/community/service.nim | 28 +++---- ui/app/AppLayouts/Chat/ChatLayout.qml | 12 +-- ui/app/AppLayouts/Chat/stores/RootStore.qml | 2 +- .../AppLayouts/Chat/views/ChatColumnView.qml | 78 ++++++++++++------- .../views/chat/InvitationBubbleView.qml | 2 +- 8 files changed, 83 insertions(+), 56 deletions(-) diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 010d2f139c..4d6af359c3 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -503,8 +503,8 @@ method activeItemSet*(self: Module, itemId: string) = return # update view maintained by this module - self.view.chatsModel().setActiveItem(itemId) self.view.activeItemSet(chat_item) + self.view.chatsModel().setActiveItem(itemId) self.updateActiveChatMembership() @@ -536,7 +536,7 @@ method getModuleAsVariant*(self: Module): QVariant = method getChatContentModule*(self: Module, chatId: string): QVariant = if(not self.chatContentModules.contains(chatId)): - error "unexisting chat key", chatId, methodName="getChatContentModule" + error "getChatContentModule: unexisting chat key", chatId, methodName="getChatContentModule" return return self.chatContentModules[chatId].getModuleAsVariant() diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim index 8a509301bd..1b4c64a94e 100644 --- a/src/app/modules/main/controller.nim +++ b/src/app/modules/main/controller.nim @@ -545,6 +545,9 @@ proc switchTo*(self: Controller, sectionId, chatId, messageId: string) = proc getCommunityById*(self: Controller, communityId: string): CommunityDto = return self.communityService.getCommunityById(communityId) +proc spectateCommunity*(self: Controller, communityId: string) = + discard self.communityService.spectateCommunity(communityId) + proc getStatusForContactWithId*(self: Controller, publicKey: string): StatusUpdateDto = return self.contactsService.getStatusForContactWithId(publicKey) diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 694167b904..9421843499 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -1013,9 +1013,8 @@ method communityJoined*[T]( if setActive: self.setActiveSection(communitySectionItem) - if(channelGroup.chats.len > 0): - let chatId = channelGroup.chats[0].id - self.channelGroupModules[community.id].setActiveItem(chatId) + if channelGroup.chats.len > 0: + self.channelGroupModules[community.id].setActiveItem(channelGroup.chats[0].id) method communityLeft*[T](self: Module[T], communityId: string) = if(not self.channelGroupModules.contains(communityId)): @@ -1038,6 +1037,8 @@ method communityLeft*[T](self: Module[T], communityId: string) = method communityEdited*[T]( self: Module[T], community: CommunityDto) = + if(not self.channelGroupModules.contains(community.id)): + return let channelGroup = community.toChannelGroupDto() var channelGroupItem = self.createChannelGroupItem(channelGroup) # We need to calculate the unread counts because the community update doesn't come with it @@ -1411,6 +1412,9 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun of StatusUrlAction.OpenCommunity: let item = self.view.model().getItemById(communityId) if item.isEmpty(): + if self.controller.getCommunityById(communityId).id != "": + self.controller.spectateCommunity(communityId) + return # request community info and then spectate self.pendingSpectateRequest.communityId = communityId self.pendingSpectateRequest.channelUuid = "" diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index d19fb23781..7d01663148 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -930,7 +930,7 @@ QtObject: error "trying to get community categories for an unexisting community id" return - let categories = self.communities[communityId].categories + let categories = self.getCommunityById(communityId).categories let categoryIndex = findIndexById(categoryId, categories) return categories[categoryIndex] @@ -939,7 +939,7 @@ QtObject: error "trying to get community categories for an unexisting community id" return - result = self.communities[communityId].categories + result = self.getCommunityById(communityId).categories if(order == SortOrder.Ascending): result.sort(sortAsc[Category]) else: @@ -971,7 +971,7 @@ QtObject: error "trying to get all community chats for an unexisting community id", communityId return - result = self.communities[communityId].chats + result = self.getCommunityById(communityId).chats if(order == SortOrder.Ascending): result.sort(sortAsc[ChatDto]) @@ -1048,7 +1048,9 @@ QtObject: self.events.emit(SIGNAL_COMMUNITY_SPECTATED, CommunityArgs(community: updatedCommunity, fromUserAction: true, isPendingOwnershipRequest: (ownerTokenNotification != nil))) for k, chat in updatedCommunity.chats: - let fullChatId = communityId & chat.id + var fullChatId = chat.id + if not chat.id.startsWith(communityId): + fullChatId = communityId & chat.id let currentChat = self.chatService.getChatById(fullChatId, showWarning = false) if (currentChat.id != ""): @@ -1387,7 +1389,7 @@ QtObject: let prev_chat_idx = findIndexById(chat.id, self.communities[communityId].chats) if prev_chat_idx == -1: continue - let prev_chat = self.communities[communityId].chats[prev_chat_idx] + let prev_chat = self.getCommunityById(communityId).chats[prev_chat_idx] # we are free to do this cause channel must be created before we add it to a category var chatDetails = self.chatService.getChatById(chat.id) @@ -1974,7 +1976,7 @@ QtObject: error "Error slowing down archives import: ", msg = e.msg proc getPendingRequestIndex(self: Service, communityId: string, requestId: string): int = - let community = self.communities[communityId] + let community = self.getCommunityById(communityId) var i = 0 for pendingRequest in community.pendingRequestsToJoin: if (pendingRequest.id == requestId): @@ -1983,7 +1985,7 @@ QtObject: return -1 proc getDeclinedRequestIndex(self: Service, communityId: string, requestId: string): int = - let community = self.communities[communityId] + let community = self.getCommunityById(communityId) var i = 0 for declinedRequest in community.declinedRequestsToJoin: if (declinedRequest.id == requestId): @@ -1992,7 +1994,7 @@ QtObject: return -1 proc getWaitingForSharedAddressesRequestIndex(self: Service, communityId: string, requestId: string): int = - let community = self.communities[communityId] + let community = self.getCommunityById(communityId) for i in 0 ..< len(community.waitingForSharedAddressesRequestsToJoin): if (community.waitingForSharedAddressesRequestsToJoin[i].id == requestId): return i @@ -2007,7 +2009,7 @@ QtObject: if (indexPending == -1 and indexDeclined == -1 and indexAwaitingAddresses == -1): raise newException(RpcException, fmt"Community request not found: {requestId}") - var community = self.communities[communityId] + var community = self.getCommunityById(communityId) if (indexPending != -1): if @[RequestToJoinType.Declined, RequestToJoinType.Accepted, RequestToJoinType.Canceled].any(x => x == newState): @@ -2040,7 +2042,7 @@ QtObject: error "Cancel request to join community failed: unknown community", communityId=communityId return - var community = self.communities[communityId] + var community = self.getCommunityById(communityId) let myPublicKey = singletonInstance.userProfile.getPubKey() var i = 0 for myPendingRequest in community.pendingRequestsToJoin: @@ -2206,7 +2208,7 @@ QtObject: return false let myPublicKey = singletonInstance.userProfile.getPubKey() - var community = self.communities[communityId] + var community = self.getCommunityById(communityId) for pendingRequest in community.pendingRequestsToJoin: if pendingRequest.publicKey == myPublicKey: return true @@ -2218,7 +2220,7 @@ QtObject: return false let myPublicKey = singletonInstance.userProfile.getPubKey() - var community = self.communities[communityId] + var community = self.getCommunityById(communityId) for request in community.waitingForSharedAddressesRequestsToJoin: if request.publicKey == myPublicKey: return true @@ -2281,7 +2283,7 @@ QtObject: if (indexPending == -1 and indexDeclined == -1): raise newException(RpcException, fmt"Community request not found: {requestId}") - let community = self.communities[communityId] + let community = self.getCommunityById(communityId) if (indexPending != -1): return community.pendingRequestsToJoin[indexPending].publicKey else: diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index a97dd7397f..e40031188c 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -59,15 +59,15 @@ StackLayout { Loader { id: mainViewLoader - readonly property var chatItem: root.rootStore.chatCommunitySectionModule + readonly property var sectionItem: root.rootStore.chatCommunitySectionModule sourceComponent: { - if (chatItem.isCommunity() && !chatItem.amIMember) { + if (sectionItem.isCommunity() && !sectionItem.amIMember) { if (sectionItemModel.amIBanned) { return communityBanComponent - } else if (chatItem.isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin) { + } else if (sectionItem.isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin) { return controlNodeOfflineComponent - } else if (chatItem.requiresTokenPermissionToJoin) { + } else if (sectionItem.requiresTokenPermissionToJoin) { return joinCommunityViewComponent } } @@ -149,7 +149,7 @@ StackLayout { ChatView { id: chatView - readonly property var chatItem: root.rootStore.chatCommunitySectionModule + readonly property var sectionItem: root.rootStore.chatCommunitySectionModule readonly property string communityId: root.sectionItemModel.id emojiPopup: root.emojiPopup @@ -162,7 +162,7 @@ StackLayout { walletAssetsStore: root.walletAssetsStore currencyStore: root.currencyStore sectionItemModel: root.sectionItemModel - amIMember: chatItem.amIMember + amIMember: sectionItem.amIMember amISectionAdmin: root.sectionItemModel.memberRole === Constants.memberRole.owner || root.sectionItemModel.memberRole === Constants.memberRole.admin || root.sectionItemModel.memberRole === Constants.memberRole.tokenMaster diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index 07a37886f7..6ff862a44d 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -75,7 +75,7 @@ QtObject { readonly property var oneToOneChatContact: _d.oneToOneChatContact // Since qml component doesn't follow encaptulation from the backend side, we're introducing // a method which will return appropriate chat content module for selected chat/channel - function currentChatContentModule(){ + function currentChatContentModule() { // When we decide to have the same struct as it's on the backend we will remove this function. // So far this is a way to deal with refactored backend from the current qml structure. chatCommunitySectionModule.prepareChatContentModuleForChatId(chatCommunitySectionModule.activeItem.id) diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index ea57f4a489..8a06134429 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -82,12 +82,15 @@ Item { readonly property var activeChatContentModule: d.getChatContentModule(root.activeChatId) readonly property var urlsList: { + if (!d.activeChatContentModule) { + return + } urlsModelChangeTracker.revision ModelUtils.modelToFlatArray(d.activeChatContentModule.inputAreaModule.urlsModel, "url") } readonly property ModelChangeTracker urlsModelChangeTracker: ModelChangeTracker { - model: d.activeChatContentModule.inputAreaModule.urlsModel + model: !!d.activeChatContentModule ? d.activeChatContentModule.inputAreaModule.urlsModel : null } readonly property UsersStore activeUsersStore: UsersStore { @@ -126,6 +129,9 @@ Item { } function restoreInputReply() { + if (!d.activeChatContentModule) { + return + } const replyMessageId = d.activeChatContentModule.inputAreaModule.preservedProperties.replyMessageId if (replyMessageId) d.showReplyArea(replyMessageId) @@ -134,6 +140,9 @@ Item { } function restoreInputAttachments() { + if (!d.activeChatContentModule) { + return + } const filesJson = d.activeChatContentModule.inputAreaModule.preservedProperties.fileUrlsAndSourcesJson let filesList = [] if (filesJson) { @@ -164,6 +173,9 @@ Item { } readonly property var updateLinkPreviews: { + if (!d.activeChatContentModule) { + return + } return Backpressure.debounce(this, 250, () => { const messageText = root.rootStore.cleanMessageText(chatInput.textInput.text) d.activeChatContentModule.inputAreaModule.setText(messageText) @@ -171,10 +183,11 @@ Item { } onActiveChatContentModuleChanged: { - let preservedText = "" - if (d.activeChatContentModule) { - preservedText = d.activeChatContentModule.inputAreaModule.preservedProperties.text + if (!d.activeChatContentModule) { + return } + let preservedText = "" + preservedText = d.activeChatContentModule.inputAreaModule.preservedProperties.text d.activeChatContentModule.inputAreaModule.clearLinkPreviewCache() // Call later to make sure activeUsersStore and activeMessagesStore bindings are updated @@ -203,33 +216,38 @@ Item { id: chatRepeater model: parentModule && parentModule.model - ChatContentView { + Loader { width: parent.width height: parent.height - visible: !root.rootStore.openCreateChat && model.active - chatId: model.itemId - chatType: model.type - chatMessagesLoader.active: model.loaderActive - rootStore: root.rootStore - contactsStore: root.contactsStore - emojiPopup: root.emojiPopup - stickersPopup: root.stickersPopup - stickersLoaded: root.stickersLoaded - isBlocked: model.blocked - onOpenStickerPackPopup: { - root.openStickerPackPopup(stickerPackId) - } - onShowReplyArea: (messageId) => { - d.showReplyArea(messageId) - } - onForceInputFocus: { - chatInput.forceInputActiveFocus() - } + active: model.type !== Constants.chatType.category && model.type !== Constants.chatType.unknown + sourceComponent: ChatContentView { + width: parent.width + height: parent.height + visible: !root.rootStore.openCreateChat && model.active + chatId: model.itemId + chatType: model.type + chatMessagesLoader.active: model.loaderActive + rootStore: root.rootStore + contactsStore: root.contactsStore + emojiPopup: root.emojiPopup + stickersPopup: root.stickersPopup + stickersLoaded: root.stickersLoaded + isBlocked: model.blocked + onOpenStickerPackPopup: { + root.openStickerPackPopup(stickerPackId) + } + onShowReplyArea: (messageId) => { + d.showReplyArea(messageId) + } + onForceInputFocus: { + chatInput.forceInputActiveFocus() + } - Component.onCompleted: { - chatContentModule = d.getChatContentModule(model.itemId) - chatSectionModule = root.parentModule - root.checkForCreateChatOptions(model.itemId) + Component.onCompleted: { + chatContentModule = d.getChatContentModule(model.itemId) + chatSectionModule = root.parentModule + root.checkForCreateChatOptions(model.itemId) + } } } } @@ -264,7 +282,7 @@ Item { store: root.rootStore usersStore: d.activeUsersStore - linkPreviewModel: d.activeChatContentModule.inputAreaModule.linkPreviewModel + linkPreviewModel: !!d.activeChatContentModule ? d.activeChatContentModule.inputAreaModule.linkPreviewModel : null urlsList: d.urlsList askToEnableLinkPreview: { if(!d.activeChatContentModule || !d.activeChatContentModule.inputAreaModule || !d.activeChatContentModule.inputAreaModule.preservedProperties) @@ -274,7 +292,7 @@ Item { } textInput.placeholderText: { if (!channelPostRestrictions.visible) { - if (d.activeChatContentModule.chatDetails.blocked) + if (d.activeChatContentModule && d.activeChatContentModule.chatDetails.blocked) return qsTr("This user has been blocked.") if (!root.rootStore.sectionDetails.joined || root.rootStore.sectionDetails.amIBanned) { return qsTr("You need to join this community to send messages") diff --git a/ui/imports/shared/views/chat/InvitationBubbleView.qml b/ui/imports/shared/views/chat/InvitationBubbleView.qml index e428555c78..12e2bf97a3 100644 --- a/ui/imports/shared/views/chat/InvitationBubbleView.qml +++ b/ui/imports/shared/views/chat/InvitationBubbleView.qml @@ -206,7 +206,7 @@ Control { if (d.communityJoined || d.communitySpectated) { root.store.setActiveCommunity(communityId) } else { - root.store.spectateCommunity(communityId, userProfile.name) + root.store.spectateCommunity(communityId) } } }