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:
parent
8a83aba05a
commit
d5a11ce0fa
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue