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",
shortName: "AMP",
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,19 +23,26 @@ Item {
property var checkedKeys: []
property int type: ExtendedDropdownContent.Type.Assets
property string noDataText: qsTr("No data found")
property bool showAllTokensMode: false
readonly property bool canGoBack: root.state !== d.depth1_ListState
signal itemClicked(string key, string name, url iconSource)
signal footerButtonClicked
signal navigateDeep(string key, var subItems)
signal layoutChanged()
signal navigateToMintTokenSettings
implicitHeight: content.implicitHeight
implicitWidth: content.implicitWidth
enum Type{
onShowAllTokensModeChanged: searcher.text = ""
enum Type {
Assets,
Collectibles
}
@ -107,18 +114,39 @@ Item {
id: filteredModel
sourceComponent: SortFilterProxyModel {
filters: ExpressionFilter {
expression: {
searcher.text
filters: [
ValueFilter {
roleName: "category"
value: TokenCategories.Category.General
inverted: true
enabled: !root.showAllTokensMode
},
AnyOf {
enabled: root.showAllTokensMode
if (model.shortName && model.shortName.toLowerCase()
.includes(searcher.text.toLowerCase()))
return true
ValueFilter {
roleName: "category"
value: TokenCategories.Category.Own
}
return model.name.toLowerCase().includes(
searcher.text.toLowerCase())
ValueFilter {
roleName: "category"
value: TokenCategories.Category.General
}
},
ExpressionFilter {
expression: {
searcher.text
if (model.shortName && model.shortName.toLowerCase()
.includes(searcher.text.toLowerCase()))
return true
return model.name.toLowerCase().includes(
searcher.text.toLowerCase())
}
}
}
]
proxyRoles: ExpressionRole {
name: "categoryLabel"
@ -131,7 +159,6 @@ Item {
}
expression: getCategoryLabelForType(model.category, root.type)
}
}
}
@ -352,10 +379,21 @@ Item {
minimumHeight: 36
maximumHeight: 36
placeholderText: root.type === ExtendedDropdownContent.Type.Assets ?
qsTr("Search assets") : qsTr("Search collectibles")
placeholderText: {
if (root.type === ExtendedDropdownContent.Type.Assets) {
if (root.showAllTokensMode)
return qsTr("Search all listed assets")
Binding on placeholderText{
return qsTr("Search assets")
}
if (root.showAllTokensMode)
return qsTr("Search all collectibles")
return qsTr("Search collectibles")
}
Binding on placeholderText {
when: d.currentItemName !== ""
value: qsTr("Search %1").arg(d.currentItemName)
}
@ -408,12 +446,23 @@ Item {
checkedKeys: root.checkedKeys
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: {
if(key === "MINT") console.log("TODO: Mint asset")
else if(key === "IMPORT") console.log("TODO: Import existing asset")
}
onItemClicked: root.itemClicked(key, shortName, iconSource)
onImplicitHeightChanged: root.layoutChanged()
Binding on implicitHeight {
value: contentHeight
//avoid too many changes of the implicit height
@ -429,14 +478,31 @@ Item {
availableData: d.availableData
noDataText: root.noDataText
areHeaderButtonsVisible: root.state === d.depth1_ListState
&& !root.showAllTokensMode
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
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()
onFooterButtonClicked: root.footerButtonClicked()
onItemClicked: {
if(subItems && root.state === d.depth1_ListState) {
// One deep navigation

View File

@ -48,7 +48,7 @@ StatusDropdown {
signal navigateToMintTokenSettings
enum FlowType {
Selected, List_Deep1, List_Deep2
Selected, List_Deep1, List_Deep1_All, List_Deep2
}
function openUpdateFlow() {
@ -102,6 +102,8 @@ StatusDropdown {
: (updateSelected ? HoldingTypes.Mode.Update : HoldingTypes.Mode.Add)
property bool extendedDeepNavigation: false
property bool allTokensMode: false
property var currentSubItems
property string currentItemKey: ""
@ -224,14 +226,27 @@ StatusDropdown {
states: [
State {
name: HoldingsDropdown.FlowType.Selected
PropertyChanges {target: loader; sourceComponent: (d.currentHoldingType === HoldingTypes.Type.Asset) ? assetLayout :
((d.currentHoldingType === HoldingTypes.Type.Collectible) ? collectibleLayout : ensLayout) }
PropertyChanges {
target: loader
sourceComponent: {
if (d.currentHoldingType === HoldingTypes.Type.Asset)
return assetLayout
if (d.currentHoldingType === HoldingTypes.Type.Collectible)
return collectibleLayout
return ensLayout
}
}
},
State {
name: HoldingsDropdown.FlowType.List_Deep1
PropertyChanges {target: loader; sourceComponent: listLayout}
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 {
name: HoldingsDropdown.FlowType.List_Deep2
extend: HoldingsDropdown.FlowType.List_Deep1
@ -256,7 +271,9 @@ StatusDropdown {
checkedKeys: root.usedTokens.map(entry => entry.key)
type: d.extendedDropdownType
onTypeChanged: forceActiveFocus()
showAllTokensMode: d.allTokensMode
onTypeChanged: forceActiveFocus()
onItemClicked: {
d.assetAmountText = ""
@ -290,6 +307,9 @@ StatusDropdown {
statesStack.push(HoldingsDropdown.FlowType.List_Deep2)
}
onFooterButtonClicked: statesStack.push(
HoldingsDropdown.FlowType.List_Deep1_All)
onLayoutChanged: d.forceLayout()
Component.onCompleted: {
@ -308,6 +328,7 @@ StatusDropdown {
function onClicked() {
if (listPanel.canGoBack)
listPanel.goBack()
statesStack.pop()
}
}
@ -342,16 +363,16 @@ StatusDropdown {
onUpdateClicked: root.updateAsset(root.assetKey, root.assetAmount)
onRemoveClicked: root.removeClicked()
Component.onCompleted: {
if (d.assetAmountText.length === 0 && root.assetAmount)
assetPanel.setAmount(root.assetAmount)
}
Connections {
target: backButton
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 string footerButtonText
property var headerModel
property bool areHeaderButtonsVisible: true
property bool isFooterButtonVisible: true
property bool areSectionsVisible: true
property bool searchMode: false
property bool availableData: false
property string noDataText: qsTr("No data found")
@ -26,6 +31,8 @@ StatusListView {
signal headerItemClicked(string key)
signal itemClicked(var key, string name, var shortName, url iconSource, var subItems)
signal footerButtonClicked
implicitWidth: 273
implicitHeight: Math.min(contentHeight, root.maxHeight)
currentIndex: -1
@ -93,7 +100,8 @@ StatusListView {
key, name, shortName, iconSource, subItems)
}
section.property: root.searchMode ? "" : "categoryLabel"
section.property: root.searchMode || !root.areSectionsVisible
? "" : "categoryLabel"
section.criteria: ViewSection.FullString
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 {
id: d

View File

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