status-desktop/ui/app/AppLayouts/Chat/controls/community/MembersDropdown.qml

269 lines
6.9 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Utils 0.1
import shared.controls 1.0
import shared.controls.delegates 1.0
StatusDropdown {
id: root
property var selectedKeys: new Set()
property bool forceButtonDisabled: false
property int maximumListHeight: 288
property alias model: listView.model
readonly property alias count: listView.count
readonly property alias searchText: filterInput.text
enum Mode {
Add, Update
}
Instantiator {
id: selectionChecker
model: root.model
property var keys: []
delegate: QtObject {
readonly property string key: model.pubKey
}
readonly property bool allSelected:
keys.every(key => root.selectedKeys.has(key))
onObjectAdded: {
const keysCopy = [...keys]
keysCopy.splice(index, 0, object.key)
keys = keysCopy
}
onObjectRemoved: {
const keysCopy = [...keys]
keysCopy.splice(index, 1)
keys = keysCopy
}
}
property int mode: MembersDropdown.Mode.Add
signal backButtonClicked
signal addButtonClicked
width: 295
padding: 11
bottomInset: 10
bottomPadding: padding + bottomInset
onOpened: {
listView.positionViewAtBeginning()
filterInput.text = ""
}
QtObject {
id: d
readonly property int sectionDelegateHeight: 40
readonly property int delegateHeight: 47
readonly property int scrollBarWidth: 4
}
contentItem: ColumnLayout {
id: content
spacing: 8
height: root.availableHeight
clip: true
StatusIconTextButton {
id: backButton
Layout.preferredHeight: 48
Layout.maximumWidth: root.availableWidth
spacing: 0
leftPadding: 4
statusIcon: "previous"
icon.width: 12
icon.height: 12
text: qsTr("Back")
onClicked: root.backButtonClicked()
}
SearchBox {
id: filterInput
Layout.fillWidth: true
placeholderText: qsTr("Search members")
maximumHeight: 36
topPadding: 0
bottomPadding: 0
input.asset.width: 15
input.asset.height: 15
input.leftPadding: 13
input.font.pixelSize: 13
input.placeholder.font.pixelSize: 13
}
StatusBaseText {
id: noContactsText
Layout.fillWidth: true
Layout.preferredHeight: 50
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: listView.count === 0
text: qsTr("No contacts found")
color: Theme.palette.baseColor1
font.pixelSize: Theme.tertiaryTextFontSize
elide: Text.ElideRight
lineHeight: 1.2
}
StatusListView {
id: listView
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredHeight: Math.min(contentHeight,
root.maximumListHeight)
verticalScrollBar {
implicitWidth: d.scrollBarWidth + ScrollBar.vertical.padding * 2
}
visible: count > 0
header: StatusCheckBox {
width: ListView.view.width
text: qsTr("Select all")
font.weight: Font.Medium
checked: selectionChecker.allSelected
leftSide: false
size: StatusCheckBox.Size.Small
indicator.anchors.rightMargin: 12
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
const currentKeys = selectionChecker.keys
const keysSet = new Set([...root.selectedKeys])
if (listView.headerItem.checked)
currentKeys.forEach(key => keysSet.delete(key))
else
currentKeys.forEach(key => keysSet.add(key))
root.selectedKeys = keysSet
}
}
}
delegate: ContactListItemDelegate {
id: delegateRoot
width: ListView.view.width
height: d.delegateHeight
asset.width: 29
asset.height: 29
rightPadding: 0
leftPadding: 6
color: "transparent"
onClicked: {
const selectedKeysCopy = new Set([...root.selectedKeys])
if (root.selectedKeys.has(model.pubKey))
selectedKeysCopy.delete(model.pubKey)
else
selectedKeysCopy.add(model.pubKey)
root.selectedKeys = selectedKeysCopy
}
components: [
StatusCheckBox {
id: contactCheckbox
size: StatusCheckBox.Size.Small
checked: root.selectedKeys.has(model.pubKey)
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: delegateRoot.clicked(
delegateRoot.itemId, mouse)
}
}
]
}
section.property: "displayName"
section.criteria: ViewSection.FirstCharacter
section.delegate: StatusBaseText {
text: section.toUpperCase()
width: ListView.view.width
height: d.sectionDelegateHeight
padding: 5
verticalAlignment: Qt.AlignVCenter
color: Theme.palette.baseColor1
font.pixelSize: Theme.tertiaryTextFontSize
}
}
StatusButton {
id: addButton
Layout.fillWidth: true
textFillWidth: true
enabled: {
if (root.forceButtonDisabled)
return false
if (root.mode === MembersDropdown.Mode.Add)
return root.selectedKeys.size > 0
return true
}
text: {
if (root.mode === MembersDropdown.Mode.Update)
return qsTr("Update members")
return root.selectedKeys.size > 0
? qsTr("Add %n member(s)", "", root.selectedKeys.size)
: qsTr("Add")
}
onClicked: root.addButtonClicked()
}
}
}