feat(community): Add Pending states to community membership request decisions in members tab panel
This commit is contained in:
parent
e9a2b183c7
commit
7d0d321b35
|
@ -121,7 +121,7 @@ method curatedCommunitiesLoadingFailed*(self: Module) =
|
|||
self.curatedCommunitiesLoaded = true
|
||||
self.view.setCuratedCommunitiesLoading(false)
|
||||
|
||||
proc createMemberItem(self: Module, memberId, requestId: string): MemberItem =
|
||||
proc createMemberItem(self: Module, memberId, requestId: string, status: MembershipRequestState): MemberItem =
|
||||
let contactDetails = self.controller.getContactDetails(memberId)
|
||||
result = initMemberItem(
|
||||
pubKey = memberId,
|
||||
|
@ -137,6 +137,7 @@ proc createMemberItem(self: Module, memberId, requestId: string): MemberItem =
|
|||
isContact = contactDetails.dto.isContact,
|
||||
isVerified = contactDetails.dto.isContactVerified(),
|
||||
requestToJoinId = requestId,
|
||||
membershipRequestState = status,
|
||||
)
|
||||
|
||||
method getCommunityItem(self: Module, c: CommunityDto): SectionItem =
|
||||
|
@ -168,14 +169,14 @@ method getCommunityItem(self: Module, c: CommunityDto): SectionItem =
|
|||
c.permissions.ensOnly,
|
||||
c.muted,
|
||||
c.members.map(proc(member: ChatMember): MemberItem =
|
||||
result = self.createMemberItem(member.id, "")),
|
||||
result = self.createMemberItem(member.id, "", MembershipRequestState.Accepted)),
|
||||
historyArchiveSupportEnabled = c.settings.historyArchiveSupportEnabled,
|
||||
bannedMembers = c.bannedMembersIds.map(proc(bannedMemberId: string): MemberItem =
|
||||
result = self.createMemberItem(bannedMemberId, "")),
|
||||
result = self.createMemberItem(bannedMemberId, "", MembershipRequestState.Banned)),
|
||||
pendingMemberRequests = c.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem =
|
||||
result = self.createMemberItem(requestDto.publicKey, requestDto.id)),
|
||||
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)),
|
||||
result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state))),
|
||||
encrypted = c.encrypted,
|
||||
communityTokens = @[]
|
||||
)
|
||||
|
|
|
@ -313,6 +313,7 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
isVerified = contactDetails.dto.isContactVerified(),
|
||||
memberRole = member.role,
|
||||
airdropAddress = member.airdropAccount.address,
|
||||
membershipRequestState = MembershipRequestState.Accepted
|
||||
)),
|
||||
# pendingRequestsToJoin
|
||||
if (isCommunity): communityDetails.pendingRequestsToJoin.map(x => pending_request_item.initItem(
|
||||
|
@ -341,6 +342,7 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
onlineStatus = toOnlineStatus(self.controller.getStatusForContactWithId(bannedMemberId).statusType),
|
||||
isContact = contactDetails.dto.isContact,
|
||||
isVerified = contactDetails.dto.isContactVerified(),
|
||||
membershipRequestState = MembershipRequestState.Banned,
|
||||
)
|
||||
),
|
||||
# pendingMemberRequests
|
||||
|
@ -360,6 +362,7 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
isContact = contactDetails.dto.isContact,
|
||||
isVerified = contactDetails.dto.isContactVerified(),
|
||||
requestToJoinId = requestDto.id,
|
||||
membershipRequestState = MembershipRequestState(requestDto.state),
|
||||
)
|
||||
) else: @[],
|
||||
# declinedMemberRequests
|
||||
|
@ -379,6 +382,7 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
isContact = contactDetails.dto.isContact,
|
||||
isVerified = contactDetails.dto.isContactVerified(),
|
||||
requestToJoinId = requestDto.id,
|
||||
membershipRequestState = MembershipRequestState(requestDto.state),
|
||||
)
|
||||
) else: @[],
|
||||
channelGroup.encrypted,
|
||||
|
|
|
@ -12,6 +12,7 @@ type
|
|||
requestToJoinId: string
|
||||
requestToJoinLoading*: bool
|
||||
airdropAddress*: string
|
||||
membershipRequestState: MembershipRequestState
|
||||
|
||||
# FIXME: remove defaults
|
||||
proc initMemberItem*(
|
||||
|
@ -37,6 +38,7 @@ proc initMemberItem*(
|
|||
requestToJoinId: string = "",
|
||||
requestToJoinLoading: bool = false,
|
||||
airdropAddress: string = "",
|
||||
membershipRequestState: MembershipRequestState = MembershipRequestState.None
|
||||
): MemberItem =
|
||||
result = MemberItem()
|
||||
result.memberRole = memberRole
|
||||
|
@ -44,6 +46,7 @@ proc initMemberItem*(
|
|||
result.requestToJoinId = requestToJoinId
|
||||
result.requestToJoinLoading = requestToJoinLoading
|
||||
result.airdropAddress = airdropAddress
|
||||
result.membershipRequestState = membershipRequestState
|
||||
result.UserItem.setup(
|
||||
pubKey = pubKey,
|
||||
displayName = displayName,
|
||||
|
@ -86,7 +89,8 @@ proc `$`*(self: MemberItem): string =
|
|||
outgoingVerificationStatus: {$self.outgoingVerificationStatus.int},
|
||||
memberRole: {self.memberRole},
|
||||
joined: {self.joined},
|
||||
requestToJoinId: {self.requestToJoinId}
|
||||
requestToJoinId: {self.requestToJoinId},
|
||||
membershipRequestState: {$self.membershipRequestState.int}
|
||||
]"""
|
||||
|
||||
proc memberRole*(self: MemberItem): MemberRole {.inline.} =
|
||||
|
@ -112,3 +116,6 @@ proc requestToJoinLoading*(self: MemberItem): bool {.inline.} =
|
|||
|
||||
proc airdropAddress*(self: MemberItem): string {.inline.} =
|
||||
self.airdropAddress
|
||||
|
||||
proc membershipRequestState*(self: MemberItem): MembershipRequestState {.inline.} =
|
||||
self.membershipRequestState
|
|
@ -30,6 +30,7 @@ type
|
|||
RequestToJoinId
|
||||
RequestToJoinLoading
|
||||
AirdropAddress
|
||||
MembershipRequestState
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -98,6 +99,7 @@ QtObject:
|
|||
ModelRole.RequestToJoinId.int: "requestToJoinId",
|
||||
ModelRole.RequestToJoinLoading.int: "requestToJoinLoading",
|
||||
ModelRole.AirdropAddress.int: "airdropAddress",
|
||||
ModelRole.MembershipRequestState.int: "membershipRequestState"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -155,6 +157,8 @@ QtObject:
|
|||
result = newQVariant(item.requestToJoinLoading)
|
||||
of ModelRole.AirdropAddress:
|
||||
result = newQVariant(item.airdropAddress)
|
||||
of ModelRole.MembershipRequestState:
|
||||
result = newQVariant(item.membershipRequestState.int)
|
||||
|
||||
proc addItem*(self: Model, item: MemberItem) =
|
||||
self.beginInsertRows(newQModelIndex(), self.items.len, self.items.len)
|
||||
|
|
|
@ -54,6 +54,18 @@ type MemberRole* {.pure} = enum
|
|||
ModerateContent
|
||||
Admin
|
||||
|
||||
type MembershipRequestState* {.pure} = enum
|
||||
None = 0,
|
||||
Pending = 1,
|
||||
Accepted = 2,
|
||||
Declined = 3,
|
||||
AcceptedPending = 4,
|
||||
DeclinedPending = 5,
|
||||
Banned = 6,
|
||||
Kicked = 7,
|
||||
BannedPending = 8,
|
||||
KickedPending = 9
|
||||
|
||||
type
|
||||
ContractTransactionStatus* {.pure.} = enum
|
||||
Failed,
|
||||
|
|
|
@ -142,6 +142,9 @@
|
|||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=22647-498410",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=22642-497015"
|
||||
],
|
||||
"MembersTabPanel": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=35909-605774&mode=design&t=KfrAekLfW5mTy68x-0"
|
||||
],
|
||||
"MintTokensSettingsPanel": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=22721%3A498587&t=v2Krj5iZQaSTK7Om-1",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2934%3A480877&t=v2Krj5iZQaSTK7Om-1",
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import AppLayouts.Communities.panels 1.0
|
||||
|
||||
import Models 1.0
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
MembersTabPanel {
|
||||
id: membersTabPanelPage
|
||||
placeholderText: "Placeholder text"
|
||||
model: usersModelWithMembershipState
|
||||
panelType: MembersTabPanel.TabType.PendingRequests
|
||||
}
|
||||
|
||||
UsersModel {
|
||||
id: usersModel
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: usersModelWithMembershipState
|
||||
readonly property var acceptedStates: [0, 3, 4]
|
||||
sourceModel: usersModel
|
||||
|
||||
proxyRoles: [
|
||||
ExpressionRole {
|
||||
name: "membershipRequestState"
|
||||
expression: usersModelWithMembershipState.acceptedStates[model.index % (usersModelWithMembershipState.acceptedStates.length)]
|
||||
},
|
||||
ExpressionRole {
|
||||
name: "requestToJoinLoading"
|
||||
expression: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import StatusQ.Popups 0.1
|
|||
import utils 1.0
|
||||
import shared.views.chat 1.0
|
||||
import shared.controls.chat 1.0
|
||||
import shared.controls 1.0
|
||||
|
||||
import AppLayouts.Communities.layouts 1.0
|
||||
|
||||
|
@ -102,28 +103,46 @@ Item {
|
|||
onClicked: root.unbanUserClicked(model.pubKey)
|
||||
},
|
||||
|
||||
StatusButton {
|
||||
visible: (root.panelType === MembersTabPanel.TabType.PendingRequests) && isHovered
|
||||
text: qsTr("Reject")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
icon.name: "close-circle"
|
||||
icon.color: Style.current.danger
|
||||
onClicked: root.declineRequestToJoin(model.requestToJoinId)
|
||||
},
|
||||
DisabledTooltipButton {
|
||||
id: acceptButton
|
||||
visible: ((root.panelType === MembersTabPanel.TabType.PendingRequests ||
|
||||
root.panelType === MembersTabPanel.TabType.DeclinedRequests) && isHovered) ||
|
||||
model.membershipRequestState === Constants.CommunityMembershipRequestState.AcceptedPending
|
||||
//TODO: Only the current user can reject a pending request, so we should check that here
|
||||
|
||||
StatusButton {
|
||||
visible: (root.panelType === MembersTabPanel.TabType.PendingRequests ||
|
||||
root.panelType === MembersTabPanel.TabType.DeclinedRequests) && isHovered
|
||||
text: qsTr("Accept")
|
||||
tooltipText: qsTr("Waiting for owner node to come online")
|
||||
interactive: model.membershipRequestState !== Constants.CommunityMembershipRequestState.AcceptedPending
|
||||
buttonComponent: StatusButton {
|
||||
text: model.membershipRequestState == Constants.CommunityMembershipRequestState.AcceptedPending ? qsTr("Accept pending") : qsTr("Accept")
|
||||
icon.name: "checkmark-circle"
|
||||
icon.color: Theme.palette.successColor1
|
||||
icon.color: enabled ? Theme.palette.successColor1 : disabledTextColor
|
||||
normalColor: Theme.palette.successColor2
|
||||
hoverColor: Theme.palette.successColor3
|
||||
textColor: Theme.palette.successColor1
|
||||
loading: model.requestToJoinLoading
|
||||
enabled: acceptButton.interactive
|
||||
onClicked: root.acceptRequestToJoin(model.requestToJoinId)
|
||||
}
|
||||
},
|
||||
|
||||
DisabledTooltipButton {
|
||||
id: rejectButton
|
||||
//using opacity instead of visible to avoid the acceptButton jumping around
|
||||
opacity: ((root.panelType === MembersTabPanel.TabType.PendingRequests) && isHovered) ||
|
||||
model.membershipRequestState === Constants.CommunityMembershipRequestState.RejectedPending
|
||||
//TODO: Only the current user can reject a pending request, so we should check that here
|
||||
|
||||
tooltipText: qsTr("Waiting for owner node to come online")
|
||||
interactive: model.membershipRequestState !== Constants.CommunityMembershipRequestState.RejectedPending
|
||||
buttonComponent: StatusButton {
|
||||
text: model.membershipRequestState == Constants.CommunityMembershipRequestState.RejectedPending ? qsTr("Reject pending") : qsTr("Reject")
|
||||
type: StatusBaseButton.Type.Danger
|
||||
icon.name: "close-circle"
|
||||
icon.color: enabled ? Style.current.danger : disabledTextColor
|
||||
enabled: rejectButton.interactive
|
||||
onClicked: root.declineRequestToJoin(model.requestToJoinId)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
width: membersList.width
|
||||
|
|
|
@ -14,6 +14,7 @@ JoinCommunityCenterPanel 1.0 JoinCommunityCenterPanel.qml
|
|||
JoinCommunityHeaderPanel 1.0 JoinCommunityHeaderPanel.qml
|
||||
JoinPermissionsOverlayPanel 1.0 JoinPermissionsOverlayPanel.qml
|
||||
MembersSettingsPanel 1.0 MembersSettingsPanel.qml
|
||||
MembersTabPanel 1.0 MembersTabPanel.qml
|
||||
MintTokensFooterPanel 1.0 MintTokensFooterPanel.qml
|
||||
MintTokensSettingsPanel 1.0 MintTokensSettingsPanel.qml
|
||||
OverviewSettingsChart 1.0 OverviewSettingsChart.qml
|
||||
|
|
|
@ -9,16 +9,20 @@ import StatusQ.Components 0.1
|
|||
import utils 1.0
|
||||
import shared.panels 1.0
|
||||
|
||||
import "../stores"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property bool pending: false
|
||||
property bool accepted: false
|
||||
property bool declined: false
|
||||
property bool acceptedPending: false
|
||||
property bool declinedPending: false
|
||||
property int membershipStatus: ActivityCenterStore.ActivityCenterMembershipStatus.None
|
||||
property bool ctaAllowed: true
|
||||
|
||||
readonly property bool pending: membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Pending
|
||||
readonly property bool accepted: membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Accepted
|
||||
readonly property bool declined: membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Declined
|
||||
readonly property bool acceptedPending: membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.AcceptedPending
|
||||
readonly property bool declinedPending: membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.DeclinedPending
|
||||
|
||||
signal acceptRequestToJoinCommunity()
|
||||
signal declineRequestToJoinCommunity()
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ QtObject {
|
|||
}
|
||||
|
||||
enum ActivityCenterMembershipStatus {
|
||||
None = 0,
|
||||
Pending = 1,
|
||||
Accepted = 2,
|
||||
Declined = 3,
|
||||
|
|
|
@ -43,11 +43,7 @@ ActivityNotificationMessage {
|
|||
}
|
||||
|
||||
ctaComponent: MembershipCta {
|
||||
pending: notification && notification.membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Pending
|
||||
accepted: notification && notification.membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Accepted
|
||||
declined: notification && notification.membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.Declined
|
||||
acceptedPending: notification && notification.membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.AcceptedPending
|
||||
declinedPending: notification && notification.membershipStatus === ActivityCenterStore.ActivityCenterMembershipStatus.DeclinedPending
|
||||
membershipStatus: notification && notification.membershipStatus ? notification.membershipStatus : ActivityNotification.MembershipStatus.None
|
||||
onAcceptRequestToJoinCommunity: root.store.acceptRequestToJoinCommunity(notification.id, notification.communityId)
|
||||
onDeclineRequestToJoinCommunity: root.store.declineRequestToJoinCommunity(notification.id, notification.communityId)
|
||||
//TODO: Get backend value. If the membersip is in acceptedPending or declinedPending state, another user can't accept or decline the request
|
||||
|
|
|
@ -10,6 +10,8 @@ Item {
|
|||
property alias tooltipText: tooltip.text
|
||||
property int buttonType: DisabledTooltipButton.Normal
|
||||
property bool interactive: true
|
||||
property Component buttonComponent: buttonType === DisabledTooltipButton.Normal ? normalButton : flatButton
|
||||
|
||||
signal clicked()
|
||||
|
||||
enum Type {
|
||||
|
@ -23,7 +25,7 @@ Item {
|
|||
Loader {
|
||||
id: buttonLoader
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: buttonType === DisabledTooltipButton.Normal ? normalButton : flatButton
|
||||
sourceComponent: buttonComponent
|
||||
active: root.visible
|
||||
}
|
||||
HoverHandler {
|
||||
|
|
|
@ -1115,6 +1115,19 @@ QtObject {
|
|||
BannedMembers
|
||||
}
|
||||
|
||||
enum CommunityMembershipRequestState {
|
||||
None = 0,
|
||||
Pending,
|
||||
Accepted,
|
||||
Rejected,
|
||||
AcceptedPending,
|
||||
RejectedPending,
|
||||
Banned,
|
||||
Kicked,
|
||||
BannedPending,
|
||||
KickedPending
|
||||
}
|
||||
|
||||
readonly property QtObject walletAccountColors: QtObject {
|
||||
readonly property string primary: "primary"
|
||||
readonly property string purple: "purple"
|
||||
|
|
Loading…
Reference in New Issue