feat(HoldingsDropdown): All listed assets / collectibles submenu

Closes: #9263
This commit is contained in:
Michał Cieślak 2023-03-23 22:45:45 +01:00 committed by Michał
parent b3af519476
commit 5b9017757f
5 changed files with 177 additions and 26 deletions

View File

@ -38,6 +38,20 @@ ListModel {
name: "Amp", name: "Amp",
shortName: "AMP", shortName: "AMP",
category: TokenCategories.Category.Own category: TokenCategories.Category.Own
},
{
key: "Dai",
iconSource: ModelsData.assets.dai,
name: "Dai",
shortName: "DAI",
category: TokenCategories.Category.General
},
{
key: "Dai2",
iconSource: ModelsData.assets.dai,
name: "Dai2",
shortName: "DAI2",
category: TokenCategories.Category.General
} }
] ]

View File

@ -23,18 +23,25 @@ Item {
property var checkedKeys: [] property var checkedKeys: []
property int type: ExtendedDropdownContent.Type.Assets property int type: ExtendedDropdownContent.Type.Assets
property string noDataText: qsTr("No data found") property string noDataText: qsTr("No data found")
property bool showAllTokensMode: false
readonly property bool canGoBack: root.state !== d.depth1_ListState readonly property bool canGoBack: root.state !== d.depth1_ListState
signal itemClicked(string key, string name, url iconSource) signal itemClicked(string key, string name, url iconSource)
signal footerButtonClicked
signal navigateDeep(string key, var subItems) signal navigateDeep(string key, var subItems)
signal layoutChanged() signal layoutChanged()
signal navigateToMintTokenSettings signal navigateToMintTokenSettings
implicitHeight: content.implicitHeight implicitHeight: content.implicitHeight
implicitWidth: content.implicitWidth implicitWidth: content.implicitWidth
onShowAllTokensModeChanged: searcher.text = ""
enum Type { enum Type {
Assets, Assets,
Collectibles Collectibles
@ -107,7 +114,27 @@ Item {
id: filteredModel id: filteredModel
sourceComponent: SortFilterProxyModel { sourceComponent: SortFilterProxyModel {
filters: ExpressionFilter { filters: [
ValueFilter {
roleName: "category"
value: TokenCategories.Category.General
inverted: true
enabled: !root.showAllTokensMode
},
AnyOf {
enabled: root.showAllTokensMode
ValueFilter {
roleName: "category"
value: TokenCategories.Category.Own
}
ValueFilter {
roleName: "category"
value: TokenCategories.Category.General
}
},
ExpressionFilter {
expression: { expression: {
searcher.text searcher.text
@ -119,6 +146,7 @@ Item {
searcher.text.toLowerCase()) searcher.text.toLowerCase())
} }
} }
]
proxyRoles: ExpressionRole { proxyRoles: ExpressionRole {
name: "categoryLabel" name: "categoryLabel"
@ -131,7 +159,6 @@ Item {
} }
expression: getCategoryLabelForType(model.category, root.type) expression: getCategoryLabelForType(model.category, root.type)
} }
} }
} }
@ -352,8 +379,19 @@ Item {
minimumHeight: 36 minimumHeight: 36
maximumHeight: 36 maximumHeight: 36
placeholderText: root.type === ExtendedDropdownContent.Type.Assets ? placeholderText: {
qsTr("Search assets") : qsTr("Search collectibles") if (root.type === ExtendedDropdownContent.Type.Assets) {
if (root.showAllTokensMode)
return qsTr("Search all listed assets")
return qsTr("Search assets")
}
if (root.showAllTokensMode)
return qsTr("Search all collectibles")
return qsTr("Search collectibles")
}
Binding on placeholderText { Binding on placeholderText {
when: d.currentItemName !== "" when: d.currentItemName !== ""
@ -408,12 +446,23 @@ Item {
checkedKeys: root.checkedKeys checkedKeys: root.checkedKeys
searchMode: d.searchMode searchMode: d.searchMode
footerButtonText: TokenCategories.getCategoryLabelForAsset(
TokenCategories.Category.General)
areSectionsVisible: !root.showAllTokensMode
isFooterButtonVisible: !root.showAllTokensMode && !d.searchMode
&& filteredModel.item && d.currentModel.count > filteredModel.item.count
onFooterButtonClicked: root.footerButtonClicked()
onHeaderItemClicked: { onHeaderItemClicked: {
if(key === "MINT") console.log("TODO: Mint asset") if(key === "MINT") console.log("TODO: Mint asset")
else if(key === "IMPORT") console.log("TODO: Import existing asset") else if(key === "IMPORT") console.log("TODO: Import existing asset")
} }
onItemClicked: root.itemClicked(key, shortName, iconSource) onItemClicked: root.itemClicked(key, shortName, iconSource)
onImplicitHeightChanged: root.layoutChanged() onImplicitHeightChanged: root.layoutChanged()
Binding on implicitHeight { Binding on implicitHeight {
value: contentHeight value: contentHeight
//avoid too many changes of the implicit height //avoid too many changes of the implicit height
@ -429,14 +478,31 @@ Item {
availableData: d.availableData availableData: d.availableData
noDataText: root.noDataText noDataText: root.noDataText
areHeaderButtonsVisible: root.state === d.depth1_ListState areHeaderButtonsVisible: root.state === d.depth1_ListState
&& !root.showAllTokensMode
headerModel: ListModel { headerModel: ListModel {
ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint collectible"); rotation: 0; spacing: 8 } ListElement {
key: "MINT"
icon: "add"
iconSize: 16
description: qsTr("Mint collectible")
rotation: 0
spacing: 8
}
} }
checkedKeys: root.checkedKeys checkedKeys: root.checkedKeys
searchMode: d.searchMode searchMode: d.searchMode
footerButtonText: TokenCategories.getCategoryLabelForCollectible(
TokenCategories.Category.General)
areSectionsVisible: !root.showAllTokensMode
isFooterButtonVisible: !root.showAllTokensMode && !d.searchMode
&& filteredModel.item && d.currentModel.count > filteredModel.item.count
onHeaderItemClicked: root.navigateToMintTokenSettings() onHeaderItemClicked: root.navigateToMintTokenSettings()
onFooterButtonClicked: root.footerButtonClicked()
onItemClicked: { onItemClicked: {
if(subItems && root.state === d.depth1_ListState) { if(subItems && root.state === d.depth1_ListState) {
// One deep navigation // One deep navigation

View File

@ -48,7 +48,7 @@ StatusDropdown {
signal navigateToMintTokenSettings signal navigateToMintTokenSettings
enum FlowType { enum FlowType {
Selected, List_Deep1, List_Deep2 Selected, List_Deep1, List_Deep1_All, List_Deep2
} }
function openUpdateFlow() { function openUpdateFlow() {
@ -102,6 +102,8 @@ StatusDropdown {
: (updateSelected ? HoldingTypes.Mode.Update : HoldingTypes.Mode.Add) : (updateSelected ? HoldingTypes.Mode.Update : HoldingTypes.Mode.Add)
property bool extendedDeepNavigation: false property bool extendedDeepNavigation: false
property bool allTokensMode: false
property var currentSubItems property var currentSubItems
property string currentItemKey: "" property string currentItemKey: ""
@ -224,14 +226,27 @@ StatusDropdown {
states: [ states: [
State { State {
name: HoldingsDropdown.FlowType.Selected name: HoldingsDropdown.FlowType.Selected
PropertyChanges {target: loader; sourceComponent: (d.currentHoldingType === HoldingTypes.Type.Asset) ? assetLayout : PropertyChanges {
((d.currentHoldingType === HoldingTypes.Type.Collectible) ? collectibleLayout : ensLayout) } target: loader
sourceComponent: {
if (d.currentHoldingType === HoldingTypes.Type.Asset)
return assetLayout
if (d.currentHoldingType === HoldingTypes.Type.Collectible)
return collectibleLayout
return ensLayout
}
}
}, },
State { State {
name: HoldingsDropdown.FlowType.List_Deep1 name: HoldingsDropdown.FlowType.List_Deep1
PropertyChanges {target: loader; sourceComponent: listLayout} PropertyChanges {target: loader; sourceComponent: listLayout}
PropertyChanges {target: d; extendedDeepNavigation: false} PropertyChanges {target: d; extendedDeepNavigation: false}
}, },
State {
name: HoldingsDropdown.FlowType.List_Deep1_All
extend: HoldingsDropdown.FlowType.List_Deep1
PropertyChanges {target: d; extendedDeepNavigation: false; allTokensMode: true }
},
State { State {
name: HoldingsDropdown.FlowType.List_Deep2 name: HoldingsDropdown.FlowType.List_Deep2
extend: HoldingsDropdown.FlowType.List_Deep1 extend: HoldingsDropdown.FlowType.List_Deep1
@ -256,6 +271,8 @@ StatusDropdown {
checkedKeys: root.usedTokens.map(entry => entry.key) checkedKeys: root.usedTokens.map(entry => entry.key)
type: d.extendedDropdownType type: d.extendedDropdownType
showAllTokensMode: d.allTokensMode
onTypeChanged: forceActiveFocus() onTypeChanged: forceActiveFocus()
onItemClicked: { onItemClicked: {
@ -290,6 +307,9 @@ StatusDropdown {
statesStack.push(HoldingsDropdown.FlowType.List_Deep2) statesStack.push(HoldingsDropdown.FlowType.List_Deep2)
} }
onFooterButtonClicked: statesStack.push(
HoldingsDropdown.FlowType.List_Deep1_All)
onLayoutChanged: d.forceLayout() onLayoutChanged: d.forceLayout()
Component.onCompleted: { Component.onCompleted: {
@ -308,6 +328,7 @@ StatusDropdown {
function onClicked() { function onClicked() {
if (listPanel.canGoBack) if (listPanel.canGoBack)
listPanel.goBack() listPanel.goBack()
statesStack.pop() statesStack.pop()
} }
} }
@ -342,16 +363,16 @@ StatusDropdown {
onUpdateClicked: root.updateAsset(root.assetKey, root.assetAmount) onUpdateClicked: root.updateAsset(root.assetKey, root.assetAmount)
onRemoveClicked: root.removeClicked() onRemoveClicked: root.removeClicked()
Component.onCompleted: {
if (d.assetAmountText.length === 0 && root.assetAmount)
assetPanel.setAmount(root.assetAmount)
}
Connections { Connections {
target: backButton target: backButton
function onClicked() { statesStack.pop() } function onClicked() { statesStack.pop() }
} }
Component.onCompleted: {
if (d.assetAmountText.length === 0 && root.assetAmount)
assetPanel.setAmount(root.assetAmount)
}
} }
} }

View File

@ -15,8 +15,13 @@ StatusListView {
property var checkedKeys: [] property var checkedKeys: []
property string footerButtonText
property var headerModel property var headerModel
property bool areHeaderButtonsVisible: true property bool areHeaderButtonsVisible: true
property bool isFooterButtonVisible: true
property bool areSectionsVisible: true
property bool searchMode: false property bool searchMode: false
property bool availableData: false property bool availableData: false
property string noDataText: qsTr("No data found") property string noDataText: qsTr("No data found")
@ -26,6 +31,8 @@ StatusListView {
signal headerItemClicked(string key) signal headerItemClicked(string key)
signal itemClicked(var key, string name, var shortName, url iconSource, var subItems) signal itemClicked(var key, string name, var shortName, url iconSource, var subItems)
signal footerButtonClicked
implicitWidth: 273 implicitWidth: 273
implicitHeight: Math.min(contentHeight, root.maxHeight) implicitHeight: Math.min(contentHeight, root.maxHeight)
currentIndex: -1 currentIndex: -1
@ -93,7 +100,8 @@ StatusListView {
key, name, shortName, iconSource, subItems) key, name, shortName, iconSource, subItems)
} }
section.property: root.searchMode ? "" : "categoryLabel" section.property: root.searchMode || !root.areSectionsVisible
? "" : "categoryLabel"
section.criteria: ViewSection.FullString section.criteria: ViewSection.FullString
section.delegate: Item { section.delegate: Item {
@ -113,6 +121,48 @@ StatusListView {
} }
} }
Component {
id: footerComponent
Item {
width: ListView.view ? ListView.view.width : 0
height: d.sectionHeight
Loader {
id: footerLoader
anchors.fill: parent
sourceComponent: sectionComponent
Binding {
target: footerLoader.item
property: "section"
value: root.footerButtonText
}
StatusIcon {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 16
icon: "tiny/chevron-right"
color: Theme.palette.baseColor1
width: 16
height: 16
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: root.footerButtonClicked()
}
}
}
}
footer: root.isFooterButtonVisible ? footerComponent : null
QtObject { QtObject {
id: d id: d

View File

@ -14,7 +14,7 @@ QtObject {
case TokenCategories.Category.Own: case TokenCategories.Category.Own:
return qsTr("Your assets") return qsTr("Your assets")
case TokenCategories.Category.General: case TokenCategories.Category.General:
return qsTr("All assets") return qsTr("All listed assets")
} }
return "" return ""