feat: Add Ban/Kick Pending state in the Community members settings.

This commit is contained in:
Alex Jbanca 2023-08-08 11:41:59 +03:00 committed by Alex Jbanca
parent 49ec6962b1
commit 7d4df690c5
3 changed files with 124 additions and 27 deletions

View File

@ -1,34 +1,76 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Qt.labs.settings 1.0
import AppLayouts.Communities.panels 1.0
import utils 1.0
import Models 1.0
import SortFilterProxyModel 0.2
import Storybook 1.0
SplitView {
id: root
orientation: Qt.Vertical
Logs { id: logs }
MembersTabPanel {
id: membersTabPanelPage
SplitView.fillWidth: true
SplitView.fillHeight: true
placeholderText: "Placeholder text"
model: usersModelWithMembershipState
panelType: MembersTabPanel.TabType.PendingRequests
panelType: viewStateSelector.currentValue
onKickUserClicked: {
logs.logEvent("MembersTabPanel::onKickUserClicked")
}
onBanUserClicked: {
logs.logEvent("MembersTabPanel::onBanUserClicked")
}
onUnbanUserClicked: {
logs.logEvent("MembersTabPanel::onUnbanUserClicked")
}
onAcceptRequestToJoin: {
logs.logEvent("MembersTabPanel::onAcceptRequestToJoin")
}
onDeclineRequestToJoin: {
logs.logEvent("MembersTabPanel::onDeclineRequestToJoin")
}
}
UsersModel {
id: usersModel
}
SortFilterProxyModel {
id: usersModelWithMembershipState
readonly property var acceptedStates: [0, 3, 4]
readonly property var membershipStatePerView: [
[Constants.CommunityMembershipRequestState.Accepted , Constants.CommunityMembershipRequestState.BannedPending, Constants.CommunityMembershipRequestState.KickedPending],
[Constants.CommunityMembershipRequestState.Banned],
[Constants.CommunityMembershipRequestState.Pending, Constants.CommunityMembershipRequestState.AcceptedPending, Constants.CommunityMembershipRequestState.RejectedPending],
[Constants.CommunityMembershipRequestState.Rejected]
]
sourceModel: usersModel
sortRole: membersTabPanelPage.panelType
proxyRoles: [
ExpressionRole {
name: "membershipRequestState"
expression: usersModelWithMembershipState.acceptedStates[model.index % (usersModelWithMembershipState.acceptedStates.length)]
expression: {
var memberStates = usersModelWithMembershipState.membershipStatePerView[membersTabPanelPage.panelType]
return memberStates[model.index % (memberStates.length)]
}
},
ExpressionRole {
name: "requestToJoinLoading"
@ -36,4 +78,38 @@ SplitView {
}
]
}
LogsAndControlsPanel {
SplitView.minimumHeight: 100
SplitView.preferredHeight: 320
logsView.logText: logs.logText
ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
Label {
text: "View state"
}
ComboBox {
id: viewStateSelector
textRole: "text"
valueRole: "value"
model: ListModel {
id: model
ListElement { text: "All members"; value: MembersTabPanel.TabType.AllMembers }
ListElement { text: "Banned Members"; value: MembersTabPanel.TabType.BannedMembers }
ListElement { text: "Pending Members"; value: MembersTabPanel.TabType.PendingRequests }
ListElement { text: "Declined Members"; value: MembersTabPanel.TabType.DeclinedRequests }
}
}
}
}
Settings {
property alias membersTabPanelSelection: viewStateSelector.currentIndex
}
}

View File

