status-desktop/ui/app/AppLayouts/Chat/controls/community/ExtendedDropdownContent.qml
Noelia 3d6e40fd79 feat(CommunityPermission): Added How holds collectibles dropdown
- Added collectibles tab component.
- Added extended dropdown base content component
- Added filter popup option.
- Added collectibles model
- Added subitems in model
- Added thumbnails mode view
- Created `CommunitiesStore` and moved mock data to there.
- Added forward subitems navigation and selection.
- Updated `statusq`.

Closes #6337
2022-08-26 18:06:58 +02:00

278 lines
10 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
import StatusQ.Core 0.1
import shared.panels 1.0
ColumnLayout {
id: root
property var store
property int type: ExtendedDropdownContent.Type.Tokens
signal goBack()
signal itemClicked(string key, string name, url iconSource)
enum Type{
Tokens,
Collectibles
}
QtObject {
id: d
readonly property int filterItemsHeight: 36
readonly property int filterPopupWidth: 233
readonly property int filterPopupHeight: 205
// Internal management properties
property bool isFilterOptionVisible: false
readonly property string thumbnailsViewState: "THUMBNAILS"
readonly property string listView_depth1_State: "LIST-DEPTH1"
readonly property string listView_depth2_State: "LIST-DEPTH2"
property var currentModel: root.store.collectiblesModel
property var currentSubitems
property string currentItemName: ""
property url currentItemSource: ""
function reset() {
d.currentItemName = ""
d.currentItemSource = ""
d.currentModel = root.store.collectiblesModel
d.currentSubitems = undefined
root.state = d.listView_depth1_State
}
}
spacing: 0
state: d.listView_depth1_State
states: [
State {
name: d.thumbnailsViewState
PropertyChanges {target: contentLoader; sourceComponent: thumbnailsView}
PropertyChanges {target: d; isFilterOptionVisible: true}
PropertyChanges {target: d; currentModel: d.currentSubitems}
},
State {
name: d.listView_depth1_State
PropertyChanges {target: contentLoader; sourceComponent: root.type === ExtendedDropdownContent.Type.Tokens ? tokensListView : collectiblesListView}
PropertyChanges {target: d; isFilterOptionVisible: false}
PropertyChanges {target: d; currentModel: root.type === ExtendedDropdownContent.Type.Tokens ? root.store.tokensModel : root.store.collectiblesModel}
},
State {
name: d.listView_depth2_State
PropertyChanges {target: contentLoader; sourceComponent: collectiblesListView}
PropertyChanges {target: d; isFilterOptionVisible: true }
PropertyChanges {target: d; currentModel: d.currentSubitems}
}
]
// Header
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 8
Layout.topMargin: 5
StatusIconTextButton {
Layout.alignment: Qt.AlignVCenter
spacing: 0
statusIcon: "next"
icon.width: 12
icon.height: 12
iconRotation: 180
text: qsTr("Back")
onClicked: {
if(root.state == d.listView_depth1_State) {
root.goBack()
}
else {
root.state = d.listView_depth1_State
}
}
}
// Just a filler to fit layout
Item { Layout.fillWidth: true; height: filterButton.implicitHeight }
StatusFlatRoundButton {
id: filterButton
implicitWidth: 32
implicitHeight: 32
visible: d.isFilterOptionVisible
type: StatusFlatRoundButton.Type.Secondary
icon.name: "filter"
onClicked: {
filterOptionsPopup.x = filterButton.x + filterButton.width - filterOptionsPopup.width
filterOptionsPopup.y = filterButton.y + filterButton.height + 8
filterOptionsPopup.open()
}
}
// Filter options popup:
StatusDropdown {
id: filterOptionsPopup
width: d.filterPopupWidth
height: d.filterPopupHeight
contentItem: ColumnLayout {
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
ListView {
Layout.fillWidth: true
Layout.preferredHeight: model.count * d.filterItemsHeight
model: ListModel {
ListElement { text: qsTr("Most viewed"); selected: true }
ListElement { text: qsTr("Newest first"); selected: false }
ListElement { text: qsTr("Oldest first"); selected: false }
}
delegate: StatusItemPicker {
width: ListView.view.width
height: d.filterItemsHeight
color: sensor1.containsMouse ? Theme.palette.baseColor4 : "transparent"
name: model.text
namePixelSize: 13
selectorType: StatusItemPicker.SelectorType.RadioButton
radioGroup: filterRadioBtnGroup
radioButtonSize: StatusRadioButton.Size.Small
selected: model.selected
MouseArea {
id: sensor1
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
selected = !selected
console.log("TODO: Clicked filter option: " + model.text)
filterOptionsPopup.close()
}
}
}
// Not visual element to control filter options
ButtonGroup {
id: filterRadioBtnGroup
}
}
Separator { Layout.fillWidth: true }
ListView {
Layout.fillWidth: true
Layout.preferredHeight: model.count * d.filterItemsHeight
model: ListModel {
ListElement { key: "LIST"; text: qsTr("List"); selected: true }
ListElement { key: "THUMBNAILS"; text: qsTr("Thumbnails"); selected: false }
}
delegate: StatusItemPicker {
width: ListView.view.width
height: d.filterItemsHeight
color: sensor2.containsMouse ? Theme.palette.baseColor4 : "transparent"
name: model.text
namePixelSize: 13
selectorType: StatusItemPicker.SelectorType.RadioButton
radioGroup: visualizationRadioBtnGroup
radioButtonSize: StatusRadioButton.Size.Small
selected: model.selected
MouseArea {
id: sensor2
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
selected = !selected
if(model.key === "LIST") {
root.state = d.listView_depth2_State
}
else if(model.key === "THUMBNAILS") {
root.state = d.thumbnailsViewState
}
filterOptionsPopup.close()
}
}
}
// Not visual element to control visualization options
ButtonGroup {
id: visualizationRadioBtnGroup
}
}
}
}
}
// List elements content
Loader {
id: contentLoader
Layout.preferredWidth: 289 // by design
Layout.bottomMargin: 5
Layout.preferredHeight: (item != null && typeof(item) !== 'undefined') ? item.implicitHeight : 0
}
Component {
id: tokensListView
ListDropdownContent {
headerModel: ListModel {
ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint token"); rotation: 0; spacing: 8 }
ListElement { key: "IMPORT"; icon: "invite-users"; iconSize: 16; description: qsTr("Import existing token"); rotation: 180; spacing: 8 }
}
model: d.currentModel
onHeaderItemClicked: {
if(key === "MINT") console.log("TODO: Mint token")
else if(key === "IMPORT") console.log("TODO: Import existing token")
}
onItemClicked: root.itemClicked(key, shortName, iconSource)
}
}
Component {
id: collectiblesListView
ListDropdownContent {
isHeaderVisible: root.state === d.listView_depth1_State
headerModel: ListModel {
ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint collectible"); rotation: 0; spacing: 8 }
}
model: d.currentModel
onHeaderItemClicked: {
if(key === "MINT") console.log("TODO: Mint collectible")
}
onItemClicked: {
if(subItems && root.state === d.listView_depth1_State) {
// One deep navigation
d.currentSubitems = subItems
d.currentItemName = name
d.currentItemSource = iconSource
root.state = d.listView_depth2_State
}
else {
d.reset()
root.itemClicked(key, name, iconSource)
}
}
}
}
Component {
id: thumbnailsView
ThumbnailsDropdownContent {
title: d.currentItemName
titleImage: d.currentItemSource
model: d.currentModel
onItemClicked: {
d.reset()
root.itemClicked(key, name, iconSource)
}
}
}
}