refactor(MintingToken): Navigations refactor

- It has been added a `StackView` in main mint tokens panel to easily switch back / forward between views.

- It has been created a SQ component `StackViewStatesManager` that allows a managing together a stackview and states.

- Updated `HoldingsDropdown` to use new stack states component
This commit is contained in:
Noelia 2023-03-09 12:12:49 +01:00 committed by Noelia
parent d84d7a8a33
commit 79a1a60c70
7 changed files with 167 additions and 184 deletions

View File

@ -0,0 +1,45 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
QtObject {
id: root
required property StackView stackView
readonly property StatesStack _statesStack: StatesStack { id: statesStack }
property alias currentState: statesStack.currentState
property alias size: statesStack.size
readonly property alias states: statesStack.states
function pushInitialState(state) {
if(size > 0)
console.warn("Pushing initial state but the stack already contains elements: " + size)
statesStack.push(state)
}
function push(state, item, properties, operation) {
// States related operations:
statesStack.push(state)
// Stack view related operations:
stackView.push(item, properties, operation)
}
function pop(operation) {
// States related operations:
statesStack.pop()
// Stack view related operations:
stackView.pop(operation)
}
function clear(initialState, operation) {
// States related operations:
statesStack.clear()
statesStack.push(initialState)
// Stack view related operations:
stackView.pop(null, operation) // Resetting to the initial stack state
}
}

View File

@ -0,0 +1,27 @@
import QtQml 2.14
QtObject {
id: root
property string currentState
property int size: 0
property var states: []
function push(state) {
states.push(state)
currentState = state
size++
}
function pop(operation) {
states.pop()
currentState = states.length ? states[states.length - 1] : ""
size = states.length
}
function clear() {
currentState = ""
size = 0
states = []
}
}

View File

@ -2,6 +2,8 @@ module StatusQ.Core.Utils
EmojiJSON 1.0 emojiList.js EmojiJSON 1.0 emojiList.js
JSONListModel 0.1 JSONListModel.qml JSONListModel 0.1 JSONListModel.qml
StatesStack 0.1 StatesStack.qml
StackViewStates 0.1 StackViewStates.qml
ModelChangeGuard 0.1 ModelChangeGuard.qml ModelChangeGuard 0.1 ModelChangeGuard.qml
ModelChangeTracker 0.1 ModelChangeTracker.qml ModelChangeTracker 0.1 ModelChangeTracker.qml
ModelsComparator 0.1 ModelsComparator.qml ModelsComparator 0.1 ModelsComparator.qml

View File

