feat(@desktop/communities) Permissions - 'is allowed to' dropdown

This commit is contained in:
Michał Cieślak 2022-09-10 00:09:37 +02:00 committed by Michał
parent 34625ad1c4
commit 648c943c53
6 changed files with 316 additions and 3 deletions

View File

@ -53,6 +53,7 @@ ColumnLayout {
// intercepting event by the StatusRadioButton
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: root.ensType = EnsPanel.EnsType.Any
}
}
@ -76,6 +77,7 @@ ColumnLayout {
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: root.ensType = EnsPanel.EnsType.CustomSubdomain
}
}

View File

@ -53,6 +53,9 @@ StatusDropdown {
width: d.defaultWidth
padding: d.padding
// force keeping within the bounds of the enclosing window
margins: 0
onClosed: root.reset()
enum FlowType {

View File

@ -0,0 +1,50 @@
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import QtQuick 2.14
import QtQuick.Controls 2.14
StatusListItem {
id: root
property ButtonGroup buttonGroup
property alias checked: radioButton.checked
readonly property alias radioButton: radioButton
implicitHeight: 44
leftPadding: 8
rightPadding: 9
statusListItemTitle.font.pixelSize: 13
statusListItemTitleArea.anchors.leftMargin: 8
asset.bgWidth: 32
asset.bgHeight: 32
components: [
StatusRadioButton {
id: radioButton
// reference to root for better integration with ButtonGroup
// by accessing main component via ButtonGroup::checkedButton.item
readonly property alias item: root
size: StatusRadioButton.Size.Small
ButtonGroup.group: root.buttonGroup
rightPadding: 0
}
]
// using MouseArea instead of build-in 'clicked' signal to avoid
// intercepting event by the StatusRadioButton
MouseArea {
anchors.fill: parent
onClicked: {
if (!radioButton.checked)
radioButton.toggle()
}
cursorShape: Qt.PointingHandCursor
}
}

View File

@ -0,0 +1,7 @@
import QtQml 2.14
QtObject {
enum Type {
None, Admin, Member, Moderator, ViewAndPost, Read
}
}

View File

@ -0,0 +1,202 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import shared.panels 1.0
StatusDropdown {
id: root
property int mode: PermissionsDropdown.Mode.Add
property int initialPermissionType: PermissionTypes.Type.None
enum Mode {
Add, Update
}
signal done(int permissionType, string title, string asset)
width: d.width
padding: d.padding
// force keeping within the bounds of the enclosing window
margins: 0
onAboutToShow: {
group.checkState = Qt.Unchecked
d.initialPermissionTypeChanged()
}
QtObject {
id: d
// internals
readonly property int initialPermissionType: root.initialPermissionType
// values from design
readonly property int padding: 8
readonly property int width: 289
readonly property int sectionHeight: 34
readonly property int sectionFontSize: 12
readonly property int extraMarginForText: 8
readonly property int separatorTopMargin: 4
readonly property int separatorBottomMargin: 12
readonly property int descriptionFontSize: 13
readonly property int descriptionLineHeight: 18
readonly property int buttonTopMargin: 32
}
ButtonGroup {
id: group
}
contentItem: ColumnLayout {
spacing: 0
Item {
Layout.fillWidth: true
Layout.preferredHeight: d.sectionHeight
StatusBaseText {
anchors.margins: d.extraMarginForText
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Community")
color: Theme.palette.baseColor1
font.pixelSize: d.sectionFontSize
elide: Text.ElideRight
}
}
PermissionListItem {
readonly property int permissionType: PermissionTypes.Type.Admin
readonly property string description: {
const generalInfo = qsTr("Members who meet the requirements will be allowed to create and edit permissions, token sales, airdrops and subscriptions")
const warning = qsTr("Be careful with assigning this permission.")
const warningExplanation = qsTr("Only the community owner can modify admin permissions")
const warningStyled = `<font color="${Theme.palette.dangerColor1}">${warning}</font>`
return `${generalInfo}<br><br>${warningStyled} ${warningExplanation}`
}
title: qsTr("Become admin")
asset.name: "admin"
checked: d.initialPermissionType === permissionType
buttonGroup: group
Layout.fillWidth: true
}
PermissionListItem {
readonly property int permissionType: PermissionTypes.Type.Member
readonly property string description:
qsTr("Anyone who meets the requirements will be allowed to join your community")
title: qsTr("Become member")
asset.name: "in-contacts"
checked: d.initialPermissionType === permissionType
buttonGroup: group
Layout.fillWidth: true
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: d.sectionHeight
StatusBaseText {
anchors.margins: d.extraMarginForText
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Channels")
color: Theme.palette.baseColor1
font.pixelSize: d.sectionFontSize
elide: Text.ElideRight
}
}
PermissionListItem {
readonly property int permissionType: PermissionTypes.Type.Moderator
readonly property string description:
qsTr("Members who meet the requirements will be allowed to read, write, ban members and pin messages in the selected channels")
title: qsTr("Moderate")
asset.name: "arbitrator"
checked: d.initialPermissionType === permissionType
buttonGroup: group
Layout.fillWidth: true
}
PermissionListItem {
readonly property int permissionType: PermissionTypes.Type.ViewAndPost
readonly property string description:
qsTr("Members who meet the requirements will be allowed to read and write in the selected channels")
title: qsTr("View and post")
asset.name: "edit"
checked: d.initialPermissionType === permissionType
buttonGroup: group
Layout.fillWidth: true
}
PermissionListItem {
readonly property int permissionType: PermissionTypes.Type.Read
readonly property string description:
qsTr("Members who meet the requirements will be allowed to read the selected channels")
title: qsTr("Read")
asset.name: "show"
checked: d.initialPermissionType === permissionType
buttonGroup: group
Layout.fillWidth: true
}
Separator {
visible: !!group.checkedButton
Layout.fillWidth: true
Layout.topMargin: d.separatorTopMargin
Layout.bottomMargin: d.separatorBottomMargin
}
StatusBaseText {
Layout.fillWidth: true
Layout.leftMargin: d.extraMarginForText
visible: !!group.checkedButton
text: group.checkedButton ? group.checkedButton.item.description : ""
textFormat: Text.StyledText
wrapMode: Text.Wrap
color: Theme.palette.baseColor1
font.pixelSize: d.descriptionFontSize
lineHeight: d.descriptionLineHeight
lineHeightMode: Text.FixedHeight
}
StatusButton {
Layout.fillWidth: true
Layout.topMargin: d.buttonTopMargin
text: root.mode === PermissionsDropdown.Mode.Add ? qsTr("Add") : qsTr("Update")
enabled: !!group.checkedButton
onClicked: root.done(group.checkedButton.item.permissionType,
group.checkedButton.item.title,
group.checkedButton.item.asset.name)
}
}
}

View File

@ -32,6 +32,7 @@ Flickable {
id: d
property bool isPrivate: false
property ListModel permissions: ListModel{}
property int permissionType: PermissionTypes.Type.None
}
contentWidth: mainLayout.width
@ -116,7 +117,7 @@ Flickable {
onAddEns: {
const key = any ? "EnsAny" : "EnsCustom"
const name = any ? "" : customDomain
const icon = "qrc:imports/assets/icons/profile/ensUsernames.svg"
const icon = Style.svg("ensUsernames")
holdingsModel.append({type: HoldingTypes.Type.Ens, key, name, amount: 1, imageSource: icon, operator })
d.permissions.append([{ key }, { operator }])
@ -144,7 +145,7 @@ Flickable {
onUpdateEns: {
const key = any ? "EnsAny" : "EnsCustom"
const name = any ? "" : customDomain
const icon = "qrc:imports/assets/icons/profile/ensUsernames.svg"
const icon = Style.svg("ensUsernames")
holdingsModel.set(tokensSelector.editedIndex, { type: HoldingTypes.Type.Ens, key, name: name, amount: 1, imageSource: icon })
dropdown.close()
@ -166,7 +167,7 @@ Flickable {
dropdown.x = tokensSelector.addButton.width + 4
dropdown.y = 0
if (tokensSelector.itemsModel.count === 0)
if (holdingsModel.count === 0)
dropdown.openFlow(HoldingsDropdown.FlowType.Add)
else
dropdown.openFlow(HoldingsDropdown.FlowType.AddWithOperators)
@ -214,11 +215,59 @@ Flickable {
color: Style.current.separator
}
StatusItemSelector {
id: permissionsSelector
Layout.fillWidth: true
icon: Style.svg("profile/security")
iconSize: 24
useIcons: true
title: qsTr("Is allowed to")
defaultItemText: qsTr("Example: View and post")
Binding on itemsModel {
when: d.permissionType !== PermissionTypes.Type.None
value: QtObject {
id: permissionsListObjectModel
readonly property int operator: SQ.Utils.Operators.None
property string text: ""
property string imageSource: ""
}
}
addButton.visible: d.permissionType === PermissionTypes.Type.None
PermissionsDropdown {
id: permissionsDropdown
initialPermissionType: d.permissionType
onDone: {
d.permissionType = permissionType
permissionsListObjectModel.text = title
permissionsListObjectModel.imageSource = asset
permissionsDropdown.close()
}
}
addButton.onClicked: {
permissionsDropdown.mode = PermissionsDropdown.Mode.Add
permissionsDropdown.parent = permissionsSelector.addButton
permissionsDropdown.x = permissionsSelector.addButton.width + 4
permissionsDropdown.y = 0
permissionsDropdown.open()
}
onItemClicked: {
if (mouse.button !== Qt.LeftButton)
return
permissionsDropdown.mode = PermissionsDropdown.Mode.Update
permissionsDropdown.parent = item
permissionsDropdown.x = mouse.x + 4
permissionsDropdown.y = 1
permissionsDropdown.open()
}
}
Rectangle {
Layout.leftMargin: 16