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 2.15
import QtQuick.Controls 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 AppLayouts.Communities.panels 1.0
import utils 1.0
import Models 1.0 import Models 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import Storybook 1.0
SplitView { SplitView {
id: root id: root
orientation: Qt.Vertical
Logs { id: logs }
MembersTabPanel { MembersTabPanel {
id: membersTabPanelPage id: membersTabPanelPage
SplitView.fillWidth: true
SplitView.fillHeight: true
placeholderText: "Placeholder text" placeholderText: "Placeholder text"
model: usersModelWithMembershipState 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 { UsersModel {
id: usersModel id: usersModel
} }
SortFilterProxyModel { SortFilterProxyModel {
id: usersModelWithMembershipState 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 sourceModel: usersModel
sortRole: membersTabPanelPage.panelType
proxyRoles: [ proxyRoles: [
ExpressionRole { ExpressionRole {
name: "membershipRequestState" name: "membershipRequestState"
expression: usersModelWithMembershipState.acceptedStates[model.index % (usersModelWithMembershipState.acceptedStates.length)] expression: {
var memberStates = usersModelWithMembershipState.membershipStatePerView[membersTabPanelPage.panelType]
return memberStates[model.index % (memberStates.length)]
}
}, },
ExpressionRole { ExpressionRole {
name: "requestToJoinLoading" 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} 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} 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_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} communitySettings_KickModal_Kick_Button = {"container": statusDesktop_mainWindow_overlay, "objectName": "CommunityMembers_KickModal_KickButton", "type": "StatusButton", "visible": True}
# Chat components # Chat components

View File

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