chore(MintTokensSettingsPanel): component simplified, storybook page

improved

- management of header simplified, no states needed
- no need to use StackViewStates helper
- no need to use internal `d` object as a proxy to pass data between
  pages
- StackView used as a base class
- clipping problems fixed (#11285)
- scrolling problems fixed (#11289)
- all flows working from the storybook
- header management simplified

Closes: #11285
Closes: #11298
This commit is contained in:
Michał Cieślak 2023-06-28 21:30:01 +02:00 committed by Michał
parent 8a83aba05a
commit d5a11ce0fa
4 changed files with 386 additions and 525 deletions

View File

@ -24,6 +24,18 @@ SplitView {
text: "Back" text: "Back"
onClicked: panel.navigateBack() onClicked: panel.navigateBack()
} }
Timer {
id: feesTimer
interval: 1000
onTriggered: {
panel.isFeeLoading = false
panel.feeText = "0,0002 ETH (123,15 USD)"
}
}
Rectangle { Rectangle {
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.fillHeight: true SplitView.fillHeight: true
@ -49,6 +61,8 @@ SplitView {
onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible") onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible")
onMintAsset: logs.logEvent("CommunityMintTokensSettingsPanel::mintAssets") onMintAsset: logs.logEvent("CommunityMintTokensSettingsPanel::mintAssets")
onDeleteToken: logs.logEvent("CommunityMintTokensSettingsPanel::deleteToken: " + tokenKey) onDeleteToken: logs.logEvent("CommunityMintTokensSettingsPanel::deleteToken: " + tokenKey)
onSignMintTransactionOpened: feesTimer.restart()
} }
} }
@ -60,34 +74,29 @@ SplitView {
logsView.logText: logs.logText logsView.logText: logs.logText
RowLayout {
ColumnLayout { ColumnLayout {
Label {
Layout.fillWidth: true
text: "Is empty model?"
}
CheckBox { CheckBox {
id: editorModelChecked id: editorModelChecked
checked: true checked: true
}
} text: "Empty model"
ColumnLayout {
Label {
Layout.fillWidth: true
text: "Is minting in progress?"
} }
CheckBox { RowLayout {
id: editorMintingChecked Button {
checked: true text: "Set all to 'In progress'"
onCheckedChanged:{
if(checked)
mintedTokensModel.changeAllMintingStates(1/*In progress*/)
else
mintedTokensModel.changeAllMintingStates(2/*Deployed*/)
}
onClicked: mintedTokensModel.changeAllMintingStates(1)
}
Button {
text: "Set all to 'Deployed'"
onClicked: mintedTokensModel.changeAllMintingStates(2)
}
Button {
text: "Set all to 'Error'"
onClicked: mintedTokensModel.changeAllMintingStates(0)
} }
} }
} }

View File

@ -1,6 +1,6 @@
import QtQuick 2.14 import QtQuick 2.15
import QtQuick.Controls 2.14 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.15
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
@ -25,9 +25,8 @@ Control {
height: 61 // by design height: 61 // by design
spacing: Style.current.padding spacing: Style.current.padding
contentItem: Item {
anchors.fill: parent
contentItem: Item {
StatusModalDivider { StatusModalDivider {
width: parent.width width: parent.width
anchors.top: parent.top anchors.top: parent.top

View File

@ -4,18 +4,17 @@ import QtQuick.Layouts 1.15
import QtQml 2.15 import QtQml 2.15
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import AppLayouts.Communities.layouts 1.0 import AppLayouts.Communities.controls 1.0
import AppLayouts.Communities.views 1.0
import AppLayouts.Communities.popups 1.0
import AppLayouts.Communities.helpers 1.0 import AppLayouts.Communities.helpers 1.0
import AppLayouts.Communities.popups 1.0
import AppLayouts.Communities.views 1.0
import utils 1.0 import utils 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
SettingsPageLayout { StackView {
id: root id: root
// General properties: // General properties:
@ -40,20 +39,16 @@ SettingsPageLayout {
signal mintCollectible(var collectibleItem) signal mintCollectible(var collectibleItem)
signal mintAsset(var assetItem) signal mintAsset(var assetItem)
signal signMintTransactionOpened(int chainId, string accountAddress, int tokenType) signal signMintTransactionOpened(int chainId, string accountAddress, int tokenType)
signal signRemoteDestructTransactionOpened(var remotelyDestructTokensList, // [key , amount] signal signRemoteDestructTransactionOpened(var remotelyDestructTokensList, // [key , amount]
string tokenKey) string tokenKey)
signal remotelyDestructCollectibles(var remotelyDestructTokensList, // [key , amount] signal remotelyDestructCollectibles(var remotelyDestructTokensList, // [key , amount]
string tokenKey) string tokenKey)
signal signBurnTransactionOpened(string tokenKey, int amount) signal signBurnTransactionOpened(string tokenKey, int amount)
signal burnToken(string tokenKey, int amount) signal burnToken(string tokenKey, int amount)
signal airdropToken(string tokenKey, int type, var addresses) signal airdropToken(string tokenKey, int type, var addresses)
signal deleteToken(string tokenKey) signal deleteToken(string tokenKey)
function setFeeLoading() { function setFeeLoading() {
@ -63,85 +58,63 @@ SettingsPageLayout {
} }
function navigateBack() { function navigateBack() {
stackManager.pop(StackView.Immediate) pop(StackView.Immediate)
} }
function resetNavigation(isAssetView = false) { function resetNavigation() {
d.isAssetView = isAssetView pop(initialItem, StackView.Immediate)
stackManager.clear(d.initialViewState, StackView.Immediate)
} }
QtObject { function openNewTokenForm(isAssetView) {
id: d resetNavigation()
readonly property string initialViewState: "TOKENS_LIST" const properties = { isAssetView }
readonly property string newTokenViewState: "NEW_TOKEN" root.push(newTokenView, properties, StackView.Immediate)
readonly property string previewTokenViewState: "PREVIEW_TOKEN"
readonly property string tokenViewState: "VIEW_TOKEN"
readonly property string tokensListPageTitle: qsTr("Tokens")
readonly property string newCollectiblePageTitle: qsTr("Mint collectible")
readonly property string newAssetPageTitle: qsTr("Mint asset")
readonly property string newTokenButtonText: qsTr("Mint token")
readonly property string backButtonText: qsTr("Back")
property string accountName
property int chainId
property string chainName
property var tokenOwnersModel
property var remotelyDestructTokensList
property bool remotelyDestruct
property bool infiniteSupply
property string tokenKey
property int burnAmount
property int remainingTokens
property url artworkSource
property bool isAssetView: false
property TokenObject currentToken
signal airdropClicked()
signal remoteDestructAddressClicked(string address)
signal retryMintClicked()
} }
secondaryHeaderButton.type: StatusBaseButton.Type.Danger property string previousPageName: depth > 1 ? qsTr("Back") : ""
content: StackView { component SettingsPage: Page {
anchors.fill: parent id: page
initialItem: mintedTokensView
Component.onCompleted: stackManager.pushInitialState(d.initialViewState) leftPadding: 64
topPadding: 16
// refactor to aliasses, why it doesn't work??
property list<StatusButton> buttons//: pageHeader.buttons
property string pageTitle//: pageHeader.title
property string pageSubtitle//: pageHeader.subtitle
header: SettingsPageHeader {
height: 44
leftPadding: 64
rightPadding: width - 560 - leftPadding
title: page.pageTitle
subtitle: page.pageSubtitle
buttons: page.buttons
}
} }
state: stackManager.currentState initialItem: SettingsPage {
states: [ implicitWidth: 0
State { pageTitle: qsTr("Tokens")
name: d.initialViewState
PropertyChanges {target: root; title: d.tokensListPageTitle} buttons: StatusButton {
PropertyChanges {target: root; subTitle: ""} text: qsTr("Mint token")
PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; primaryHeaderButton.visible: true} onClicked: root.push(newTokenView, StackView.Immediate)
PropertyChanges {target: root; primaryHeaderButton.text: d.newTokenButtonText} }
},
State { contentItem: MintedTokensView {
name: d.newTokenViewState model: root.tokensModel
PropertyChanges {target: root; title: d.isAssetView ? d.newAssetPageTitle : d.newCollectiblePageTitle }
PropertyChanges {target: root; subTitle: ""} onItemClicked: {
PropertyChanges {target: root; previousPageName: d.backButtonText} const properties = { preview: false, tokenKey }
}, root.push(tokenView, properties, StackView.Immediate)
State { }
name: d.previewTokenViewState }
PropertyChanges {target: root; previousPageName: d.backButtonText}
},
State {
name: d.tokenViewState
PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; footer: mintTokenFooter}
} }
]
Component { Component {
id: tokenObjectComponent id: tokenObjectComponent
@ -149,66 +122,12 @@ SettingsPageLayout {
TokenObject {} TokenObject {}
} }
onPrimaryHeaderButtonClicked: {
if(root.state == d.initialViewState) {
// Then move on to the new token view, with the specific tab selected:
const properties = {
isAssetView: d.isAssetView
}
stackManager.push(d.newTokenViewState, newTokenView, properties,
StackView.Immediate)
}
if(root.state == d.tokenViewState) {
if (!d.currentToken) {
console.warn("Mint Token Settings - Trying to retry undefined token object.")
return
}
const isAssetView = d.currentToken.type === TokenObject.Type.Asset
// copy TokenObject
const tokenObject = tokenObjectComponent.createObject(
null, d.currentToken)
// Reset the stack:
root.resetNavigation(isAssetView)
// Then move on to the new token view, but token pre-filled:
const properties = {
isAssetView,
referenceName: tokenObject.name,
referenceSymbol: tokenObject.symbol,
validationMode: StatusInput.ValidationMode.Always,
[isAssetView ? "asset" : "collectible"]: tokenObject
}
const tokenView = stackManager.push(d.newTokenViewState,
newTokenView, properties,
StackView.Immediate)
// cleanup dynamically created TokenObject
tokenView.Component.destruction.connect(() => tokenObject.destroy())
}
}
onSecondaryHeaderButtonClicked: {
if(root.state == d.tokenViewState)
deleteTokenAlertPopup.open()
}
StackViewStates {
id: stackManager
stackView: root.contentItem
}
// Mint tokens possible view contents: // Mint tokens possible view contents:
Component { Component {
id: newTokenView id: newTokenView
ColumnLayout { SettingsPage {
id: colLayout id: newTokenPage
property TokenObject asset: TokenObject{ property TokenObject asset: TokenObject{
type: TokenObject.Type.Asset type: TokenObject.Type.Asset
@ -223,6 +142,10 @@ SettingsPageLayout {
property string referenceName: "" property string referenceName: ""
property string referenceSymbol: "" property string referenceSymbol: ""
pageTitle: optionsTab.currentItem == assetsTab
? qsTr("Mint asset") : qsTr("Mint collectible")
contentItem: ColumnLayout {
width: root.viewWidth width: root.viewWidth
spacing: Style.current.padding spacing: Style.current.padding
@ -230,7 +153,7 @@ SettingsPageLayout {
id: optionsTab id: optionsTab
Layout.preferredWidth: root.viewWidth Layout.preferredWidth: root.viewWidth
currentIndex: colLayout.isAssetView ? 1 : 0 currentIndex: newTokenPage.isAssetView ? 1 : 0
StatusSwitchTabButton { StatusSwitchTabButton {
id: collectiblesTab id: collectiblesTab
@ -255,24 +178,20 @@ SettingsPageLayout {
id: newCollectibleView id: newCollectibleView
isAssetView: false isAssetView: false
validationMode: !colLayout.isAssetView validationMode: !newTokenPage.isAssetView
? colLayout.validationMode ? newTokenPage.validationMode
: StatusInput.ValidationMode.OnlyWhenDirty : StatusInput.ValidationMode.OnlyWhenDirty
collectible: colLayout.collectible collectible: newTokenPage.collectible
referenceName: colLayout.referenceName
referenceSymbol: colLayout.referenceSymbol
} }
CustomEditCommunityTokenView { CustomEditCommunityTokenView {
id: newAssetView id: newAssetView
isAssetView: true isAssetView: true
validationMode: colLayout.isAssetView validationMode: newTokenPage.isAssetView
? colLayout.validationMode ? newTokenPage.validationMode
: StatusInput.ValidationMode.OnlyWhenDirty : StatusInput.ValidationMode.OnlyWhenDirty
asset: colLayout.asset asset: newTokenPage.asset
referenceName: colLayout.referenceName
referenceSymbol: colLayout.referenceSymbol
} }
component CustomEditCommunityTokenView: EditCommunityTokenView { component CustomEditCommunityTokenView: EditCommunityTokenView {
@ -285,25 +204,19 @@ SettingsPageLayout {
accounts: root.accounts accounts: root.accounts
tokensModel: root.tokensModel tokensModel: root.tokensModel
referenceName: newTokenPage.referenceName
referenceSymbol: newTokenPage.referenceSymbol
onPreviewClicked: { onPreviewClicked: {
const properties = { const properties = {
preview: true,
token: isAssetView ? asset : collectible token: isAssetView ? asset : collectible
} }
stackManager.push(d.previewTokenViewState, root.push(previewTokenView, properties,
previewTokenView, properties,
StackView.Immediate) StackView.Immediate)
} }
} }
} }
Binding {
target: root
property: "title"
value: optionsTab.currentItem == collectiblesTab
? d.newCollectiblePageTitle : d.newAssetPageTitle
restoreMode: Binding.RestoreBindingOrValue
} }
} }
} }
@ -311,11 +224,20 @@ SettingsPageLayout {
Component { Component {
id: previewTokenView id: previewTokenView
CommunityTokenView { SettingsPage {
id: tokenPreviewPage
property alias token: preview.token
pageTitle: token.name
pageSubtitle: token.symbol
contentItem: CommunityTokenView {
id: preview id: preview
function signMintTransaction() { function signMintTransaction() {
root.setFeeLoading() root.setFeeLoading()
if(preview.isAssetView) if(preview.isAssetView)
root.mintAsset(token) root.mintAsset(token)
else else
@ -325,22 +247,10 @@ SettingsPageLayout {
} }
viewWidth: root.viewWidth viewWidth: root.viewWidth
preview: true
onMintClicked: signMintPopup.open() onMintClicked: signMintPopup.open()
Binding {
target: root
property: "title"
value: preview.name
}
Binding {
target: root
property: "subTitle"
value: preview.symbol
restoreMode: Binding.RestoreBindingOrValue
}
SignTokenTransactionsPopup { SignTokenTransactionsPopup {
id: signMintPopup id: signMintPopup
@ -355,23 +265,144 @@ SettingsPageLayout {
onOpened: { onOpened: {
root.setFeeLoading() root.setFeeLoading()
root.signMintTransactionOpened(preview.chainId, preview.accountAddress, preview.isAssetView ? Constants.TokenType.ERC20 : Constants.TokenType.ERC721) root.signMintTransactionOpened(preview.chainId, preview.accountAddress,
preview.isAssetView ? Constants.TokenType.ERC20
: Constants.TokenType.ERC721)
} }
onCancelClicked: close() onCancelClicked: close()
onSignTransactionClicked: preview.signMintTransaction() onSignTransactionClicked: preview.signMintTransaction()
} }
} }
} }
}
Component { Component {
id: mintTokenFooter id: tokenView
MintTokensFooterPanel { SettingsPage {
id: footerPanel id: tokenViewPage
readonly property bool deployStateCompleted: !!d.currentToken property string tokenKey
? d.currentToken.deployState === Constants.ContractTransactionStatus.Completed
: false pageTitle: view.name
pageSubtitle: view.symbol
buttons: [
StatusButton {
text: qsTr("Delete")
type: StatusBaseButton.Type.Danger
visible: view.deployState === Constants.ContractTransactionStatus.Failed
onClicked: deleteTokenAlertPopup.open()
},
StatusButton {
text: qsTr("Retry mint")
visible: view.deployState === Constants.ContractTransactionStatus.Failed
onClicked: {
const isAssetView = view.isAssetView
// copy TokenObject
const tokenObject = tokenObjectComponent.createObject(
null, view.token)
// Then move on to the new token view, but token pre-filled:
const properties = {
isAssetView,
referenceName: tokenObject.name,
referenceSymbol: tokenObject.symbol,
validationMode: StatusInput.ValidationMode.Always,
[isAssetView ? "asset" : "collectible"]: tokenObject
}
const tokenView = root.push(newTokenView, properties,
StackView.Immediate)
// cleanup dynamically created TokenObject
tokenView.Component.destruction.connect(() => tokenObject.destroy())
}
}
]
Instantiator {
id: instantiator
model: SortFilterProxyModel {
sourceModel: root.tokensModel
filters: ValueFilter {
roleName: "contractUniqueKey"
value: tokenViewPage.tokenKey
}
}
delegate: QtObject {
component Bind: Binding { target: view }
readonly property list<Binding> bindings: [
Bind { property: "tokenOwnersModel"; value: model.tokenOwnersModel },
Bind { property: "tokenType"; value: model.tokenType },
Bind { property: "airdropKey"; value: model.symbol } // TO BE REMOVED: When airdrop backend is ready to use token key instead of symbol
]
component BindToken: Binding { target: view.token }
readonly property list<Binding> tokenBindings: [
BindToken { property: "type"; value: model.tokenType === Constants.TokenType.ERC20
? TokenObject.Type.Asset : TokenObject.Type.Collectible},
BindToken { property: "key"; value: model.contractUniqueKey },
BindToken { property: "deployState"; value: model.deployState },
BindToken { property: "burnState"; value: model.burnState },
BindToken { property: "name"; value: model.name },
BindToken { property: "artworkSource"; value: model.image },
BindToken { property: "symbol"; value: model.symbol },
BindToken { property: "description"; value: model.description },
BindToken { property: "supply"; value: model.supply },
BindToken { property: "infiniteSupply"; value: model.infiniteSupply },
BindToken { property: "remainingTokens"; value: model.remainingSupply },
BindToken { property: "chainId"; value: model.chainId },
BindToken { property: "chainName"; value: model.chainName },
BindToken { property: "chainIcon"; value: model.chainIcon },
BindToken { property: "accountName"; value: model.accountName },
BindToken { property: "accountAddress"; value: model.accountAddress }, // TODO: Backend
BindToken { property: "transferable"; value: model.transferable },
BindToken { property: "remotelyDestructState"; value: model.remotelyDestructState },
BindToken { property: "remotelyDestruct"; value: model.remoteSelfDestruct },
BindToken { property: "decimals"; value: model.decimals }
]
}
}
contentItem: CommunityTokenView {
id: view
property string airdropKey // TO REMOVE: Temporal property until airdrop backend is not ready to use token key instead of symbol
property int tokenType
viewWidth: root.viewWidth
token: TokenObject {}
onGeneralAirdropRequested: {
root.airdropToken(view.airdropKey, view.tokenType, []) // tokenKey instead when backend airdrop ready to use key instead of symbol
}
onAirdropRequested: {
root.airdropToken(view.airdropKey, view.tokenType, [address]) // tokenKey instead when backend airdrop ready to use key instead of symbol
}
onRemoteDestructRequested: {
remotelyDestructPopup.open()
// TODO: set the address selected in the popup's list
}
}
footer: MintTokensFooterPanel {
id: footer
readonly property TokenObject token: view.token
readonly property bool deployStateCompleted:
token.deployState === Constants.ContractTransactionStatus.Completed
function closePopups() { function closePopups() {
remotelyDestructPopup.close() remotelyDestructPopup.close()
@ -380,26 +411,38 @@ SettingsPageLayout {
burnTokensPopup.close() burnTokensPopup.close()
} }
airdropEnabled: deployStateCompleted && (d.infiniteSupply || d.remainingTokens != 0) airdropEnabled: deployStateCompleted &&
remotelyDestructEnabled: deployStateCompleted && (d.tokenOwnersModel && d.tokenOwnersModel.count > 0) (token.infiniteSupply ||
token.remainingTokens !== 0)
remotelyDestructEnabled: deployStateCompleted &&
!!view.tokenOwnersModel &&
view.tokenOwnersModel.count > 0
burnEnabled: deployStateCompleted burnEnabled: deployStateCompleted
remotelyDestructVisible: d.remotelyDestruct remotelyDestructVisible: token.remotelyDestruct
burnVisible: !d.infiniteSupply burnVisible: !token.infiniteSupply
onAirdropClicked:root.airdropToken(view.airdropKey, // tokenKey instead when backend airdrop ready to use key instead of symbol
view.tokenType, [])
onAirdropClicked: d.airdropClicked()
onRemotelyDestructClicked: remotelyDestructPopup.open() onRemotelyDestructClicked: remotelyDestructPopup.open()
onBurnClicked: burnTokensPopup.open() onBurnClicked: burnTokensPopup.open()
// helper properties to pass data through popups
property var remotelyDestructTokensList
property int burnAmount
RemotelyDestructPopup { RemotelyDestructPopup {
id: remotelyDestructPopup id: remotelyDestructPopup
collectibleName: root.title collectibleName: view.token.name
model: d.tokenOwnersModel model: view.tokenOwnersModel || null
destroyOnClose: false destroyOnClose: false
onRemotelyDestructClicked: { onRemotelyDestructClicked: {
d.remotelyDestructTokensList = remotelyDestructTokensList footer.remotelyDestructTokensList = remotelyDestructTokensList
alertPopup.tokenCount = tokenCount alertPopup.tokenCount = tokenCount
alertPopup.open() alertPopup.open()
} }
@ -426,14 +469,16 @@ SettingsPageLayout {
id: signTransactionPopup id: signTransactionPopup
property bool isRemotelyDestructTransaction property bool isRemotelyDestructTransaction
readonly property alias tokenKey: tokenViewPage.tokenKey
function signTransaction() { function signTransaction() {
root.setFeeLoading() root.setFeeLoading()
if(signTransactionPopup.isRemotelyDestructTransaction) {
root.remotelyDestructCollectibles(d.remotelyDestructTokensList, d.tokenKey) if(signTransactionPopup.isRemotelyDestructTransaction)
} else { root.remotelyDestructCollectibles(
root.burnToken(d.tokenKey, d.burnAmount) footer.remotelyDestructTokensList, tokenKey)
} else
root.burnToken(tokenKey, footer.burnAmount)
footerPanel.closePopups() footerPanel.closePopups()
} }
@ -441,9 +486,10 @@ SettingsPageLayout {
title: signTransactionPopup.isRemotelyDestructTransaction title: signTransactionPopup.isRemotelyDestructTransaction
? qsTr("Sign transaction - Self-destruct %1 tokens").arg(root.title) ? qsTr("Sign transaction - Self-destruct %1 tokens").arg(root.title)
: qsTr("Sign transaction - Burn %1 tokens").arg(root.title) : qsTr("Sign transaction - Burn %1 tokens").arg(root.title)
tokenName: root.title
accountName: d.accountName tokenName: footer.token.name
networkName: d.chainName accountName: footer.token.accountName
networkName: footer.token.chainName
feeText: root.feeText feeText: root.feeText
isFeeLoading: root.isFeeLoading isFeeLoading: root.isFeeLoading
errorText: root.errorText errorText: root.errorText
@ -451,8 +497,8 @@ SettingsPageLayout {
onOpened: { onOpened: {
root.setFeeLoading() root.setFeeLoading()
signTransactionPopup.isRemotelyDestructTransaction signTransactionPopup.isRemotelyDestructTransaction
? root.signRemoteDestructTransactionOpened(d.remotelyDestructTokensList, d.tokenKey) ? root.signRemoteDestructTransactionOpened(footer.remotelyDestructTokensList, tokenKey)
: root.signBurnTransactionOpened(d.tokenKey, d.burnAmount) : root.signBurnTransactionOpened(tokenKey, footer.burnAmount)
} }
onCancelClicked: close() onCancelClicked: close()
onSignTransactionClicked: signTransaction() onSignTransactionClicked: signTransaction()
@ -462,225 +508,34 @@ SettingsPageLayout {
id: burnTokensPopup id: burnTokensPopup
communityName: root.communityName communityName: root.communityName
tokenName: root.title tokenName: footer.token.name
remainingTokens: d.remainingTokens remainingTokens: footer.token.remainingTokens
tokenSource: d.artworkSource tokenSource: footer.token.artworkSource
onBurnClicked: { onBurnClicked: {
d.burnAmount = burnAmount footer.burnAmount = burnAmount
signTransactionPopup.isRemotelyDestructTransaction = false signTransactionPopup.isRemotelyDestructTransaction = false
signTransactionPopup.open() signTransactionPopup.open()
} }
} }
Connections {
target: d
function onRemoteDestructAddressClicked(address) {
remotelyDestructPopup.open()
// TODO: set the address selected in the popup's list
}
}
}
}
Component {
id: mintedTokensView
MintedTokensView {
viewWidth: root.viewWidth
model: root.tokensModel
onItemClicked: {
d.chainId = chainId
d.chainName = chainName
d.accountName = accountName
d.tokenKey = tokenKey
stackManager.push(d.tokenViewState,
tokenView,
{
preview: false,
tokenKey
},
StackView.Immediate)
}
}
}
Component {
id: tokenView
CommunityTokenView {
id: view
property string airdropKey // TO REMOVE: Temporal property until airdrop backend is not ready to use token key instead of symbol
property int tokenType
viewWidth: root.viewWidth
token: TokenObject {}
Binding {
target: root
property: "title"
value: view.name
}
Binding {
target: root
property: "subTitle"
value: view.symbol
restoreMode: Binding.RestoreBindingOrValue
}
Binding {
target: root
property: "primaryHeaderButton.visible"
value: view.deployState === Constants.ContractTransactionStatus.Failed
}
Binding {
target: root
property: "primaryHeaderButton.text"
value: (view.deployState === Constants.ContractTransactionStatus.Failed) ? qsTr("Retry mint") : ""
}
Binding {
target: root
property: "secondaryHeaderButton.visible"
value: view.deployState === Constants.ContractTransactionStatus.Failed
}
Binding {
target: root
property: "secondaryHeaderButton.text"
value: (view.deployState === Constants.ContractTransactionStatus.Failed) ? qsTr("Delete") : ""
}
Binding {
target: d
property: "tokenOwnersModel"
value: view.tokenOwnersModel
}
Binding {
target: d
property: "remotelyDestruct"
value: view.token.remotelyDestruct
}
Binding {
target: d
property: "infiniteSupply"
value: view.infiniteSupply
restoreMode: Binding.RestoreBindingOrValue
}
Binding {
target: d
property: "remainingTokens"
value: view.remainingTokens
}
Binding {
target: d
property: "artworkSource"
value: view.artworkSource
}
Binding {
target: d
property: "isAssetView"
value: view.isAssetView
}
Binding {
target: d
property: "currentToken"
value: view.token
}
Instantiator {
id: instantiator
model: SortFilterProxyModel {
sourceModel: root.tokensModel
filters: ValueFilter {
roleName: "contractUniqueKey"
value: d.tokenKey
}
}
delegate: QtObject {
component Bind: Binding { target: view }
readonly property list<Binding> bindings: [
Bind { property: "tokenOwnersModel"; value: model.tokenOwnersModel },
Bind { property: "tokenType"; value: model.tokenType },
Bind { property: "airdropKey"; value: model.symbol } // TO BE REMOVED: When airdrop backend is ready to use token key instead of symbol
]
component BindToken: Binding { target: view.token }
readonly property list<Binding> collectibleBindings: [
BindToken { property: "type"; value: model.tokenType === Constants.TokenType.ERC20
? TokenObject.Type.Asset : TokenObject.Type.Collectible},
BindToken { property: "key"; value: model.contractUniqueKey },
BindToken { property: "deployState"; value: model.deployState },
BindToken { property: "burnState"; value: model.burnState },
BindToken { property: "name"; value: model.name },
BindToken { property: "artworkSource"; value: model.image },
BindToken { property: "symbol"; value: model.symbol },
BindToken { property: "description"; value: model.description },
BindToken { property: "supply"; value: model.supply },
BindToken { property: "infiniteSupply"; value: model.infiniteSupply },
BindToken { property: "remainingTokens"; value: model.remainingSupply },
BindToken { property: "chainId"; value: model.chainId },
BindToken { property: "chainName"; value: model.chainName },
BindToken { property: "chainIcon"; value: model.chainIcon },
BindToken { property: "accountName"; value: model.accountName },
BindToken { property: "accountAddress"; value: model.accountAddress }, // TODO: Backend
BindToken { property: "transferable"; value: model.transferable },
BindToken { property: "remotelyDestructState"; value: model.remotelyDestructState },
BindToken { property: "remotelyDestruct"; value: model.remoteSelfDestruct },
BindToken { property: "decimals"; value: model.decimals }
]
}
}
onGeneralAirdropRequested: {
root.airdropToken(view.airdropKey, view.tokenType, []) // d.tokenKey instead when backend airdrop ready to use key instead of symbol
}
onAirdropRequested: {
root.airdropToken(view.airdropKey, view.tokenType, [address]) // d.tokenKey instead when backend airdrop ready to use key instead of symbol
}
onRemoteDestructRequested: {
d.remoteDestructAddressClicked(address)
}
Connections {
target: d
// handle airdrop request from the footer
function onAirdropClicked() {
root.airdropToken(view.airdropKey, // d.tokenKey instead when backend airdrop ready to use key instead of symbol
view.tokenType,
[])
}
}
}
} }
AlertPopup { AlertPopup {
id: deleteTokenAlertPopup id: deleteTokenAlertPopup
readonly property alias tokenName: view.token.name
width: 521 width: 521
title: qsTr("Delete %1").arg(root.title) title: qsTr("Delete %1").arg(tokenName)
acceptBtnText: qsTr("Delete %1 token").arg(root.title) acceptBtnText: qsTr("Delete %1 token").arg(tokenName)
alertText: qsTr("%1 is not yet minted, are you sure you want to delete it? All data associated with this token including its icon and description will be permanently deleted.").arg(root.title) alertText: qsTr("%1 is not yet minted, are you sure you want to delete it? All data associated with this token including its icon and description will be permanently deleted.").arg(tokenName)
onAcceptClicked: { onAcceptClicked: {
root.deleteToken(d.tokenKey) root.deleteToken(tokenViewPage.tokenKey)
root.resetNavigation() root.navigateBack()
} }
onCancelClicked: close() onCancelClicked: close()
} }
} }
}
}

View File

@ -464,9 +464,7 @@ StatusSectionLayout {
target: airdropPanel target: airdropPanel
function onNavigateToMintTokenSettings(isAssetType) { function onNavigateToMintTokenSettings(isAssetType) {
// Here it is forced a navigation to the new airdrop form, like if it was clicked the header button mintPanel.openNewTokenForm(isAssetType)
mintPanel.resetNavigation(isAssetType)
mintPanel.primaryHeaderButtonClicked()
} }
} }
} }