@ -122,30 +122,8 @@ StatusDropdown {
} }
} }
QtObject { StatesStack {
id: statesStack id: statesStack
property alias currentState: content.state
property int size: 0
property var states: []
function push(state) {
states.push(state)
currentState = state
size++
}
function pop() {
states.pop()
currentState = states.length ? states[states.length - 1] : ""
size--
}
function clear() {
currentState = ""
size = 0
states = []
}
} }
width: d.defaultWidth width: d.defaultWidth
@ -155,6 +133,7 @@ StatusDropdown {
id: content id: content
spacing: d.backButtonToContentSpace spacing: d.backButtonToContentSpace
state: statesStack.currentState
StatusIconTextButton { StatusIconTextButton {
id: backButton id: backButton

View File

@ -1,9 +1,12 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.14
import QtQml 2.15
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import AppLayouts.Chat.layouts 1.0 import AppLayouts.Chat.layouts 1.0
import AppLayouts.Chat.views.communities 1.0 import AppLayouts.Chat.views.communities 1.0
@ -24,10 +27,6 @@ SettingsPageLayout {
property var enabledNetworks property var enabledNetworks
property var allNetworks property var allNetworks
// Other properties:
property alias chainName: collectibleItem.chainName
property alias chainIcon: collectibleItem.chainIcon
property int viewWidth: 560 // by design property int viewWidth: 560 // by design
signal mintCollectible(url artworkSource, signal mintCollectible(url artworkSource,
@ -40,128 +39,65 @@ SettingsPageLayout {
bool selfDestruct, bool selfDestruct,
int chainId) int chainId)
signal requestChainName(int chainId)
signal requestChainIcon(int chainId)
function navigateBack() { function navigateBack() {
if (root.state === d.newCollectibleViewState) { stackManager.pop(StackView.Immediate)
root.state = d.initialState
} else if (root.state === d.previewCollectibleViewState) {
root.state = d.newCollectibleViewState
} else if (root.state === d.collectibleViewState) {
root.state = d.mintedCollectibleViewState
}
} }
QtObject { QtObject {
id: d id: d
readonly property string welcomeViewState: "WELCOME" readonly property string initialViewState: "WELCOME_OR_LIST_COLLECTIBLES"
readonly property string newCollectibleViewState: "NEW_COLLECTIBLE" readonly property string newCollectibleViewState: "NEW_COLLECTIBLE"
readonly property string previewCollectibleViewState: "PREVIEW_COLLECTIBLE" readonly property string previewCollectibleViewState: "PREVIEW_COLLECTIBLE"
readonly property string mintedCollectibleViewState: "MINTED_COLLECTIBLE"
readonly property string collectibleViewState: "VIEW_COLLECTIBLE" readonly property string collectibleViewState: "VIEW_COLLECTIBLE"
readonly property string welcomePageTitle: qsTr("Mint tokens") readonly property string welcomePageTitle: qsTr("Mint tokens")
readonly property string newCollectiblePageTitle: qsTr("Create new collectible") readonly property string newCollectiblePageTitle: qsTr("Create new collectible")
readonly property string newTokenButtonText: qsTr("Create new token")
readonly property string backButtonText: qsTr("Back") readonly property string backButtonText: qsTr("Back")
readonly property string backTokensText: qsTr("Tokens") readonly property string backTokensText: qsTr("Tokens")
property bool preview: false property bool preview: false
readonly property string initialState: root.tokensModel.count > 0 ? d.mintedCollectibleViewState : d.welcomeViewState
}
QtObject {
id: collectibleItem
property int deployState
property url artworkSource
property string collectibleName property string collectibleName
property string symbol readonly property var initialItem: (root.tokensModel && root.tokensModel.count > 0) ? mintedTokensView : welcomeView
property string description
property string supplyText
property bool infiniteSupply: true
property bool transferable: true
property bool selfDestruct: true
property int chainId
property string chainName
property string chainIcon
function initialize() {
deployState = 1
artworkSource = ""
collectibleName = ""
symbol = ""
description = ""
supplyText = ""
infiniteSupply = true
transferable = true
selfDestruct = true
chainId = -1
chainName = ""
chainIcon = ""
}
function loadData(model) {
deployState = model.deployState
collectibleName = model.name
description = model.description
supplyText = model.supply.toString()
infiniteSupply = model.infiniteSupply
transferable = model.transferable
artworkSource = model.image
symbol = model.symbol
selfDestruct = model.remoteSelfDestruct
chainId = model.chainId
requestChainName(model.chainId)
requestChainIcon(model.chainId)
}
} }
state: d.initialState content: StackView {
anchors.fill: parent
initialItem: d.initialItem
Component.onCompleted: stackManager.pushInitialState(d.initialViewState)
}
state: stackManager.currentState
states: [ states: [
State { State {
name: d.welcomeViewState name: d.initialViewState
PropertyChanges {target: root; title: d.welcomePageTitle} PropertyChanges {target: root; title: d.welcomePageTitle}
PropertyChanges {target: root; previousPageName: ""} PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: welcomeView}
PropertyChanges {target: root; headerButtonVisible: true} PropertyChanges {target: root; headerButtonVisible: true}
PropertyChanges {target: root; headerButtonText: qsTr("Create new token")} PropertyChanges {target: root; headerButtonText: d.newTokenButtonText}
PropertyChanges {target: root; headerWidth: root.viewWidth} PropertyChanges {target: root; headerWidth: root.viewWidth}
}, },
State { State {
name: d.newCollectibleViewState name: d.newCollectibleViewState
PropertyChanges {target: root; title: d.newCollectiblePageTitle} PropertyChanges {target: root; title: d.newCollectiblePageTitle}
PropertyChanges {target: root; previousPageName: d.welcomePageTitle} PropertyChanges {target: root; previousPageName: d.welcomePageTitle}
PropertyChanges {target: root; content: newCollectiblesView}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; headerButtonVisible: false}
PropertyChanges {target: root; headerWidth: 0} PropertyChanges {target: root; headerWidth: 0}
}, },
State { State {
name: d.previewCollectibleViewState name: d.previewCollectibleViewState
PropertyChanges {target: root; title: collectibleItem.collectibleName} PropertyChanges {target: root; title: d.collectibleName}
PropertyChanges {target: root; previousPageName: d.backButtonText} PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; content: collectibleView}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; headerButtonVisible: false}
PropertyChanges {target: root; headerWidth: 0} PropertyChanges {target: root; headerWidth: 0}
PropertyChanges {target: d; preview: true} PropertyChanges {target: d; preview: true}
}, },
State {
name: d.mintedCollectibleViewState
PropertyChanges {target: root; title: d.welcomePageTitle}
PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: mintedTokensView}
PropertyChanges {target: root; headerButtonVisible: true}
PropertyChanges {target: root; headerButtonText: qsTr("Create new token")}
PropertyChanges {target: root; headerWidth: root.viewWidth}
PropertyChanges {target: d; preview: false}
},
State { State {
name: d.collectibleViewState name: d.collectibleViewState
PropertyChanges {target: root; title: collectibleItem.collectibleName} PropertyChanges {target: root; title: d.collectibleName}
PropertyChanges {target: root; previousPageName: d.backTokensText} PropertyChanges {target: root; previousPageName: d.backTokensText}
PropertyChanges {target: root; content: collectibleView}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; headerButtonVisible: false}
PropertyChanges {target: root; headerWidth: 0} PropertyChanges {target: root; headerWidth: 0}
PropertyChanges {target: root; footer: mintTokenFooter} PropertyChanges {target: root; footer: mintTokenFooter}
@ -169,13 +105,19 @@ SettingsPageLayout {
} }
] ]
onHeaderButtonClicked: { onHeaderButtonClicked: stackManager.push(d.newCollectibleViewState, newCollectiblesView, null, StackView.Immediate)
if(root.state === d.welcomeViewState || root.state === d.mintedCollectibleViewState) { onTokensModelChanged: {
root.state = d.newCollectibleViewState if(root.tokensModel && root.tokensModel.count === 1) {
collectibleItem.initialize() stackManager.stackView.replace(welcomeView, d.initialItem, StackView.Immediate)
} }
} }
StackViewStates {
id: stackManager
stackView: root.contentItem
}
// Mint tokens possible view contents: // Mint tokens possible view contents:
Component { Component {
id: welcomeView id: welcomeView
@ -197,36 +139,32 @@ SettingsPageLayout {
id: newCollectiblesView id: newCollectiblesView
CommunityNewCollectibleView { CommunityNewCollectibleView {
anchors.fill: parent //anchors.fill: parent
viewWidth: root.viewWidth
layer1Networks: root.layer1Networks layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks layer2Networks: root.layer2Networks
testNetworks: root.testNetworks testNetworks: root.testNetworks
enabledNetworks: root.testNetworks enabledNetworks: root.testNetworks
allNetworks: root.allNetworks allNetworks: root.allNetworks
name: collectibleItem.collectibleName
artworkSource: collectibleItem.artworkSource
symbol: collectibleItem.symbol
description: collectibleItem.description
supplyText: collectibleItem.supplyText
infiniteSupply: collectibleItem.infiniteSupply
transferable: collectibleItem.transferable
selfDestruct: collectibleItem.selfDestruct
chainId: collectibleItem.chainId
chainName: collectibleItem.chainName
chainIcon: collectibleItem.chainIcon
onNameChanged: collectibleItem.collectibleName = name onPreviewClicked: {
onArtworkSourceChanged: collectibleItem.artworkSource = artworkSource stackManager.push(d.previewCollectibleViewState,
onSymbolChanged: collectibleItem.symbol = symbol collectibleView,
onDescriptionChanged: collectibleItem.description = description {
onSupplyTextChanged: collectibleItem.supplyText = supplyText name,
onInfiniteSupplyChanged: collectibleItem.infiniteSupply = infiniteSupply artworkSource,
onTransferableChanged: collectibleItem.transferable = transferable symbol,
onSelfDestructChanged: collectibleItem.selfDestruct = selfDestruct description,
onChainIdChanged: collectibleItem.chainId = chainId supplyText,
onChainNameChanged: collectibleItem.chainName = chainName infiniteSupply,
onChainIconChanged: collectibleItem.chainIcon = chainIcon transferable,
onPreviewClicked: root.state = d.previewCollectibleViewState selfDestruct,
chainId,
chainName,
chainIcon
},
StackView.Immediate)
}
} }
} }
@ -234,21 +172,11 @@ SettingsPageLayout {
id: collectibleView id: collectibleView
CommunityCollectibleView { CommunityCollectibleView {
anchors.fill: parent id: collectibleViewItem
//anchors.fill: parent
viewWidth: root.viewWidth
preview: d.preview preview: d.preview
holdersModel: root.holdersModel holdersModel: root.holdersModel
deployState: collectibleItem.deployState
name: collectibleItem.collectibleName
artworkSource: collectibleItem.artworkSource
symbol: collectibleItem.symbol
description: collectibleItem.description
supplyText: collectibleItem.supplyText
infiniteSupply: collectibleItem.infiniteSupply
transferable: collectibleItem.transferable
selfDestruct: collectibleItem.selfDestruct
chainId: collectibleItem.chainId
chainName: collectibleItem.chainName
chainIcon: collectibleItem.chainIcon
onMintCollectible: { onMintCollectible: {
root.mintCollectible(artworkSource, root.mintCollectible(artworkSource,
@ -261,7 +189,14 @@ SettingsPageLayout {
selfDestruct, selfDestruct,
chainId) chainId)
root.state = d.mintedCollectibleViewState stackManager.clear(d.initialViewState, StackView.Immediate)
}
Binding {
target: d
property: "collectibleName"
value: collectibleViewItem.name
restoreMode: Binding.RestoreBindingOrValue
} }
} }
} }
@ -283,35 +218,42 @@ SettingsPageLayout {
// TEMPORAL: // TEMPORAL:
Item { Item {
anchors.fill: parent id: mintedTokensViewItem
width: root.viewWidth
//anchors.fill: parent
ColumnLayout { ColumnLayout {
id: backendChecker id: backendChecker
width: parent.width width: parent.width
StatusBaseText { viewWidth: root.viewWidth
text: qsTr("Collectibles") model: root.tokensModel
font.pixelSize: Theme.primaryTextFontSize onItemClicked: {
color: Theme.palette.baseColor1 selectedCollectibleName = name
} stackManager.push(d.collectibleViewState,
collectibleView,
{
"deployState": Qt.binding(() => deployState),
name,
artworkSource,
symbol,
description,
"supplyText": supply.toString(),
infiniteSupply,
transferable,
remoteSelfDestruct,
chainId,
chainName,
chainIcon
},
StackView.Immediate)
}
// TODO: We can probably use some wallet components (i.e. CollectibleView.qml) Binding {
ListView { target: d
Layout.preferredWidth: 560 property: "collectibleName"
Layout.preferredHeight: childrenRect.height value: mintedTokensViewItem.model.name
model: root.tokensModel restoreMode: Binding.RestoreBindingOrValue
delegate: StatusListItem {
width: parent.width
title: model.name + " - " + model.symbol
subTitle: model.description
titleAsideText: model.supply
label: model.deployState
onClicked: {
root.state = d.collectibleViewState
collectibleItem.loadData(model)
}
}
}
} }
} }
} }

