From f7823cd0b7f6d4a36c6a7d85ddb9ab3503591f5e Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 25 Oct 2024 21:25:50 -0400 Subject: [PATCH] refactor(members): unify members models into one (#16508) Fixes #16433 --- .../chat_content/users/module.nim | 6 +- src/app/modules/main/communities/module.nim | 85 +++++++------ src/app/modules/main/module.nim | 65 +++++----- .../modules/shared_models/member_model.nim | 25 +++- .../modules/shared_models/section_item.nim | 45 ++----- .../modules/shared_models/section_model.nim | 67 ++--------- src/app_service/common/types.nim | 25 ++-- .../ProfilePopupInviteFriendsPanelPage.qml | 2 +- ui/app/AppLayouts/Chat/ChatLayout.qml | 67 ++++++----- ui/app/AppLayouts/Chat/views/ChatView.qml | 4 +- .../Chat/views/MembersModelAdaptor.qml | 113 ++++++++++++++++++ .../panels/MembersSettingsPanel.qml | 33 ++--- .../panels/ProfilePopupInviteFriendsPanel.qml | 8 +- .../popups/ImportControlNodePopup.qml | 4 +- .../popups/InviteFriendsToCommunityPopup.qml | 2 +- .../Communities/views/CommunityColumnView.qml | 3 +- .../views/CommunitySettingsView.qml | 20 ++-- .../helpers/ProfileShowcaseModelAdapter.qml | 11 +- .../ProfileShowcaseSettingsModelAdapter.qml | 8 +- .../Profile/stores/ProfileSectionStore.qml | 2 +- ui/app/mainui/Popups.qml | 2 +- .../ProfileShowcaseCommunitiesView.qml | 6 +- ui/imports/utils/Constants.qml | 5 +- 23 files changed, 353 insertions(+), 255 deletions(-) create mode 100644 ui/app/AppLayouts/Chat/views/MembersModelAdaptor.qml diff --git a/src/app/modules/main/chat_section/chat_content/users/module.nim b/src/app/modules/main/chat_section/chat_content/users/module.nim index 5ebd9ac27d..f3898fd9c9 100644 --- a/src/app/modules/main/chat_section/chat_content/users/module.nim +++ b/src/app/modules/main/chat_section/chat_content/users/module.nim @@ -206,10 +206,10 @@ method onChatMemberUpdated*(self: Module, publicKey: string, memberRole: MemberR icon = contactDetails.icon, isContact = contactDetails.dto.isContact, isVerified = not isMe and contactDetails.dto.isContactVerified(), - memberRole = memberRole, - joined = joined, + memberRole, + joined, isUntrustworthy = contactDetails.dto.trustStatus == TrustStatus.Untrustworthy, - ) + ) method addGroupMembers*(self: Module, pubKeys: seq[string]) = self.controller.addGroupMembers(pubKeys) diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index cc10838645..6d4c4cad67 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -198,54 +198,61 @@ proc createMemberItem(self: Module, memberId, requestId: string, status: Members membershipRequestState = status, ) -method getCommunityItem(self: Module, c: CommunityDto): SectionItem = - # TODO: unite bannedMembers, pendingMemberRequests and declinedMemberRequests - var members: seq[MemberItem] = @[] - for member in c.members: - if c.pendingAndBannedMembers.hasKey(member.id): - let communityMemberState = c.pendingAndBannedMembers[member.id] - members.add(self.createMemberItem(member.id, "", toMembershipRequestState(communityMemberState))) +method getCommunityItem(self: Module, community: CommunityDto): SectionItem = + var memberItems: seq[MemberItem] = @[] + for member in community.members: + var communityMemberState = MembershipRequestState.Accepted + if community.pendingAndBannedMembers.hasKey(member.id): + let memberState = community.pendingAndBannedMembers[member.id].toMembershipRequestState() + if memberState == MembershipRequestState.BannedPending or memberState == MembershipRequestState.KickedPending: + communityMemberState = memberState + memberItems.add(self.createMemberItem(member.id, "", communityMemberState)) var bannedMembers: seq[MemberItem] = @[] - for memberId, communityMemberState in c.pendingAndBannedMembers: + for memberId, communityMemberState in community.pendingAndBannedMembers: bannedMembers.add(self.createMemberItem(memberId, "", toMembershipRequestState(communityMemberState))) + let pendingMembers = community.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = + result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state)) + ) + let declinedMemberItems = community.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = + result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state)) + ) + + memberItems = concat(memberItems, pendingMembers, declinedMemberItems, bannedMembers) + return initItem( - c.id, + community.id, SectionType.Community, - c.name, - c.memberRole, - c.isControlNode, - c.description, - c.introMessage, - c.outroMessage, - c.images.thumbnail, - c.images.banner, + community.name, + community.memberRole, + community.isControlNode, + community.description, + community.introMessage, + community.outroMessage, + community.images.thumbnail, + community.images.banner, icon = "", - c.color, - c.tags, + community.color, + community.tags, hasNotification = false, notificationsCount = 0, active = false, enabled = true, - c.joined, - c.canJoin, - c.spectated, - c.canManageUsers, - c.canRequestAccess, - c.isMember, - c.permissions.access, - c.permissions.ensOnly, - c.muted, - members = members, - historyArchiveSupportEnabled = c.settings.historyArchiveSupportEnabled, - bannedMembers = bannedMembers, - pendingMemberRequests = c.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = - result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state))), - declinedMemberRequests = c.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = - result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state))), - encrypted = c.encrypted, - communityTokens = @[] + community.joined, + community.canJoin, + community.spectated, + community.canManageUsers, + community.canRequestAccess, + community.isMember, + community.permissions.access, + community.permissions.ensOnly, + community.muted, + members = memberItems, + historyArchiveSupportEnabled = community.settings.historyArchiveSupportEnabled, + encrypted = community.encrypted, + communityTokens = @[], + activeMembersCount = int(community.activeMembersCount), ) proc getCuratedCommunityItem(self: Module, community: CommunityDto): CuratedCommunityItem = @@ -302,8 +309,10 @@ method setCommunityTags*(self: Module, communityTags: string) = self.view.setCommunityTags(communityTags) method setAllCommunities*(self: Module, communities: seq[CommunityDto]) = + var items: seq[SectionItem] = @[] for community in communities: - self.view.addItem(self.getCommunityItem(community)) + items.add(self.getCommunityItem(community)) + self.view.model.addItems(items) method communityAdded*(self: Module, community: CommunityDto) = self.view.addItem(self.getCommunityItem(community)) diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index c827d4d07e..ba961a1aa2 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -359,6 +359,36 @@ proc createCommunitySectionItem[T](self: Module[T], communityDetails: CommunityD else: discard + var memberItems = members.map(proc(member: ChatMember): MemberItem = + var state = MembershipRequestState.Accepted + if member.id in communityDetails.pendingAndBannedMembers: + let memberState = communityDetails.pendingAndBannedMembers[member.id].toMembershipRequestState() + if memberState == MembershipRequestState.BannedPending or memberState == MembershipRequestState.KickedPending: + state = memberState + elif not member.joined: + state = MembershipRequestState.AwaitingAddress + var airdropAddress = "" + if not existingCommunity.isEmpty() and not existingCommunity.communityTokens.isNil: + airdropAddress = existingCommunity.members.getAirdropAddressForMember(member.id) + result = self.createMemberItem( + member.id, + requestId = "", + state, + member.role, + airdropAddress, + ) + ) + + let pendingMembers = communityDetails.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = + result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None) + ) + + let declinedMemberItems = communityDetails.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = + result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None) + ) + + memberItems = concat(memberItems, pendingMembers, declinedMemberItems, bannedMembers) + result = initItem( communityDetails.id, sectionType = SectionType.Community, @@ -386,42 +416,15 @@ proc createCommunitySectionItem[T](self: Module[T], communityDetails: CommunityD communityDetails.permissions.access, communityDetails.permissions.ensOnly, communityDetails.muted, - # members - members.map(proc(member: ChatMember): MemberItem = - var state = MembershipRequestState.Accepted - if member.id in communityDetails.pendingAndBannedMembers: - let memberState = communityDetails.pendingAndBannedMembers[member.id].toMembershipRequestState() - if memberState == MembershipRequestState.BannedPending or memberState == MembershipRequestState.KickedPending: - state = memberState - elif not member.joined: - state = MembershipRequestState.AwaitingAddress - var airdropAddress = "" - if not existingCommunity.isEmpty() and not existingCommunity.communityTokens.isNil: - airdropAddress = existingCommunity.members.getAirdropAddressForMember(member.id) - result = self.createMemberItem( - member.id, - requestId = "", - state, - member.role, - airdropAddress, - ) - ), + memberItems, communityDetails.settings.historyArchiveSupportEnabled, communityDetails.adminSettings.pinMessageAllMembersEnabled, - bannedMembers, - # pendingMemberRequests - communityDetails.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = - result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None) - ), - # declinedMemberRequests - communityDetails.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem = - result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None) - ), communityDetails.encrypted, communityTokensItems, communityDetails.pubsubTopic, communityDetails.pubsubTopicKey, communityDetails.shard.index, + activeMembersCount = int(communityDetails.activeMembersCount), ) proc connectForNotificationsOnly[T](self: Module[T]) = @@ -1358,7 +1361,7 @@ method newCommunityMembershipRequestReceived*[T](self: Module[T], membershipRequ singletonInstance.globalEvents.newCommunityMembershipRequestNotification("New membership request", fmt "{contactName} asks to join {community.name}", community.id) - self.view.model().addPendingMember(membershipRequest.communityId, self.createMemberItem( + self.view.model().addMember(membershipRequest.communityId, self.createMemberItem( membershipRequest.publicKey, membershipRequest.id, MembershipRequestState(membershipRequest.state), @@ -1366,7 +1369,7 @@ method newCommunityMembershipRequestReceived*[T](self: Module[T], membershipRequ )) method communityMembershipRequestCanceled*[T](self: Module[T], communityId: string, requestId: string, pubKey: string) = - self.view.model().removePendingMember(communityId, pubKey) + self.view.model().removeMember(communityId, pubKey) method meMentionedCountChanged*[T](self: Module[T], allMentions: int) = singletonInstance.globalEvents.meMentionedIconBadgeNotification(allMentions) diff --git a/src/app/modules/shared_models/member_model.nim b/src/app/modules/shared_models/member_model.nim index 51315cc283..0b0e982971 100644 --- a/src/app/modules/shared_models/member_model.nim +++ b/src/app/modules/shared_models/member_model.nim @@ -174,13 +174,17 @@ QtObject: self.endInsertRows() self.countChanged() - proc findIndexForMember(self: Model, pubKey: string): int = + proc findIndexForMember*(self: Model, pubKey: string): int = for i in 0 ..< self.items.len: - if(self.items[i].pubKey == pubKey): + if self.items[i].pubKey == pubKey: return i return -1 + proc getMemberItemByIndex*(self: Model, ind: int): MemberItem = + if ind >= 0 and ind < self.items.len: + return self.items[ind] + proc getMemberItem*(self: Model, pubKey: string): MemberItem = let ind = self.findIndexForMember(pubKey) if ind != -1: @@ -283,6 +287,7 @@ QtObject: memberRole: MemberRole, joined: bool, isUntrustworthy: bool, + membershipRequestState: MembershipRequestState = MembershipRequestState.None, callDataChanged: bool = true, ): seq[int] = let ind = self.findIndexForMember(pubKey) @@ -307,6 +312,12 @@ QtObject: updateRole(joined, Joined) updateRole(isUntrustworthy, IsUntrustworthy) + var updatedMembershipRequestState = membershipRequestState + if updatedMembershipRequestState == MembershipRequestState.None: + updatedMembershipRequestState = self.items[ind].membershipRequestState + + updateRoleWithValue(membershipRequestState, MembershipRequestState, updatedMembershipRequestState) + if preferredDisplayNameChanged: roles.add(ModelRole.PreferredDisplayName.int) @@ -341,6 +352,7 @@ QtObject: item.memberRole, item.joined, item.isUntrustworthy, + item.membershipRequestState, callDataChanged = false, ) @@ -409,7 +421,7 @@ QtObject: isContact: bool, isVerified: bool, isUntrustworthy: bool, - ) = + ) = let ind = self.findIndexForMember(pubKey) if ind == -1: return @@ -427,6 +439,7 @@ QtObject: memberRole = self.items[ind].memberRole, joined = self.items[ind].joined, isUntrustworthy, + self.items[ind].membershipRequestState, ) proc setOnlineStatus*(self: Model, pubKey: string, onlineStatus: OnlineStatus) = @@ -509,3 +522,9 @@ QtObject: break if not found: result.add(pubkey) + + proc isUserBanned*(self: Model, pubkey: string): bool = + let ind = self.findIndexForMember(pubkey) + if ind == -1: + return false + return self.getMemberItemByIndex(ind).membershipRequestState == MembershipRequestState.Banned diff --git a/src/app/modules/shared_models/section_item.nim b/src/app/modules/shared_models/section_item.nim index 667c951931..cc99b3c6a3 100644 --- a/src/app/modules/shared_models/section_item.nim +++ b/src/app/modules/shared_models/section_item.nim @@ -49,15 +49,13 @@ type membersModel: member_model.Model historyArchiveSupportEnabled: bool pinMessageAllMembersEnabled: bool - bannedMembersModel: member_model.Model - pendingMemberRequestsModel*: member_model.Model - declinedMemberRequestsModel: member_model.Model encrypted: bool communityTokensModel: community_tokens_model.TokenModel pubsubTopic: string pubsubTopicKey: string shardIndex: int isPendingOwnershipRequest: bool + activeMembersCount: int proc initItem*( id: string, @@ -89,15 +87,13 @@ proc initItem*( members: seq[MemberItem] = @[], historyArchiveSupportEnabled = false, pinMessageAllMembersEnabled = false, - bannedMembers: seq[MemberItem] = @[], - pendingMemberRequests: seq[MemberItem] = @[], - declinedMemberRequests: seq[MemberItem] = @[], encrypted: bool = false, communityTokens: seq[TokenItem] = @[], pubsubTopic = "", pubsubTopicKey = "", shardIndex = -1, - isPendingOwnershipRequest: bool = false + isPendingOwnershipRequest: bool = false, + activeMembersCount: int = 0, ): SectionItem = result.id = id result.sectionType = sectionType @@ -129,12 +125,6 @@ proc initItem*( result.membersModel.setItems(members) result.historyArchiveSupportEnabled = historyArchiveSupportEnabled result.pinMessageAllMembersEnabled = pinMessageAllMembersEnabled - result.bannedMembersModel = newModel() - result.bannedMembersModel.setItems(bannedMembers) - result.pendingMemberRequestsModel = newModel() - result.pendingMemberRequestsModel.setItems(pendingMemberRequests) - result.declinedMemberRequestsModel = newModel() - result.declinedMemberRequestsModel.setItems(declinedMemberRequests) result.encrypted = encrypted result.communityTokensModel = newTokenModel() result.communityTokensModel.setItems(communityTokens) @@ -142,6 +132,7 @@ proc initItem*( result.pubsubTopicKey = pubsubTopicKey result.shardIndex = shardIndex result.isPendingOwnershipRequest = isPendingOwnershipRequest + result.activeMembersCount = activeMembersCount proc isEmpty*(self: SectionItem): bool = return self.id.len == 0 @@ -177,9 +168,6 @@ proc `$`*(self: SectionItem): string = members:{self.membersModel}, historyArchiveSupportEnabled:{self.historyArchiveSupportEnabled}, pinMessageAllMembersEnabled:{self.pinMessageAllMembersEnabled}, - bannedMembers:{self.bannedMembersModel}, - pendingMemberRequests:{self.pendingMemberRequestsModel}, - declinedMemberRequests:{self.declinedMemberRequestsModel}, encrypted:{self.encrypted}, communityTokensModel:{self.communityTokensModel}, isPendingOwnershipRequest:{self.isPendingOwnershipRequest} @@ -365,17 +353,8 @@ proc updateMember*( self.membersModel.updateItem(pubkey, name, ensName, isEnsVerified, nickname, alias, image, isContact, isVerified, isUntrustworthy) -proc bannedMembers*(self: SectionItem): member_model.Model {.inline.} = - self.bannedMembersModel - proc amIBanned*(self: SectionItem): bool {.inline.} = - self.bannedMembersModel.isContactWithIdAdded(singletonInstance.userProfile.getPubKey()) - -proc pendingMemberRequests*(self: SectionItem): member_model.Model {.inline.} = - self.pendingMemberRequestsModel - -proc declinedMemberRequests*(self: SectionItem): member_model.Model {.inline.} = - self.declinedMemberRequestsModel + return self.membersModel.isUserBanned(singletonInstance.userProfile.getPubKey()) proc isPendingOwnershipRequest*(self: SectionItem): bool {.inline.} = self.isPendingOwnershipRequest @@ -438,14 +417,10 @@ proc communityTokens*(self: SectionItem): community_tokens_model.TokenModel {.in self.communityTokensModel proc updatePendingRequestLoadingState*(self: SectionItem, memberKey: string, loading: bool) {.inline.} = - self.pendingMemberRequestsModel.updateLoadingState(memberKey, loading) + self.membersModel.updateLoadingState(memberKey, loading) proc updateMembershipStatus*(self: SectionItem, memberKey: string, state: MembershipRequestState) {.inline.} = - case state: - of MembershipRequestState.Banned, MembershipRequestState.BannedWithAllMessagesDelete, MembershipRequestState.UnbannedPending: - self.bannedMembersModel.updateMembershipStatus(memberKey, state) - else: - self.membersModel.updateMembershipStatus(memberKey, state) + self.membersModel.updateMembershipStatus(memberKey, state) proc pubsubTopic*(self: SectionItem): string {.inline.} = self.pubsubTopic @@ -464,3 +439,9 @@ proc shardIndex*(self: SectionItem): int {.inline.} = proc `shardIndex=`*(self: var SectionItem, value: int) {.inline.} = self.shardIndex = value + +proc activeMembersCount*(self: SectionItem): int {.inline.} = + self.activeMembersCount + +proc `activeMembersCount=`*(self: var SectionItem, value: int) {.inline.} = + self.activeMembersCount = value diff --git a/src/app/modules/shared_models/section_model.nim b/src/app/modules/shared_models/section_model.nim index 29f8a4deb9..94909034f3 100644 --- a/src/app/modules/shared_models/section_model.nim +++ b/src/app/modules/shared_models/section_model.nim @@ -37,16 +37,14 @@ type MembersModel HistoryArchiveSupportEnabled PinMessageAllMembersEnabled - BannedMembersModel Encrypted CommunityTokensModel - PendingMemberRequestsModel - DeclinedMemberRequestsModel AmIBanned PubsubTopic PubsubTopicKey ShardIndex IsPendingOwnershipRequest + ActiveMembersCount QtObject: type @@ -110,19 +108,17 @@ QtObject: ModelRole.Access.int:"access", ModelRole.EnsOnly.int:"ensOnly", ModelRole.Muted.int:"muted", - ModelRole.MembersModel.int:"members", + ModelRole.MembersModel.int:"allMembers", ModelRole.HistoryArchiveSupportEnabled.int:"historyArchiveSupportEnabled", ModelRole.PinMessageAllMembersEnabled.int:"pinMessageAllMembersEnabled", - ModelRole.BannedMembersModel.int:"bannedMembers", ModelRole.Encrypted.int:"encrypted", ModelRole.CommunityTokensModel.int:"communityTokens", - ModelRole.PendingMemberRequestsModel.int:"pendingMemberRequests", - ModelRole.DeclinedMemberRequestsModel.int:"declinedMemberRequests", ModelRole.AmIBanned.int:"amIBanned", ModelRole.PubsubTopic.int:"pubsubTopic", ModelRole.PubsubTopicKey.int:"pubsubTopicKey", ModelRole.ShardIndex.int:"shardIndex", ModelRole.IsPendingOwnershipRequest.int:"isPendingOwnershipRequest", + ModelRole.ActiveMembersCount.int:"activeMembersCount", }.toTable method data(self: SectionModel, index: QModelIndex, role: int): QVariant = @@ -194,16 +190,10 @@ QtObject: result = newQVariant(item.historyArchiveSupportEnabled) of ModelRole.PinMessageAllMembersEnabled: result = newQVariant(item.pinMessageAllMembersEnabled) - of ModelRole.BannedMembersModel: - result = newQVariant(item.bannedMembers) of ModelRole.Encrypted: result = newQVariant(item.encrypted) of ModelRole.CommunityTokensModel: result = newQVariant(item.communityTokens) - of ModelRole.PendingMemberRequestsModel: - result = newQVariant(item.pendingMemberRequests) - of ModelRole.DeclinedMemberRequestsModel: - result = newQVariant(item.declinedMemberRequests) of ModelRole.AmIBanned: result = newQVariant(item.amIBanned) of ModelRole.PubsubTopic: @@ -214,6 +204,8 @@ QtObject: result = newQVariant(item.shardIndex) of ModelRole.IsPendingOwnershipRequest: result = newQVariant(item.isPendingOwnershipRequest) + of ModelRole.ActiveMembersCount: + result = newQVariant(item.activeMembersCount) proc itemExists*(self: SectionModel, id: string): bool = for it in self.items: @@ -330,11 +322,9 @@ QtObject: updateRoleWithValue(pubsubTopicKey, PubsubTopicKey, item.pubsubTopicKey) updateRoleWithValue(shardIndex, ShardIndex, item.shardIndex) updateRoleWithValue(isPendingOwnershipRequest, IsPendingOwnershipRequest, item.isPendingOwnershipRequest) + updateRoleWithValue(activeMembersCount, ActiveMembersCount, item.activeMembersCount) self.items[ind].members.updateToTheseItems(item.members.getItems()) - self.items[ind].bannedMembers.updateToTheseItems(item.bannedMembers.getItems()) - self.items[ind].pendingMemberRequests.updateToTheseItems(item.pendingMemberRequests.getItems()) - self.items[ind].declinedMemberRequests.updateToTheseItems(item.declinedMemberRequests.getItems()) if roles.len == 0: return @@ -357,7 +347,6 @@ QtObject: isUntrustworthy: bool, ) = for item in self.items: - # TODO refactor to use only one model https://github.com/status-im/status-desktop/issues/16433 item.members.updateItem( pubKey, displayName, @@ -370,42 +359,6 @@ QtObject: isVerified, isUntrustworthy, ) - item.bannedMembers.updateItem( - pubKey, - displayName, - ensName, - isEnsVerified, - localNickname, - alias, - icon, - isContact, - isVerified, - isUntrustworthy, - ) - item.pendingMemberRequests.updateItem( - pubKey, - displayName, - ensName, - isEnsVerified, - localNickname, - alias, - icon, - isContact, - isVerified, - isUntrustworthy, - ) - item.declinedMemberRequests.updateItem( - pubKey, - displayName, - ensName, - isEnsVerified, - localNickname, - alias, - icon, - isContact, - isVerified, - isUntrustworthy, - ) proc getNthEnabledItem*(self: SectionModel, nth: int): SectionItem = if nth >= 0 and nth < self.items.len: @@ -598,16 +551,16 @@ QtObject: self.items[index].communityTokens.setItems(communityTokensItems) - proc addPendingMember*(self: SectionModel, communityId: string, memberItem: MemberItem) = + proc addMember*(self: SectionModel, communityId: string, memberItem: MemberItem) = let i = self.getItemIndex(communityId) if i == -1: return - self.items[i].pendingMemberRequests.addItem(memberItem) + self.items[i].members.addItem(memberItem) - proc removePendingMember*(self: SectionModel, communityId: string, memberId: string) = + proc removeMember*(self: SectionModel, communityId: string, memberId: string) = let i = self.getItemIndex(communityId) if i == -1: return - self.items[i].pendingMemberRequests.removeItemById(memberId) + self.items[i].members.removeItemById(memberId) diff --git a/src/app_service/common/types.nim b/src/app_service/common/types.nim index 6ca65a8dff..46d395277f 100644 --- a/src/app_service/common/types.nim +++ b/src/app_service/common/types.nim @@ -61,18 +61,19 @@ type MemberRole* {.pure} = enum type MembershipRequestState* {.pure} = enum None = 0, Pending = 1, - Accepted = 2, - Declined = 3, - AcceptedPending = 4, - DeclinedPending = 5, - Banned = 6, - Kicked = 7, - BannedPending = 8, - UnbannedPending = 9, - KickedPending = 10, - AwaitingAddress = 11, - Unbanned = 12, - BannedWithAllMessagesDelete = 13 + Declined = 2, + Accepted = 3 + Canceled = 4, + AcceptedPending = 5, + DeclinedPending = 6, + AwaitingAddress = 7, + Banned = 8, + Kicked = 9, + BannedPending = 10, + UnbannedPending = 11, + KickedPending = 12, + Unbanned = 13, + BannedWithAllMessagesDelete = 14 type ContractTransactionStatus* {.pure.} = enum diff --git a/storybook/pages/ProfilePopupInviteFriendsPanelPage.qml b/storybook/pages/ProfilePopupInviteFriendsPanelPage.qml index 657a169150..177fadd6a1 100644 --- a/storybook/pages/ProfilePopupInviteFriendsPanelPage.qml +++ b/storybook/pages/ProfilePopupInviteFriendsPanelPage.qml @@ -57,7 +57,7 @@ Item { sourceComponent: ProfilePopupInviteFriendsPanel { id: panel - community: ({ id: "communityId" }) + communityId: "communityId" rootStore: AppLayoutStores.RootStore { function communityHasMember(communityId, pubKey) { diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index aba064f451..99e096fe40 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -18,7 +18,9 @@ import AppLayouts.Chat.stores 1.0 as ChatStores import AppLayouts.Profile.stores 1.0 as ProfileStores import AppLayouts.Wallet.stores 1.0 as WalletStore +import StatusQ 0.1 import StatusQ.Core.Utils 0.1 +import SortFilterProxyModel 0.2 StackLayout { id: root @@ -35,6 +37,12 @@ StackLayout { required property SharedStores.CurrenciesStore currencyStore property var sectionItemModel + + MembersModelAdaptor { + id: membersModelAdaptor + allMembers: !!sectionItemModel ? sectionItemModel.allMembers : null + } + property var sendModalPopup readonly property bool isOwner: sectionItemModel.memberRole === Constants.memberRole.owner @@ -96,23 +104,22 @@ StackLayout { id: joinCommunityViewComponent JoinCommunityView { id: joinCommunityView - readonly property var communityData: sectionItemModel - readonly property string communityId: communityData.id - name: communityData.name - introMessage: communityData.introMessage - communityDesc: communityData.description - color: communityData.color - image: communityData.image - membersCount: communityData.members.count + readonly property string communityId: sectionItemModel.id + name: sectionItemModel.name + introMessage: sectionItemModel.introMessage + communityDesc: sectionItemModel.description + color: sectionItemModel.color + image: sectionItemModel.image + membersCount: membersModelAdaptor.joinedMembers.ModelCount.count accessType: mainViewLoader.accessType joinCommunity: true - amISectionAdmin: communityData.memberRole === Constants.memberRole.owner || - communityData.memberRole === Constants.memberRole.admin || - communityData.memberRole === Constants.memberRole.tokenMaster + amISectionAdmin: sectionItemModel.memberRole === Constants.memberRole.owner || + sectionItemModel.memberRole === Constants.memberRole.admin || + sectionItemModel.memberRole === Constants.memberRole.tokenMaster communityItemsModel: root.rootStore.communityItemsModel requirementsMet: root.permissionsStore.allTokenRequirementsMet requirementsCheckPending: root.rootStore.permissionsCheckOngoing - requiresRequest: !communityData.amIMember + requiresRequest: !sectionItemModel.amIMember communityHoldingsModel: root.permissionsStore.becomeMemberPermissionsModel viewOnlyHoldingsModel: root.permissionsStore.viewOnlyPermissionsModel viewAndPostHoldingsModel: root.permissionsStore.viewAndPostPermissionsModel @@ -125,13 +132,13 @@ StackLayout { onNotificationButtonClicked: Global.openActivityCenterPopup() onAdHocChatButtonClicked: rootStore.openCloseCreateChatView() onRequestToJoinClicked: { - Global.communityIntroPopupRequested(joinCommunityView.communityId, communityData.name, - communityData.introMessage, communityData.image, + Global.communityIntroPopupRequested(joinCommunityView.communityId, sectionItemModel.name, + sectionItemModel.introMessage, sectionItemModel.image, root.isInvitationPending) } onInvitationPendingClicked: { - Global.communityIntroPopupRequested(joinCommunityView.communityId, communityData.name, communityData.introMessage, - communityData.image, root.isInvitationPending) + Global.communityIntroPopupRequested(joinCommunityView.communityId, sectionItemModel.name, sectionItemModel.introMessage, + sectionItemModel.image, root.isInvitationPending) } } } @@ -157,6 +164,7 @@ StackLayout { currencyStore: root.currencyStore sendModalPopup: root.sendModalPopup sectionItemModel: root.sectionItemModel + joinedMembersCount: membersModelAdaptor.joinedMembers.ModelCount.count amIMember: sectionItem.amIMember amISectionAdmin: root.sectionItemModel.memberRole === Constants.memberRole.owner || root.sectionItemModel.memberRole === Constants.memberRole.admin || @@ -250,7 +258,11 @@ StackLayout { isPendingOwnershipRequest: root.isPendingOwnershipRequest chatCommunitySectionModule: root.rootStore.chatCommunitySectionModule - community: sectionItemModel + community: root.sectionItemModel + joinedMembers: membersModelAdaptor.joinedMembers + bannedMembers: membersModelAdaptor.bannedMembers + pendingMembers: membersModelAdaptor.pendingMembers + declinedMembers: membersModelAdaptor.declinedMembers communitySettingsDisabled: root.communitySettingsDisabled onCommunitySettingsDisabledChanged: if (communitySettingsDisabled) goTo(Constants.CommunitySettingsSections.Overview) @@ -263,12 +275,11 @@ StackLayout { id: controlNodeOfflineComponent ControlNodeOfflineCommunityView { id: controlNodeOfflineView - readonly property var communityData: sectionItemModel - name: communityData.name - communityDesc: communityData.description - color: communityData.color - image: communityData.image - membersCount: communityData.members.count + name: root.sectionItemModel.name + communityDesc: root.sectionItemModel.description + color: root.sectionItemModel.color + image: root.sectionItemModel.image + membersCount: membersModelAdaptor.joinedMembers.ModelCount.count communityItemsModel: root.rootStore.communityItemsModel notificationCount: activityCenterStore.unreadNotificationsCount hasUnseenNotifications: activityCenterStore.hasUnseenNotifications @@ -282,11 +293,11 @@ StackLayout { BannedMemberCommunityView { id: communityBanView readonly property var communityData: sectionItemModel - name: communityData.name - communityDesc: communityData.description - color: communityData.color - image: communityData.image - membersCount: communityData.members.count + name: root.sectionItemModel.name + communityDesc: root.sectionItemModel.description + color: root.sectionItemModel.color + image: root.sectionItemModel.image + membersCount: membersModelAdaptor.joinedMembers.count communityItemsModel: root.rootStore.communityItemsModel notificationCount: activityCenterStore.unreadNotificationsCount hasUnseenNotifications: activityCenterStore.hasUnseenNotifications diff --git a/ui/app/AppLayouts/Chat/views/ChatView.qml b/ui/app/AppLayouts/Chat/views/ChatView.qml index 6bf897db64..e4681d0e4b 100644 --- a/ui/app/AppLayouts/Chat/views/ChatView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatView.qml @@ -50,6 +50,7 @@ StatusSectionLayout { required property SharedStores.CurrenciesStore currencyStore required property var sendModalPopup property var sectionItemModel + property int joinedMembersCount property var emojiPopup property var stickersPopup @@ -300,7 +301,8 @@ StatusSectionLayout { id: communtiyColumnComponent CommunityColumnView { communitySectionModule: root.rootStore.chatCommunitySectionModule - communityData: sectionItemModel + communityData: root.sectionItemModel + joinedMembersCount: root.joinedMembersCount store: root.rootStore communitiesStore: root.communitiesStore walletAssetsStore: root.walletAssetsStore diff --git a/ui/app/AppLayouts/Chat/views/MembersModelAdaptor.qml b/ui/app/AppLayouts/Chat/views/MembersModelAdaptor.qml new file mode 100644 index 0000000000..67e0333541 --- /dev/null +++ b/ui/app/AppLayouts/Chat/views/MembersModelAdaptor.qml @@ -0,0 +1,113 @@ +import QtQml 2.15 + +import StatusQ 0.1 +import StatusQ.Models 0.1 +import StatusQ.Core.Utils 0.1 + +import utils 1.0 + +import SortFilterProxyModel 0.2 + +QObject { + id: root + + /** + Expected model structure: + + pubKey [string] - unique identifier of a member, e.g "0x3234235" + displayName [string] - member's chosen name + preferredDisplayName [string] - calculated member name according to priorities (eg: nickname has higher priority) + ensName [string] - member's ENS name + isEnsVerified [bool] - whether the ENS name was verified on chain + localNickname [string] - local nickname set by the current user + alias [string] - generated 3 word name + icon [string] - thumbnail image of the user + colorId [string] - generated color ID for the user's profile + colorHash [string] - generated color hash for the user's profile + onlineStatus [int] - the online status of the member + isContact [bool] - whether the user is a mutual contact or not + isVerified [bool] - wheter the user has been marked as verified or not + isUntrustworthy [bool] - wheter the user has been marked as untrustworthy or not + isBlocked [bool] - whether the user has been blocked or not + contactRequest [int] - state of the contact request that was sent + incomingVerificationStatus [int] - state of the verification request that was received + outgoingVerificationStatus [int] - state of the verification request that was send + memberRole [int] - role of the member in the community + joined [bool] - whether the user has joined the community + requestToJoinId [string] - the user's request to join ID + requestToJoinLoading [bool] - whether the request is being processed after an admin made an action (loading state) + airdropAddress [string] - the member's airdrop address (only available to TMs and owners) + membershipRequestState [int] - the user's membership state (pending, joined, etc.) + **/ + property var allMembers + + readonly property var joinedMembers: SortFilterProxyModel { + sourceModel: root.allMembers ?? null + + filters: AnyOf { + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.Accepted + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.KickedPending + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.BannedPending + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.AwaitingAddress + } + } + } + + readonly property var bannedMembers: SortFilterProxyModel { + sourceModel: root.allMembers ?? null + + filters: AnyOf { + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.Banned + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.UnbannedPending + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.BannedWithAllMessagesDelete + } + } + } + + readonly property var pendingMembers: SortFilterProxyModel { + sourceModel: root.allMembers ?? null + + filters: AnyOf { + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.Pending + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.AcceptedPending + } + ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.RejectedPending + } + } + } + + readonly property var declinedMembers: SortFilterProxyModel { + sourceModel: root.allMembers ?? null + + filters: ValueFilter { + roleName: "membershipRequestState" + value: Constants.CommunityMembershipRequestState.Rejected + } + } +} diff --git a/ui/app/AppLayouts/Communities/panels/MembersSettingsPanel.qml b/ui/app/AppLayouts/Communities/panels/MembersSettingsPanel.qml index fbca165f0d..3bb907b4a5 100644 --- a/ui/app/AppLayouts/Communities/panels/MembersSettingsPanel.qml +++ b/ui/app/AppLayouts/Communities/panels/MembersSettingsPanel.qml @@ -1,6 +1,7 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 +import StatusQ 0.1 import StatusQ.Controls 0.1 import utils 1.0 @@ -14,8 +15,8 @@ SettingsPage { property RootStore rootStore property var membersModel property var bannedMembersModel - property var pendingMemberRequestsModel - property var declinedMemberRequestsModel + property var pendingMembersModel + property var declinedMembersModel property string communityName property int memberRole @@ -56,7 +57,7 @@ SettingsPage { break } - if(tabButton.enabled) + if (tabButton.enabled) membersTabBar.currentIndex = tabButton.TabBar.index } @@ -79,7 +80,7 @@ SettingsPage { objectName: "pendingRequestsButton" width: implicitWidth text: qsTr("Pending Requests") - enabled: pendingMemberRequestsModel.count > 0 + enabled: pendingMembersModel.ModelCount.count > 0 } StatusTabButton { @@ -87,14 +88,14 @@ SettingsPage { objectName: "declinedRequestsButton" width: implicitWidth text: qsTr("Rejected") - enabled: declinedMemberRequestsModel.count > 0 + enabled: declinedMembersModel.ModelCount.count > 0 } StatusTabButton { id: bannedBtn objectName: "bannedButton" width: implicitWidth - enabled: bannedMembersModel.count > 0 + enabled: bannedMembersModel.ModelCount.count > 0 text: qsTr("Banned") } } @@ -110,10 +111,10 @@ SettingsPage { rootStore: root.rootStore memberRole: root.memberRole placeholderText: { - if (root.membersModel.count === 0) + if (root.membersModel.ModelCount.count === 0) return qsTr("No members to search") - return qsTr("Search %1's %n member(s)", "", root.membersModel ? root.membersModel.count : 0).arg(root.communityName) + return qsTr("Search %1's %n member(s)", "", root.membersModel ? root.membersModel.ModelCount.count : 0).arg(root.communityName) } panelType: MembersTabPanel.TabType.AllMembers @@ -138,14 +139,14 @@ SettingsPage { } MembersTabPanel { - model: root.pendingMemberRequestsModel + model: root.pendingMembersModel rootStore: root.rootStore memberRole: root.memberRole placeholderText: { - if (root.pendingMemberRequestsModel.count === 0) + if (root.pendingMembersModel.ModelCount.count === 0) return qsTr("No pending requests to search") - return qsTr("Search %1's %n pending request(s)", "", root.pendingMemberRequestsModel.count).arg(root.communityName) + return qsTr("Search %1's %n pending request(s)", "", root.pendingMembersModel.ModelCount.count).arg(root.communityName) } panelType: MembersTabPanel.TabType.PendingRequests @@ -157,14 +158,14 @@ SettingsPage { } MembersTabPanel { - model: root.declinedMemberRequestsModel + model: root.declinedMembersModel rootStore: root.rootStore memberRole: root.memberRole placeholderText: { - if (root.declinedMemberRequestsModel.count === 0) + if (root.declinedMembersModel.ModelCount.count === 0) return qsTr("No rejected members to search") - return qsTr("Search %1's %n rejected member(s)", "", root.declinedMemberRequestsModel.count).arg(root.communityName) + return qsTr("Search %1's %n rejected member(s)", "", root.declinedMembersModel.ModelCount.count).arg(root.communityName) } panelType: MembersTabPanel.TabType.DeclinedRequests @@ -179,10 +180,10 @@ SettingsPage { rootStore: root.rootStore memberRole: root.memberRole placeholderText: { - if (root.bannedMembersModel.count === 0) + if (root.bannedMembersModel.ModelCount.count === 0) return qsTr("No banned members to search") - return qsTr("Search %1's %n banned member(s)", "", root.bannedMembersModel.count).arg(root.communityName) + return qsTr("Search %1's %n banned member(s)", "", root.bannedMembersModel.ModelCount.count).arg(root.communityName) } panelType: MembersTabPanel.TabType.BannedMembers diff --git a/ui/app/AppLayouts/Communities/panels/ProfilePopupInviteFriendsPanel.qml b/ui/app/AppLayouts/Communities/panels/ProfilePopupInviteFriendsPanel.qml index 1db0f33c9e..cd585f5259 100644 --- a/ui/app/AppLayouts/Communities/panels/ProfilePopupInviteFriendsPanel.qml +++ b/ui/app/AppLayouts/Communities/panels/ProfilePopupInviteFriendsPanel.qml @@ -25,7 +25,7 @@ ColumnLayout { property AppLayoutStores.RootStore rootStore property ProfileStores.ContactsStore contactsStore - property var community + property string communityId property var pubKeys: ([]) @@ -58,7 +58,7 @@ ColumnLayout { rootStore: root.rootStore contactsStore: root.contactsStore - communityId: root.community.id + communityId: root.communityId hideCommunityMembers: true showCheckbox: true @@ -90,11 +90,11 @@ ColumnLayout { StatusDescriptionListItem { Layout.fillWidth: true title: qsTr("Share community") - subTitle: Utils.getCommunityShareLink(root.community.id) + subTitle: Utils.getCommunityShareLink(root.communityId) tooltip.text: qsTr("Copied!") asset.name: "copy" iconButton.onClicked: { - let link = Utils.getCommunityShareLink(root.community.id) + let link = Utils.getCommunityShareLink(root.communityId) ClipboardUtils.setText(link) tooltip.visible = !tooltip.visible } diff --git a/ui/app/AppLayouts/Communities/popups/ImportControlNodePopup.qml b/ui/app/AppLayouts/Communities/popups/ImportControlNodePopup.qml index 7da1c3a8c4..a429d3f370 100644 --- a/ui/app/AppLayouts/Communities/popups/ImportControlNodePopup.qml +++ b/ui/app/AppLayouts/Communities/popups/ImportControlNodePopup.qml @@ -17,7 +17,7 @@ StatusDialog { required property var community - signal importControlNode(var community) + signal importControlNode(string communityId) width: 640 @@ -76,7 +76,7 @@ StatusDialog { text: qsTr("Make this device the control node for %1").arg(root.community.name) enabled: agreementCheckBox.checked && agreementCheckBox2.checked onClicked: { - root.importControlNode(root.community) + root.importControlNode(root.community.id) root.close() } } diff --git a/ui/app/AppLayouts/Communities/popups/InviteFriendsToCommunityPopup.qml b/ui/app/AppLayouts/Communities/popups/InviteFriendsToCommunityPopup.qml index 53e564b965..f997c308e0 100644 --- a/ui/app/AppLayouts/Communities/popups/InviteFriendsToCommunityPopup.qml +++ b/ui/app/AppLayouts/Communities/popups/InviteFriendsToCommunityPopup.qml @@ -96,7 +96,7 @@ StatusStackModal { ProfilePopupInviteFriendsPanel { rootStore: root.rootStore contactsStore: root.contactsStore - community: root.community + communityId: root.communityId onPubKeysChanged: root.pubKeys = pubKeys }, diff --git a/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml b/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml index f818a5e232..cd7630ca01 100644 --- a/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml +++ b/ui/app/AppLayouts/Communities/views/CommunityColumnView.qml @@ -44,6 +44,7 @@ Item { required property CurrenciesStore currencyStore property bool hasAddedContacts: false property var communityData + property int joinedMembersCount property alias createChannelPopup: createChannelPopup property int requestToJoinState: Constants.RequestToJoinState.None @@ -79,7 +80,7 @@ Item { anchors.left: parent.left anchors.right: parent.right name: communityData.name - membersCount: communityData.members.count + membersCount: root.joinedMembersCount image: communityData.image color: communityData.color amISectionAdmin: root.isSectionAdmin diff --git a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml index 24951eaecc..a82d5dc8e7 100644 --- a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml +++ b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml @@ -38,7 +38,11 @@ StatusSectionLayout { property ChatStores.RootStore rootStore property var chatCommunitySectionModule required property TokensStore tokensStore - property var community + required property var community + required property var joinedMembers + required property var bannedMembers + required property var pendingMembers + required property var declinedMembers required property TransactionStore transactionStore property bool communitySettingsDisabled property var sendModalPopup @@ -109,7 +113,7 @@ StatusSectionLayout { id: communityHeader title: community.name - subTitle: qsTr("%n member(s)", "", community.members.count || 0) + subTitle: qsTr("%n member(s)", "", root.joinedMembers.ModelCount.count || 0) asset.name: community.image asset.color: community.color asset.isImage: true @@ -291,10 +295,10 @@ StatusSectionLayout { sourceComponent: MembersSettingsPanel { rootStore: root.rootStore - membersModel: root.community.members - bannedMembersModel: root.community.bannedMembers - pendingMemberRequestsModel: root.community.pendingMemberRequests - declinedMemberRequestsModel: root.community.declinedMemberRequests + membersModel: root.joinedMembers + bannedMembersModel: root.bannedMembers + pendingMembersModel: root.pendingMembers + declinedMembersModel: root.declinedMembers editable: root.isAdmin || root.isOwner || root.isTokenMasterOwner memberRole: community.memberRole communityName: root.community.name @@ -392,7 +396,7 @@ StatusSectionLayout { // Models tokensModel: root.community.communityTokens - membersModel: root.community.members + membersModel: root.joinedMembers flatNetworks: communityTokensStore.filteredFlatModel accounts: root.walletAccountsModel referenceAssetsBySymbolModel: root.tokensStore.assetsBySymbolModel @@ -559,7 +563,7 @@ StatusSectionLayout { } } - membersModel: community.members + membersModel: root.joinedMembers enabledChainIds: root.enabledChainIds onEnableNetwork: root.enableNetwork(chainId) diff --git a/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseModelAdapter.qml b/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseModelAdapter.qml index 0354fe5bce..7182924eeb 100644 --- a/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseModelAdapter.qml +++ b/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseModelAdapter.qml @@ -57,15 +57,12 @@ QObject { }, FastExpressionRole { name: "membersCount" - expression: model.members.count - expectedRoles: ["members"] + expression: model.allMembers.rowCount() + expectedRoles: ["allMembers"] }, - FastExpressionRole { + ConstantRole { name: "showcaseVisibility" - expression: getShowcaseVisibility() - function getShowcaseVisibility() { - return Constants.ShowcaseVisibility.Everyone - } + value: Constants.ShowcaseVisibility.Everyone }, FastExpressionRole { name: "isShowcaseLoading" diff --git a/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseSettingsModelAdapter.qml b/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseSettingsModelAdapter.qml index fc9dbf9742..7a0924ddc1 100644 --- a/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseSettingsModelAdapter.qml +++ b/ui/app/AppLayouts/Profile/helpers/ProfileShowcaseSettingsModelAdapter.qml @@ -55,12 +55,12 @@ QObject { }, FastExpressionRole { name: "membersCount" - expression: model.members.count - expectedRoles: ["members"] + expression: model.allMembers.rowCount() + expectedRoles: ["allMembers"] }, - FastExpressionRole { + ConstantRole { name: "isShowcaseLoading" - expression: false + value: false } ] filters: ValueFilter { diff --git a/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml index 9fcc8ae8bd..9c6c6e2187 100644 --- a/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml +++ b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml @@ -79,7 +79,7 @@ QtObject { property var communitiesModuleInst: Global.appIsReady? communitiesModule : null - property var communitiesList: SortFilterProxyModel { + readonly property var communitiesList: SortFilterProxyModel { sourceModel: root.mainModuleInst.sectionsModel filters: ValueFilter { roleName: "sectionType" diff --git a/ui/app/mainui/Popups.qml b/ui/app/mainui/Popups.qml index c6811f09bf..28d0facb27 100644 --- a/ui/app/mainui/Popups.qml +++ b/ui/app/mainui/Popups.qml @@ -963,7 +963,7 @@ QtObject { id: importControlNodePopup ImportControlNodePopup { onClosed: destroy() - onImportControlNode: root.rootStore.promoteSelfToControlNode(community.id) + onImportControlNode: root.rootStore.promoteSelfToControlNode(communityId) } }, diff --git a/ui/imports/shared/views/profile/ProfileShowcaseCommunitiesView.qml b/ui/imports/shared/views/profile/ProfileShowcaseCommunitiesView.qml index a799e70023..e135a3d679 100644 --- a/ui/imports/shared/views/profile/ProfileShowcaseCommunitiesView.qml +++ b/ui/imports/shared/views/profile/ProfileShowcaseCommunitiesView.qml @@ -63,6 +63,8 @@ Item { asset.height: 32 name: model.name ?? "" memberCountVisible: model.joined || !model.encrypted + members: model.membersCount + activeUsers: model.activeMembersCount banner: model.bannerImageData ?? "" descriptionFontSize: 12 descriptionFontColor: Theme.palette.baseColor1 @@ -70,7 +72,7 @@ Item { switch (model.memberRole) { case (Constants.memberRole.owner): return qsTr("Owner"); - case (Constants.memberRole.admin) : + case (Constants.memberRole.admin): return qsTr("Admin"); case (Constants.memberRole.tokenMaster): return qsTr("Token Master"); @@ -108,7 +110,7 @@ Item { StatusBaseText { font.pixelSize: Theme.tertiaryTextFontSize color: Theme.palette.successColor1 - text: qsTr("You’re there too") + text: qsTr("You're there too") } } } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 6b09e30221..94e8e921dc 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -1322,16 +1322,17 @@ QtObject { enum CommunityMembershipRequestState { None = 0, Pending, - Accepted, Rejected, + Accepted, + Canceled, AcceptedPending, RejectedPending, + AwaitingAddress, Banned, Kicked, BannedPending, UnbannedPending, KickedPending, - AwaitingAddress, Unbanned, BannedWithAllMessagesDelete }