@ -31,7 +31,7 @@ communitySettingsView_NavigationListItem_Mint_Tokens = {"container": statusDeskt
communitySettings_Permissions_NavigationListItem = {"container": statusDesktop_mainWindow, "objectName": "CommunitySettingsView_NavigationListItem_Permissions", "type": "StatusNavigationListItem", "visible": True}
communitySettingsView_NavigationListItem_Overview = {"container": statusDesktop_mainWindow, "objectName": "CommunitySettingsView_NavigationListItem_Overview", "type": "StatusNavigationListItem", "visible": True}
communitySettings_MembersTab_Members_ListView = {"container": statusDesktop_mainWindow, "objectName": "CommunityMembersTabPanel_MembersListViews", "type": "ListView", "visible": True}
communitySettings_MembersTab_Member_Kick_Button = {"container": communitySettings_MembersTab_Members_ListView, "objectName": "MemberListIten_KickButton", "type": "StatusButton", "visible": True}
communitySettings_MembersTab_Member_Kick_Button = {"container": communitySettings_MembersTab_Members_ListView, "objectName": "MemberListItem_KickButton", "type": "StatusButton", "visible": True}
communitySettings_KickModal_Kick_Button = {"container": statusDesktop_mainWindow_overlay, "objectName": "CommunityMembers_KickModal_KickButton", "type": "StatusButton", "visible": True}
# Chat components

View File

@ -72,6 +72,15 @@ Item {
readonly property bool itsMe: model.pubKey.toLowerCase() === userProfile.pubKey.toLowerCase()
readonly property bool isHovered: memberItem.sensor.containsMouse
readonly property bool canBeBanned: !memberItem.itsMe && (model.memberRole !== Constants.memberRole.owner && model.memberRole !== Constants.memberRole.admin)
readonly property bool canEnableKickBanButtons: canBeBanned && root.panelType === MembersTabPanel.TabType.AllMembers
readonly property bool kickEnabled: canEnableKickBanButtons && model.membershipRequestState !== Constants.CommunityMembershipRequestState.KickedPending
readonly property bool banEnabled: canEnableKickBanButtons && model.membershipRequestState !== Constants.CommunityMembershipRequestState.BannedPending
readonly property bool kickVisible: (isHovered || !kickEnabled) && banEnabled
readonly property bool banVisible: (isHovered || !banEnabled) && kickEnabled
readonly property bool unBanVisible: (root.panelType === MembersTabPanel.TabType.BannedMembers) && isHovered && canBeBanned
readonly property bool isRejectedPending: model.membershipRequestState === Constants.CommunityMembershipRequestState.RejectedPending
readonly property bool isAcceptedPending: model.membershipRequestState === Constants.CommunityMembershipRequestState.AcceptedPending
statusListItemComponentsSlot.spacing: 16
statusListItemTitleArea.anchors.rightMargin: 0
@ -80,25 +89,38 @@ Item {
leftPadding: 12
components: [
StatusButton {
objectName: "MemberListIten_KickButton"
visible: (root.panelType === MembersTabPanel.TabType.AllMembers) && isHovered && canBeBanned
text: qsTr("Kick")
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
onClicked: root.kickUserClicked(model.pubKey, model.displayName)
DisabledTooltipButton {
id: kickButton
visible: kickVisible
interactive: kickEnabled
tooltipText: qsTr("Waiting for owner node to come online")
buttonComponent: StatusButton {
objectName: "MemberListItem_KickButton"
text: model.membershipRequestState === Constants.CommunityMembershipRequestState.KickedPending ? qsTr("Kick pending") : qsTr("Kick")
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
onClicked: root.kickUserClicked(model.pubKey, model.displayName)
enabled: kickButton.interactive
}
},
DisabledTooltipButton {
id: banButton
//using opacity instead of visible to avoid the acceptButton jumping around
opacity: banVisible
interactive: banEnabled
tooltipText: qsTr("Waiting for owner node to come online")
buttonComponent: StatusButton {
text: model.membershipRequestState === Constants.CommunityMembershipRequestState.BannedPending || !banVisible ? qsTr("Ban pending") : qsTr("Ban")
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
onClicked: root.banUserClicked(model.pubKey, model.displayName)
enabled: banButton.interactive
}
},
StatusButton {
visible: (root.panelType === MembersTabPanel.TabType.AllMembers) && isHovered && canBeBanned
text: qsTr("Ban")
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
onClicked: root.banUserClicked(model.pubKey, model.displayName)
},
StatusButton {
visible: (root.panelType === MembersTabPanel.TabType.BannedMembers) && isHovered && canBeBanned
visible: unBanVisible
text: qsTr("Unban")
onClicked: root.unbanUserClicked(model.pubKey)
},
@ -107,13 +129,13 @@ Item {
id: acceptButton
visible: ((root.panelType === MembersTabPanel.TabType.PendingRequests ||
root.panelType === MembersTabPanel.TabType.DeclinedRequests) && isHovered) ||
model.membershipRequestState === Constants.CommunityMembershipRequestState.AcceptedPending
isAcceptedPending
//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.AcceptedPending
interactive: !isAcceptedPending
buttonComponent: StatusButton {
text: model.membershipRequestState == Constants.CommunityMembershipRequestState.AcceptedPending ? qsTr("Accept pending") : qsTr("Accept")
text: isAcceptedPending ? qsTr("Accept Pending") : qsTr("Accept")
icon.name: "checkmark-circle"
icon.color: enabled ? Theme.palette.successColor1 : disabledTextColor
normalColor: Theme.palette.successColor2
@ -128,14 +150,13 @@ Item {
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
opacity: ((root.panelType === MembersTabPanel.TabType.PendingRequests) && isHovered) || isRejectedPending
//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
interactive: !isRejectedPending
buttonComponent: StatusButton {
text: model.membershipRequestState == Constants.CommunityMembershipRequestState.RejectedPending ? qsTr("Reject pending") : qsTr("Reject")
text: isRejectedPending ? qsTr("Reject pending") : qsTr("Reject")
type: StatusBaseButton.Type.Danger
icon.name: "close-circle"
icon.color: enabled ? Style.current.danger : disabledTextColor