View File

@ -19,15 +19,7 @@ QtObject {
property var layer2Networks: networksModule.layer2 property var layer2Networks: networksModule.layer2
property var testNetworks: networksModule.test property var testNetworks: networksModule.test
property var enabledNetworks: networksModule.enabled property var enabledNetworks: networksModule.enabled
property var allNetworks: networksModule.all property var allNetworks: networksModule.all
function getChainName(chainId) {
return allNetworks.getNetworkFullName(chainId)
}
function getChainIcon(chainId) {
return allNetworks.getIconUrl(chainId)
}
// Token holders model: MOCKED DATA -> TODO: Update with real data // Token holders model: MOCKED DATA -> TODO: Update with real data
readonly property var holdersModel: ListModel { readonly property var holdersModel: ListModel {

View File

@ -295,8 +295,6 @@ StatusSectionLayout {
allNetworks: communityTokensStore.allNetworks allNetworks: communityTokensStore.allNetworks
onPreviousPageNameChanged: root.backButtonName = previousPageName onPreviousPageNameChanged: root.backButtonName = previousPageName
onRequestChainName: chainName = communityTokensStore.getChainName(chainId)
onRequestChainIcon: chainIcon = communityTokensStore.getChainIcon(chainId)
onMintCollectible: { onMintCollectible: {
communityTokensStore.deployCollectible(root.community.id, communityTokensStore.deployCollectible(root.community.id,
root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/ root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/
@ -309,8 +307,6 @@ StatusSectionLayout {
selfDestruct, selfDestruct,
chainId, chainId,
artworkSource) artworkSource)
root.state = d.mintedCollectibleViewState
} }
} }