refactor(MintToken): Mint token views refactor

- Created `TokenObject` files and use them inside `CommunityNewTokenView` instead of plain properties.
- Updated `CommunityTokenView` to use `TokenObject` properties instead of plain properties.
- Updated store calls to use `TokenObject` properties instead of plain properties.
- Remote destruct properties renames.
- Airdrop navigation extended passing token type (asset or collectible).
- Updated `storybook` according to new changes.
This commit is contained in:
Noelia 2023-06-01 12:38:56 +02:00 committed by Noelia
parent 02baf36070
commit f58f82d4c6
16 changed files with 485 additions and 427 deletions

View File

@ -45,7 +45,6 @@ SplitView {
onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible")
onMintAsset: logs.logEvent("CommunityMintTokensSettingsPanel::mintAssets")
onDeleteToken: logs.logEvent("CommunityMintTokensSettingsPanel::deleteToken: " + key)
onRetryMintToken: logs.logEvent("CommunityMintTokensSettingsPanel::retryMintToken: " + key)
}
}

View File

@ -28,7 +28,7 @@ SplitView {
anchors.fill: parent
anchors.margins: 50
model: MintedTokensModel.mintedTokensModel
onItemClicked: logs.logEvent("CommunityMintedTokensView::itemClicked --> " + contractUniqueKey)
onItemClicked: logs.logEvent("CommunityMintedTokensView::itemClicked --> " + tokenKey)
}
}

View File

@ -3,6 +3,7 @@ import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import AppLayouts.Chat.views.communities 1.0
import AppLayouts.Chat.helpers 1.0
import StatusQ.Core 0.1
@ -23,59 +24,59 @@ SplitView {
SplitView.fillWidth: true
SplitView.fillHeight: true
CommunityTokenView {
id: view
CollectibleObject {
id: collectibleObj
anchors.fill: parent
anchors.margins: 50
artworkSource: ModelsData.icons.superRare
preview: previewBox.checked
isAssetView: isAssetBox.checked
remotelyDestructState: remotelyDestructStateBox.checked ? 1 /*In progress*/ : 2 /*Completed*/
burnState: burnDestructStateBox.checked ? 1 /*In progress*/ : 2 /*Completed*/
name: nameText.text
symbol: symbolText.text
description: descriptionText.text
supplyAmount: parseInt(supplyText.text)
supply: parseInt(supplyText.text)
infiniteSupply: unlimitedSupplyChecker.checked
assetDecimals: parseInt(decimalText.text)
remainingTokens: parseInt(remainingText.text)
transferable: transferibleChecker.checked
selfDestruct: selfdestructChecker.checked
remotelyDestruct: selfdestructChecker.checked
chainId: 1
chainName: "Ethereum Mainnet"
chainIcon: ModelsData.networks.ethereum
accountName: "helloworld"
tokenOwnersModel: TokenHoldersModel {
}
onMintCollectible: logs.logEvent("CommunityTokenView::onMintCollectible: \n"
+ "artworkSource: " + artworkSource + "\n"
+ "name: " + name + "\n"
+ "symbol: " + symbol + "\n"
+ "description: " + description + "\n"
+ "supply: " + supply + "\n"
+ "infiniteSupply: " + infiniteSupply + "\n"
+ "transferable: " + transferable + "\n"
+ "selfDestruct: " + selfDestruct + "\n"
+ "chainId: " + chainId + "\n"
+ "accountName: " + accountName)
onMintAsset: logs.logEvent("CommunityTokenView::onMintAsset: \n"
+ "artworkSource: " + artworkSource + "\n"
+ "name: " + name + "\n"
+ "symbol: " + symbol + "\n"
+ "description: " + description + "\n"
+ "supply: " + supply + "\n"
+ "infiniteSupply: " + infiniteSupply + "\n"
+ "decimals: " + decimals + "\n"
+ "chainId: " + chainId + "\n"
+ "accountName: " + accountName)
}
AssetObject {
id: assetObj
artworkSource: ModelsData.icons.superRare
burnState: burnDestructStateBox.checked ? 1 /*In progress*/ : 2 /*Completed*/
name: nameText.text
symbol: symbolText.text
description: descriptionText.text
supply: parseInt(supplyText.text)
infiniteSupply: unlimitedSupplyChecker.checked
decimals: parseInt(decimalText.text)
remainingTokens: parseInt(remainingText.text)
chainId: 1
chainName: "Ethereum Mainnet"
chainIcon: ModelsData.networks.ethereum
accountName: "helloworld"
}
CommunityTokenView {
id: view
anchors.fill: parent
anchors.margins: 50
preview: previewBox.checked
isAssetView: isAssetBox.checked
collectible: collectibleObj
asset: assetObj
tokenOwnersModel: TokenHoldersModel {}
onMintClicked: logs.logEvent("CommunityTokenView::onMintClicked")
}
}
LogsAndControlsPanel {
id: logsAndControlsPanel
@ -119,20 +120,29 @@ SplitView {
RadioButton {
id: mintingInProgress
text: "In progress"
onCheckedChanged: if(checked) view.deployState = Constants.ContractTransactionStatus.InProgress
onCheckedChanged: {
if(view.isAssetView) assetObj.deployState = Constants.ContractTransactionStatus.InProgress
else collectibleObj.deployState = Constants.ContractTransactionStatus.InProgress
}
}
RadioButton {
id: mintingFailed
text: "Failed"
onCheckedChanged: if(checked) view.deployState = Constants.ContractTransactionStatus.Failed
onCheckedChanged: {
if(view.isAssetView) assetObj.deployState = Constants.ContractTransactionStatus.Failed
else collectibleObj.deployState = Constants.ContractTransactionStatus.Failed
}
}
RadioButton {
id: mintingCompleted
text: "Completed"
checked: true
onCheckedChanged: if(checked) view.deployState = Constants.ContractTransactionStatus.Completed
onCheckedChanged: {
if(view.isAssetView) assetObj.deployState = Constants.ContractTransactionStatus.Completed
else collectibleObj.deployState = Constants.ContractTransactionStatus.Completed
}
}
}
@ -158,17 +168,26 @@ SplitView {
RadioButton {
text: "Small"
checked: true
onCheckedChanged: view.artworkSource = ModelsData.icons.superRare
onCheckedChanged: {
if(view.isAssetView) assetObj.artworkSource = ModelsData.icons.superRare
else collectibleObj.artworkSource = ModelsData.icons.superRare
}
}
RadioButton {
text: "Medium"
onCheckedChanged: view.artworkSource = ModelsData.collectibles.kitty2Big
onCheckedChanged: {
if(view.isAssetView) assetObj.artworkSource = ModelsData.collectibles.kitty2Big
else collectibleObj.artworkSource = ModelsData.collectibles.kitty2Big
}
}
RadioButton {
text: "Large"
onCheckedChanged: view.artworkSource = ModelsData.banners.superRare
onCheckedChanged: {
if(view.isAssetView) assetObj.artworkSource = ModelsData.banners.superRare
else collectibleObj.artworkSource = ModelsData.banners.superRare
}
}
Label {
@ -280,9 +299,15 @@ SplitView {
text: "Ethereum Mainnet"
checked: true
onCheckedChanged: {
view.chainName = text
view.chainIcon = ModelsData.networks.ethereum
view.chainId = 1
if(view.isAssetView) {
assetObj.chainName = text
assetObj.chainIcon = ModelsData.networks.ethereum
assetObj.chainId = 1
} else {
collectibleObj.chainName = text
collectibleObj.chainIcon = ModelsData.networks.ethereum
collectibleObj.chainId = 1
}
}
}
@ -290,9 +315,15 @@ SplitView {
id: opt
text: "Optimism"
onCheckedChanged: {
view.chainName = text
view.chainIcon = ModelsData.networks.optimism
view.chainId = 2
if(view.isAssetView) {
assetObj.chainName = text
assetObj.chainIcon = ModelsData.networks.optimism
assetObj.chainId = 2
} else {
collectibleObj.chainName = text
collectibleObj.chainIcon = ModelsData.networks.optimism
collectibleObj.chainId = 2
}
}
}
@ -300,9 +331,15 @@ SplitView {
id: arb
text: "Arbitrum"
onCheckedChanged: {
view.chainName = text
view.chainIcon = ModelsData.networks.arbitrum
view.chainId = 3
if(view.isAssetView) {
assetObj.chainName = text
assetObj.chainIcon = ModelsData.networks.arbitrum
assetObj.chainId = 3
} else {
collectibleObj.chainName = text
collectibleObj.chainIcon = ModelsData.networks.arbitrum
collectibleObj.chainId = 3
}
}
}
}

View File

@ -0,0 +1,15 @@
import QtQuick 2.15
/*!
\qmltype AssetObject
\inherits TokenObject
\brief ERC20 token object properties definition (also known as asset).
*/
TokenObject {
property int decimals: 2 // Default value
function copyAsset(tokenObject) {
copyToken(tokenObject)
decimals = tokenObject.decimals
}
}

View File

@ -0,0 +1,21 @@
import QtQuick 2.15
import utils 1.0
/*!
\qmltype CollectibleObject
\inherits TokenObject
\brief ERC721 token object properties definition (also known as collectible).
*/
TokenObject {
property bool transferable: false
property bool remotelyDestruct: true
property int remotelyDestructState: Constants.ContractTransactionStatus.None
function copyCollectible(tokenObject) {
copyToken(tokenObject)
transferable = tokenObject.transferable
remotelyDestruct = tokenObject.remotelyDestruct
remotelyDestructState = tokenObject.remotelyDestructState
}
}

View File

@ -0,0 +1,57 @@
import QtQuick 2.15
import utils 1.0
/*!
\qmltype TokenObject
\inherits QtObject
\brief Token object properties definition.
*/
QtObject {
// Unique identifier:
property string key
// General descriptive properties:
property string name
property string symbol
property string description
property bool infiniteSupply: true
property int supply: 1
property int remainingTokens
// Artwork related properties:
property url artworkSource
property rect artworkCropRect: Qt.rect(0, 0, 0, 0)
// Network related properties:
property int chainId
property string chainName
property string chainIcon
// Account related properties (from where they will be / have been deployed):
property string accountAddress
property string accountName
// Contract transactions states:
property int deployState: Constants.ContractTransactionStatus.None
property int burnState: Constants.ContractTransactionStatus.None
function copyToken(tokenObject) {
key = tokenObject.key
name = tokenObject.name
symbol = tokenObject.symbol
description = tokenObject.description
infiniteSupply = tokenObject.infiniteSupply
supply = tokenObject.supply
remainingTokens = tokenObject.remainingTokens
artworkSource = tokenObject.artworkSource
artworkCropRect = tokenObject.artworkCropRect
chainId = tokenObject.chainId
chainName = tokenObject.chainName
chainIcon = tokenObject.chainIcon
accountAddress = tokenObject.accountAddress
accountName = tokenObject.accountName
deployState = tokenObject.deployState
burnState = tokenObject.burnState
}
}

View File

@ -1 +1,4 @@
singleton CommunityPermissionsHelpers 1.0 CommunityPermissionsHelpers.qml
AssetObject 1.0 AssetObject.qml
CollectibleObject 1.0 CollectibleObject.qml
TokenObject 1.0 TokenObject.qml

View File

@ -29,8 +29,8 @@ SettingsPageLayout {
stackManager.pop(StackView.Immediate)
}
function selectCollectible(key, amount) {
d.selectCollectible(key, amount)
function selectToken(key, amount, type) {
d.selectToken(key, amount, type)
}
function addAddresses(addresses) {
@ -46,7 +46,7 @@ SettingsPageLayout {
readonly property string welcomePageTitle: qsTr("Airdrops")
readonly property string newAirdropViewPageTitle: qsTr("New airdrop")
signal selectCollectible(string key, int amount)
signal selectToken(string key, int amount, int type)
signal addAddresses(var addresses)
}
@ -116,7 +116,7 @@ SettingsPageLayout {
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings()
Component.onCompleted: {
d.selectCollectible.connect(view.selectCollectible)
d.selectToken.connect(view.selectToken)
d.addAddresses.connect(view.addAddresses)
}
}

View File

@ -12,6 +12,7 @@ import StatusQ.Controls 0.1
import AppLayouts.Chat.layouts 1.0
import AppLayouts.Chat.views.communities 1.0
import AppLayouts.Chat.popups.community 1.0
import AppLayouts.Chat.helpers 1.0
import utils 1.0
import SortFilterProxyModel 0.2
@ -19,9 +20,15 @@ import SortFilterProxyModel 0.2
SettingsPageLayout {
id: root
// General properties:
property string communityName
property int viewWidth: 560 // by design
// Models:
property var tokensModel
property var accounts // Expected roles: address, name, color, emoji
// Transaction related properties:
property string feeText
property string errorText
property bool isFeeLoading: true
@ -33,57 +40,18 @@ SettingsPageLayout {
property var enabledNetworks
property var allNetworks
// Account expected roles: address, name, color, emoji
property var accounts
property string communityName
property int viewWidth: 560 // by design
signal mintCollectible(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
bool transferable,
bool selfDestruct,
int chainId,
string accountName,
string accountAddress,
var artworkCropRect)
signal mintAsset(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
int decimals,
int chainId,
string accountName,
string accountAddress,
var artworkCropRect)
signal mintCollectible(var collectibleItem)
signal mintAsset(var assetItem)
signal signMintTransactionOpened(int chainId, string accountAddress)
signal signSelfDestructTransactionOpened(var selfDestructTokensList, // [key , amount]
string tokenKey)
signal remoteSelfDestructCollectibles(var selfDestructTokensList, // [key , amount]
string tokenKey)
signal signRemoteDestructTransactionOpened(var remotelyDestructTokensList, // [key , amount]
string tokenKey)
signal remotelyDestructCollectibles(var remotelyDestructTokensList, // [key , amount]
string tokenKey)
signal signBurnTransactionOpened(int chainId)
signal burnCollectibles(string tokenKey,
int amount)
signal airdropCollectible(string tokenKey, var addresses)
signal burnToken(string tokenKey, int amount)
signal airdropToken(string tokenKey, int type, var addresses)
signal deleteToken(string tokenKey)
signal retryMintToken(string tokenKey)
function setFeeLoading() {
root.isFeeLoading = true
root.feeText = ""
@ -108,15 +76,13 @@ SettingsPageLayout {
readonly property string newTokenButtonText: qsTr("Mint token")
readonly property string backButtonText: qsTr("Back")
property string accountAddress
property string accountName
property int chainId
property string chainName
property string contractUniqueKey
property var tokenOwnersModel
property var selfDestructTokensList
property bool selfDestruct
property var remotelyDestructTokensList
property bool remotelyDestruct
property bool burnEnabled
property string tokenKey
property int burnAmount
@ -124,11 +90,9 @@ SettingsPageLayout {
property url artworkSource
readonly property var initialItem: (root.tokensModel && root.tokensModel.count > 0) ? mintedTokensView : welcomeView
onInitialItemChanged: updateInitialStackView()
signal airdropClicked()
signal remoteDestructAddressClicked(string address)
signal retryMintClicked()
function updateInitialStackView() {
@ -139,6 +103,8 @@ SettingsPageLayout {
stackManager.stackView.replace(welcomeView, mintedTokensView, StackView.Immediate)
}
}
onInitialItemChanged: updateInitialStackView()
}
secondaryHeaderButton.type: StatusBaseButton.Type.Danger
@ -244,7 +210,7 @@ SettingsPageLayout {
Binding {
target: root
property: "title"
value: optionsTab.currentItem === collectiblesTab ? d.newCollectiblePageTitle : d.newAssetPageTitle
value: optionsTab.currentItem == collectiblesTab ? d.newCollectiblePageTitle : d.newAssetPageTitle
}
}
@ -252,9 +218,14 @@ SettingsPageLayout {
Layout.preferredWidth: root.viewWidth
Layout.fillHeight: true
currentIndex: optionsTab.currentItem === collectiblesTab ? 0 : 1
currentIndex: optionsTab.currentItem == collectiblesTab ? 0 : 1
CommunityNewTokenView {
CustomCommunityNewTokenView {}
CustomCommunityNewTokenView { isAssetView: true }
component CustomCommunityNewTokenView: CommunityNewTokenView {
isAssetView: false
viewWidth: root.viewWidth
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
@ -265,60 +236,13 @@ SettingsPageLayout {
tokensModel: root.tokensModel
onPreviewClicked: {
d.accountAddress = accountAddress
stackManager.push(d.previewTokenViewState,
previewTokenView,
{
preview: true,
isAssetView: false,
name,
artworkSource,
artworkCropRect,
symbol,
description,
supplyAmount,
infiniteSupply,
transferable: !notTransferable,
selfDestruct,
chainId,
chainName,
chainIcon,
accountName
},
StackView.Immediate)
}
}
CommunityNewTokenView {
viewWidth: root.viewWidth
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
enabledNetworks: root.testNetworks
allNetworks: root.allNetworks
accounts: root.accounts
tokensModel: root.tokensModel
isAssetView: true
onPreviewClicked: {
d.accountAddress = accountAddress
stackManager.push(d.previewTokenViewState,
previewTokenView,
{
preview: true,
isAssetView: true,
name,
artworkSource,
artworkCropRect,
symbol,
description,
supplyAmount,
infiniteSupply,
assetDecimals,
chainId,
chainName,
chainIcon,
accountName
preview : true,
isAssetView,
asset,
collectible
},
StackView.Immediate)
}
@ -335,40 +259,17 @@ SettingsPageLayout {
function signMintTransaction() {
root.setFeeLoading()
if(preview.isAssetView) {
root.mintAsset(artworkSource,
name,
symbol,
description,
supplyAmount,
infiniteSupply,
assetDecimals,
chainId,
accountName,
d.accountAddress,
artworkCropRect)
} else {
root.mintCollectible(artworkSource,
name,
symbol,
description,
supplyAmount,
infiniteSupply,
transferable,
selfDestruct,
chainId,
accountName,
d.accountAddress,
artworkCropRect)
}
if(preview.isAssetView)
root.mintAsset(asset)
else
root.mintCollectible(collectible)
stackManager.clear(d.initialViewState, StackView.Immediate)
}
viewWidth: root.viewWidth
onMintCollectible: popup.open()
onMintAsset: popup.open()
onMintClicked: signMintPopup.open()
Binding {
target: root
@ -384,10 +285,10 @@ SettingsPageLayout {
}
SignTokenTransactionsPopup {
id: popup
id: signMintPopup
anchors.centerIn: Overlay.overlay
title: qsTr("Sign transaction - Mint %1 token").arg(popup.tokenName)
title: qsTr("Sign transaction - Mint %1 token").arg(signMintPopup.tokenName)
tokenName: preview.name
accountName: preview.accountName
networkName: preview.chainName
@ -397,7 +298,7 @@ SettingsPageLayout {
onOpened: {
root.setFeeLoading()
root.signMintTransactionOpened(preview.chainId, d.accountAddress)
root.signMintTransactionOpened(preview.chainId, preview.accountAddress)
}
onCancelClicked: close()
onSignTransactionClicked: preview.signMintTransaction()
@ -419,7 +320,7 @@ SettingsPageLayout {
airdropEnabled: true
retailEnabled: false
remotelySelfDestructVisible: d.selfDestruct
remotelySelfDestructVisible: d.remotelyDestruct
burnVisible: d.burnEnabled
onAirdropClicked: d.airdropClicked()
@ -434,7 +335,7 @@ SettingsPageLayout {
destroyOnClose: false
onRemotelyDestructClicked: {
d.selfDestructTokensList = selfDestructTokensList
d.remotelyDestructTokensList = remotelyDestructTokensList
alertPopup.tokenCount = tokenCount
alertPopup.open()
}
@ -465,9 +366,9 @@ SettingsPageLayout {
function signTransaction() {
root.setFeeLoading()
if(signTransactionPopup.isRemotelyDestructTransaction) {
root.remoteSelfDestructCollectibles(d.selfDestructTokensList, d.tokenKey)
root.remotelyDestructCollectibles(d.remotelyDestructTokensList, d.tokenKey)
} else {
root.burnCollectibles(d.tokenKey, d.burnAmount)
root.burnToken(d.tokenKey, d.burnAmount)
}
footerPanel.closePopups()
@ -484,7 +385,7 @@ SettingsPageLayout {
onOpened: {
root.setFeeLoading()
signTransactionPopup.isRemotelyDestructTransaction ? root.signSelfDestructTransactionOpened(d.selfDestructTokensList, d.tokenKey) :
signTransactionPopup.isRemotelyDestructTransaction ? root.signRemoteDestructTransactionOpened(d.remotelyDestructTokensList, d.tokenKey) :
root.signBurnTransactionOpened(d.chainId)
}
onCancelClicked: close()
@ -524,28 +425,18 @@ SettingsPageLayout {
viewWidth: root.viewWidth
model: root.tokensModel
onItemClicked: {
d.accountAddress = accountAddress
d.chainId = chainId
d.chainName = chainName
d.accountName = accountName
d.tokenKey = contractUniqueKey
d.tokenKey = tokenKey
stackManager.push(d.tokenViewState,
tokenView,
{
preview: false,
contractUniqueKey
tokenKey
},
StackView.Immediate)
}
Connections {
target: d
function onRetryMintClicked() {
root.retryMintToken(d.tokenKey)
stackManager.clear(d.initialViewState, StackView.Immediate)
}
}
}
}
@ -555,9 +446,12 @@ SettingsPageLayout {
CommunityTokenView {
id: view
property string contractUniqueKey
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
collectible: CollectibleObject{}
asset: AssetObject{}
Binding {
target: root
@ -604,8 +498,8 @@ SettingsPageLayout {
Binding {
target: d
property: "selfDestruct"
value: view.selfDestruct
property: "remotelyDestruct"
value: view.collectible.remotelyDestruct
}
Binding {
@ -634,40 +528,68 @@ SettingsPageLayout {
sourceModel: root.tokensModel
filters: ValueFilter {
roleName: "contractUniqueKey"
value: view.contractUniqueKey
value: d.tokenKey
}
}
delegate: QtObject {
component Bind: Binding { target: view }
readonly property list<Binding> bindings: [
Bind { property: "isAssetView"; value: model.tokenType === Constants.TokenType.ERC20 },
Bind { property: "deployState"; value: model.deployState },
Bind { property: "remotelyDestructState"; value: model.remotelyDestructState },
Bind { property: "burnState"; value: model.burnState },
Bind { property: "name"; value: model.name },
Bind { property: "artworkSource"; value: model.image },
Bind { property: "symbol"; value: model.symbol },
Bind { property: "description"; value: model.description },
Bind { property: "supplyAmount"; value: model.supply },
Bind { property: "infiniteSupply"; value: model.infiniteSupply },
Bind { property: "remainingTokens"; value: model.remainingTokens },
Bind { property: "selfDestruct"; value: model.remoteSelfDestruct },
Bind { property: "chainId"; value: model.chainId },
Bind { property: "chainName"; value: model.chainName },
Bind { property: "chainIcon"; value: model.chainIcon },
Bind { property: "accountName"; value: model.accountName },
Bind { property: "tokenOwnersModel"; value: model.tokenOwnersModel },
Bind { property: "assetDecimals"; value: model.decimals }
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 BindCollectible: Binding { target: view.collectible }
readonly property list<Binding> collectibleBindings: [
BindCollectible { property: "key"; value: model.contractUniqueKey },
BindCollectible { property: "deployState"; value: model.deployState },
BindCollectible { property: "burnState"; value: model.burnState },
BindCollectible { property: "name"; value: model.name },
BindCollectible { property: "artworkSource"; value: model.image },
BindCollectible { property: "symbol"; value: model.symbol },
BindCollectible { property: "description"; value: model.description },
BindCollectible { property: "supply"; value: model.supply },
BindCollectible { property: "infiniteSupply"; value: model.infiniteSupply },
BindCollectible { property: "remainingTokens"; value: model.remainingTokens },
BindCollectible { property: "chainId"; value: model.chainId },
BindCollectible { property: "chainName"; value: model.chainName },
BindCollectible { property: "chainIcon"; value: model.chainIcon },
BindCollectible { property: "accountName"; value: model.accountName },
BindCollectible { property: "accountAddress"; value: model.accountAddress }, // TODO: Backend
BindCollectible { property: "transferable"; value: model.transferable },
BindCollectible { property: "remotelyDestructState"; value: model.remotelyDestructState },
BindCollectible { property: "remotelyDestruct"; value: model.remoteSelfDestruct }
]
component BindAsset: Binding { target: view.asset }
readonly property list<Binding> assetBindings: [
BindAsset { property: "key"; value: model.contractUniqueKey },
BindAsset { property: "deployState"; value: model.deployState },
BindAsset { property: "burnState"; value: model.burnState },
BindAsset { property: "name"; value: model.name },
BindAsset { property: "artworkSource"; value: model.image },
BindAsset { property: "symbol"; value: model.symbol },
BindAsset { property: "description"; value: model.description },
BindAsset { property: "supply"; value: model.supply },
BindAsset { property: "infiniteSupply"; value: model.infiniteSupply },
BindAsset { property: "remainingTokens"; value: model.remainingTokens },
BindAsset { property: "chainId"; value: model.chainId },
BindAsset { property: "chainName"; value: model.chainName },
BindAsset { property: "chainIcon"; value: model.chainIcon },
BindAsset { property: "accountName"; value: model.accountName },
BindCollectible { property: "accountAddress"; value: model.accountAddress }, // TODO: Backend
BindAsset { property: "decimals"; value: model.decimals }
]
}
}
onGeneralAirdropRequested: {
root.airdropCollectible(view.symbol, [])
root.airdropToken(view.airdropKey, view.tokenType, []) // d.tokenKey instead when backend airdrop ready to use key instead of symbol
}
onAirdropRequested: {
root.airdropCollectible(view.symbol, [address])
root.airdropToken(view.airdropKey, view.tokenType, [address]) // d.tokenKey instead when backend airdrop ready to use key instead of symbol
}
onRemoteDestructRequested: {
@ -679,7 +601,9 @@ SettingsPageLayout {
// handle airdrop request from the footer
function onAirdropClicked() {
root.airdropCollectible(view.symbol, []) // TODO: Backend. It should just be the key (hash(chainId + contractAddress)
root.airdropToken(view.airdropKey, // d.tokenKey instead when backend airdrop ready to use key instead of symbol
view.tokenType,
[])
}
}
}

View File

@ -20,7 +20,7 @@ StatusDialog {
property string collectibleName
signal remotelyDestructClicked(int tokenCount, var selfDestructTokensList)
signal remotelyDestructClicked(int tokenCount, var remotelyDestructTokensList)
QtObject {
id: d

View File

@ -305,48 +305,18 @@ StatusSectionLayout {
onPreviousPageNameChanged: root.backButtonName = previousPageName
onSignMintTransactionOpened: communityTokensStore.computeDeployFee(chainId, accountAddress)
onMintCollectible: {
communityTokensStore.deployCollectible(root.community.id,
accountAddress,
name,
symbol,
description,
supply,
infiniteSupply,
transferable,
selfDestruct,
chainId,
artworkSource,
accountName,
artworkCropRect)
}
onMintAsset: {
communityTokensStore.deployAsset(root.community.id,
accountAddress,
name,
symbol,
description,
supply,
infiniteSupply,
decimals,
chainId,
artworkSource,
accountName,
artworkCropRect)
}
onSignSelfDestructTransactionOpened: communityTokensStore.computeSelfDestructFee(selfDestructTokensList, tokenKey)
onRemoteSelfDestructCollectibles: {
onMintCollectible: communityTokensStore.deployCollectible(root.community.id, collectibleItem)
onMintAsset: communityTokensStore.deployAsset(root.community.id, assetItem)
onSignRemoteDestructTransactionOpened: communityTokensStore.computeSelfDestructFee(remotelyDestructTokensList, tokenKey)
onRemotelyDestructCollectibles: {
communityTokensStore.remoteSelfDestructCollectibles(root.community.id,
selfDestructTokensList,
remotelyDestructTokensList,
tokenKey)
}
onSignBurnTransactionOpened: communityTokensStore.computeBurnFee(chainId)
onBurnCollectibles: communityTokensStore.burnCollectibles(tokenKey, amount)
onAirdropCollectible: {
root.goTo(Constants.CommunitySettingsSections.Airdrops)
}
onBurnToken: communityTokensStore.burnToken(tokenKey, amount)
onAirdropToken: root.goTo(Constants.CommunitySettingsSections.Airdrops)
onDeleteToken: communityTokensStore.deleteToken(root.community.id, tokenKey)
onRetryMintToken: communityTokensStore.retryMintToken(root.community.id, tokenKey)
Connections {
target: rootStore.communityTokensStore
@ -480,13 +450,13 @@ StatusSectionLayout {
Connections {
target: mintPanel
function onAirdropCollectible(key, addresses) {
function onAirdropToken(tokenKey, type, addresses) {
// Here it is forced a navigation to the new airdrop form, like if it was clicked the header button
airdropPanel.primaryHeaderButtonClicked()
// Force a token selection to be airdroped with default amount 1
airdropPanel.selectCollectible(key, 1)
airdropPanel.selectToken(tokenKey, 1, type)
// Set given addresses as recipients
airdropPanel.addAddresses(addresses)
}

View File

@ -17,7 +17,7 @@ StatusScrollView {
property int viewWidth: 560 // by design
property var model
signal itemClicked(string contractUniqueKey,
signal itemClicked(string tokenKey,
int chainId,
string chainName,
string accountName,

View File

@ -37,11 +37,17 @@ StatusScrollView {
signal airdropClicked(var airdropTokens, var addresses, var membersPubKeys)
signal navigateToMintTokenSettings
function selectCollectible(key, amount) {
const modelItem = CommunityPermissionsHelpers.getTokenByKey(
root.collectiblesModel, key)
function selectToken(key, amount, type) {
var tokenModel = null
if(type === Constants.TokenType.ERC20)
tokenModel = root.assetsModel
else if (type === Constants.TokenType.ERC721)
tokenModel = root.collectiblesModel
const entry = d.prepareEntry(key, amount)
const modelItem = CommunityPermissionsHelpers.getTokenByKey(
tokenModel, key)
const entry = d.prepareEntry(key, amount, type)
entry.valid = true
selectedHoldingsModel.append(entry)
}
@ -57,9 +63,14 @@ StatusScrollView {
readonly property int dropdownHorizontalOffset: 4
readonly property int dropdownVerticalOffset: 1
function prepareEntry(key, amount) {
const modelItem = CommunityPermissionsHelpers.getTokenByKey(
root.collectiblesModel, key)
function prepareEntry(key, amount, type) {
var tokenModel = null
if(type === Constants.TokenType.ERC20)
tokenModel = root.assetsModel
else if (type === Constants.TokenType.ERC721)
tokenModel = root.collectiblesModel
const modelItem = CommunityPermissionsHelpers.getTokenByKey(tokenModel, key)
return {
key, amount,
@ -170,7 +181,7 @@ StatusScrollView {
}
onAddCollectible: {
const entry = d.prepareEntry(key, amount)
const entry = d.prepareEntry(key, amount, Constants.TokenType.ERC721)
entry.valid = true
selectedHoldingsModel.append(entry)
@ -180,7 +191,7 @@ StatusScrollView {
onUpdateCollectible: {
const itemIndex = prepareUpdateIndex(key)
const entry = d.prepareEntry(key, amount)
const entry = d.prepareEntry(key, amount, Constants.TokenType.ERC721)
const modelItem = CommunityPermissionsHelpers.getTokenByKey(
root.collectiblesModel, key)

View File

@ -10,6 +10,7 @@ import StatusQ.Core.Utils 0.1 as SQUtils
import utils 1.0
import AppLayouts.Chat.helpers 1.0
import AppLayouts.Wallet.controls 1.0
import shared.panels 1.0
import shared.popups 1.0
@ -21,26 +22,10 @@ StatusScrollView {
property int viewWidth: 560 // by design
property bool isAssetView: false
// Token properties
readonly property alias name: nameInput.text
readonly property alias symbol: symbolInput.text
readonly property alias description: descriptionInput.text
readonly property alias infiniteSupply: unlimitedSupplyChecker.checked
readonly property int supplyAmount: supplyInput.text ? parseInt(supplyInput.text) : 0
property alias artworkSource: dropAreaItem.artworkSource
property alias artworkCropRect: dropAreaItem.artworkCropRect
property int chainId
property string chainName
property string chainIcon
property var tokensModel
// Collectible properties (ERC721)
readonly property alias notTransferable: transferableChecker.checked
readonly property alias selfDestruct: selfDestructChecker.checked
// Asset properties (ERC20)
readonly property int assetDecimals: assetDecimalsInput.text ? parseInt(assetDecimalsInput.text) : 0
property CollectibleObject collectible: CollectibleObject{}
property AssetObject asset: AssetObject{}
// Network related properties:
property var layer1Networks
@ -49,11 +34,8 @@ StatusScrollView {
property var enabledNetworks
property var allNetworks
// Account related properties:
// Account expected roles: address, name, color, emoji
property var accounts
readonly property string accountAddress: accountsComboBox.address
readonly property string accountName: accountsComboBox.control.displayText
signal chooseArtWork
signal previewClicked
@ -61,12 +43,12 @@ StatusScrollView {
QtObject {
id: d
readonly property bool isFullyFilled: root.artworkSource.toString().length > 0
readonly property bool isFullyFilled: dropAreaItem.artworkSource.toString().length > 0
&& nameInput.valid
&& descriptionInput.valid
&& symbolInput.valid
&& (root.infiniteSupply || (!root.infiniteSupply && root.supplyAmount > 0))
&& (!root.isAssetView || (root.isAssetView&& assetDecimalsInput.valid))
&& (unlimitedSupplyChecker.checked || (!unlimitedSupplyChecker.checked && parseInt(supplyInput.text) > 0))
&& (!root.isAssetView || (root.isAssetView && assetDecimalsInput.valid))
readonly property int imageSelectorRectWidth: root.isAssetView ? 128 : 290
}
@ -87,8 +69,10 @@ StatusScrollView {
DropAndEditImagePanel {
id: dropAreaItem
Layout.fillWidth: true
Layout.preferredHeight: d.imageSelectorRectWidth
artworkSource: root.isAssetView ? assetObj.artworkSource : collectibleObj.artworkSource
editorAnchorLeft: !root.isAssetView
editorRoundedImage: root.isAssetView
uploadTextLabel.uploadText: root.isAssetView ? qsTr("Upload") : qsTr("Drag and Drop or Upload Artwork")
@ -96,24 +80,46 @@ StatusScrollView {
uploadTextLabel.showAdditionalInfo: !root.isAssetView
editorTitle: root.isAssetView ? qsTr("Asset icon") : qsTr("Collectible artwork")
acceptButtonText: root.isAssetView ? qsTr("Upload asset icon") : qsTr("Upload collectible artwork")
onArtworkSourceChanged: {
if(root.isAssetView)
asset.artworkSource = artworkSource
else
collectible.artworkSource = artworkSource
}
onArtworkCropRectChanged: {
if(root.isAssetView)
asset.artworkCropRect = artworkCropRect
else
collectible.artworkCropRect = artworkCropRect
}
}
CustomStatusInput {
id: nameInput
label: qsTr("Name")
text: root.isAssetView ? asset.name : collectible.name
charLimit: 15
placeholderText: qsTr("Name")
minLengthValidator.errorMessage: qsTr("Please name your token name (use A-Z and 0-9, hyphens and underscores only)")
regexValidator.errorMessage: qsTr("Your token name contains invalid characters (use A-Z and 0-9, hyphens and underscores only)")
extraValidator.validate: function (value) { return !SQUtils.ModelUtils.contains(root.tokensModel, "name", nameInput.text) }
extraValidator.errorMessage: qsTr("You have used this token name before")
onTextChanged: {
if(root.isAssetView)
asset.name = text
else
collectible.name = text
}
}
CustomStatusInput {
id: descriptionInput
label: qsTr("Description")
text: root.isAssetView ? asset.description : collectible.description
charLimit: 280
placeholderText: root.isAssetView ? qsTr("Describe your asset") : qsTr("Describe your collectible")
input.multiline: true
@ -124,12 +130,20 @@ StatusScrollView {
minLengthValidator.errorMessage: qsTr("Please enter a token description")
regexValidator.regularExpression: Constants.regularExpressions.asciiPrintable
regexValidator.errorMessage: qsTr("Only A-Z, 0-9 and standard punctuation allowed")
onTextChanged: {
if(root.isAssetView)
asset.description = text
else
collectible.description = text
}
}
CustomStatusInput {
id: symbolInput
label: qsTr("Symbol")
text: root.isAssetView ? asset.symbol : collectible.symbol
charLimit: 6
placeholderText: qsTr("e.g. DOODLE")
minLengthValidator.errorMessage: qsTr("Please enter your token symbol (use A-Z only)")
@ -137,6 +151,13 @@ StatusScrollView {
regexValidator.regularExpression: Constants.regularExpressions.capitalOnly
extraValidator.validate: function (value) { return !SQUtils.ModelUtils.contains(root.tokensModel, "symbol", symbolInput.text) }
extraValidator.errorMessage: qsTr("You have used this token symbol before")
onTextChanged: {
if(root.isAssetView)
asset.symbol = text
else
collectible.symbol = text
}
}
CustomLabelDescriptionComponent {
@ -146,11 +167,15 @@ StatusScrollView {
}
StatusEmojiAndColorComboBox {
id: accountsComboBox
id: accountBox
readonly property string address: SQUtils.ModelUtils.get(root.accounts, currentIndex, "address")
readonly property string initAccountName: root.isAssetView ? asset.accountName : collectible.accountName
readonly property int initIndex: SQUtils.ModelUtils.indexOf(root.accounts, "name", initAccountName)
Layout.fillWidth: true
currentIndex: (initIndex !== -1) ? initIndex : 0
model: SortFilterProxyModel {
sourceModel: root.accounts
proxyRoles: [
@ -171,6 +196,19 @@ StatusScrollView {
size: StatusComboBox.Size.Small
implicitHeight: 44
defaultAssetName: "filled-account"
onAddressChanged: {
if(root.isAssetView)
asset.accountAddress = address
else
collectible.accountAddress = address
}
control.onDisplayTextChanged: {
if(root.isAssetView)
asset.accountName = control.displayText
else
collectible.accountName = control.displayText
}
}
CustomNetworkFilterRowComponent {
@ -183,9 +221,16 @@ StatusScrollView {
label: qsTr("Unlimited supply")
description: qsTr("Enable to allow the minting of additional tokens in the future. Disable to specify a finite supply")
checked: true
checked: root.isAssetView ? asset.infiniteSupply : collectible.infiniteSupply
onCheckedChanged: if(!checked) supplyInput.forceActiveFocus()
onCheckedChanged: {
if(!checked) supplyInput.forceActiveFocus()
if(root.isAssetView)
asset.infiniteSupply = checked
else
collectible.infiniteSupply = checked
}
}
CustomStatusInput {
@ -193,12 +238,20 @@ StatusScrollView {
visible: !unlimitedSupplyChecker.checked
label: qsTr("Total finite supply")
text: root.isAssetView ? asset.supply : collectible.supply
placeholderText: qsTr("e.g. 300")
minLengthValidator.errorMessage: qsTr("Please enter a total finite supply")
regexValidator.errorMessage: qsTr("Your total finite supply contains invalid characters (use 0-9 only)")
regexValidator.regularExpression: Constants.regularExpressions.numerical
extraValidator.validate: function (value) { return parseInt(value) > 0 && parseInt(value) <= 999999999 }
extraValidator.errorMessage: qsTr("Enter a number between 0 and 999,999,999")
onTextChanged: {
if(root.isAssetView)
asset.supply = parseInt(text)
else
collectible.supply = parseInt(text)
}
}
CustomSwitchRowComponent {
@ -207,16 +260,19 @@ StatusScrollView {
visible: !root.isAssetView
label: checked ? qsTr("Not transferable (Soulbound)") : qsTr("Transferable")
description: qsTr("If enabled, the token is locked to the first address it is sent to and can never be transferred to another address. Useful for tokens that represent Admin permissions")
checked: true
checked: !collectible.transferable
onCheckedChanged: collectible.transferable = !checked
}
CustomSwitchRowComponent {
id: selfDestructChecker
id: remotelyDestructChecker
visible: !root.isAssetView
label: qsTr("Remotely destructible")
description: qsTr("Enable to allow you to destroy tokens remotely. Useful for revoking permissions from individuals")
checked: true
checked: !!collectible ? collectible.remotelyDestruct : true
onCheckedChanged: collectible.remotelyDestruct = checked
}
CustomStatusInput {
@ -227,11 +283,13 @@ StatusScrollView {
charLimit: 2
charLimitLabel: qsTr("Max 10")
placeholderText: "2"
text: "2" // Default value
text: !!asset ? asset.decimals : ""
validationMode: StatusInput.ValidationMode.Always
minLengthValidator.errorMessage: qsTr("Please enter how many decimals your token should have")
regexValidator.errorMessage: qsTr("Your decimal amount contains invalid characters (use 0-9 only)")
regexValidator.regularExpression: Constants.regularExpressions.numerical
onTextChanged: asset.decimals = parseInt(text)
}
StatusButton {
@ -345,9 +403,15 @@ StatusScrollView {
onToggleNetwork: (network) =>
{
root.chainId = network.chainId
root.chainName = network.chainName
root.chainIcon = network.iconUrl
if(root.isAssetView) {
asset.chainId = network.chainId
asset.chainName = network.chainName
asset.chainIcon = network.iconUrl
} else {
collectible.chainId = network.chainId
collectible.chainName = network.chainName
collectible.chainIcon = network.iconUrl
}
}
}
}

View File

@ -11,6 +11,7 @@ import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0
import shared.panels 1.0
import AppLayouts.Chat.helpers 1.0
import AppLayouts.Chat.panels.communities 1.0
StatusScrollView {
@ -20,54 +21,24 @@ StatusScrollView {
property bool preview: false
property bool isAssetView: false
// Token properties
property alias artworkSource: image.source
property rect artworkCropRect
property string name
property alias symbol: symbolBox.value
property alias description: descriptionItem.text
property int supplyAmount
property int remainingTokens
property bool infiniteSupply
property CollectibleObject collectible
property AssetObject asset
property alias accountName: accountBox.value
property int chainId
property string chainIcon
property alias chainName: chainText.text
readonly property string name: root.isAssetView ? asset.name : collectible.name
readonly property string symbol: root.isAssetView ? asset.symbol : collectible.symbol
readonly property url artworkSource: root.isAssetView ? asset.artworkSource : collectible.artworkSource
readonly property bool infiniteSupply: root.isAssetView ? asset.infiniteSupply : collectible.infiniteSupply
readonly property int remainingTokens: root.isAssetView ? asset.remainingTokens : collectible.remainingTokens
readonly property int deployState: root.isAssetView ? asset.deployState : collectible.deployState
readonly property string accountName: root.isAssetView ? asset.accountName : collectible.accountName
readonly property string chainName: root.isAssetView ? asset.chainName : collectible.chainName
readonly property string chainId: root.isAssetView ? asset.chainId : collectible.chainId
readonly property string accountAddress: root.isAssetView ? asset.accountAddress : collectible.accountAddress
// Models:
property var tokenOwnersModel
property int deployState: Constants.ContractTransactionStatus.None
property int burnState: Constants.ContractTransactionStatus.None
// Collectible object properties (ERC721)
property bool transferable
property bool selfDestruct
property int remotelyDestructState: Constants.ContractTransactionStatus.None
// Asset properties (ERC20)
property alias assetDecimals: decimalsBox.value
signal mintCollectible(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
bool transferable,
bool selfDestruct,
int chainId,
string accountName)
signal mintAsset(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
int decimals,
int chainId,
string accountName)
signal mintClicked()
signal airdropRequested(string address)
signal generalAirdropRequested
@ -80,6 +51,7 @@ StatusScrollView {
readonly property int imageSelectorRectSize: root.isAssetView ? 104 : 280
readonly property int iconSize: 20
readonly property string infiniteSymbol: "∞"
readonly property int burnState: root.isAssetView ? asset.burnState : collectible.burnState
function startAnimation(isBurn) {
totalbox.highlighted = true
@ -87,13 +59,12 @@ StatusScrollView {
if(isBurn)
remainingBox.highlighted = true
}
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
}
padding: 0
onRemotelyDestructStateChanged: if(remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
ColumnLayout {
id: mainLayout
@ -105,9 +76,7 @@ StatusScrollView {
(root.deployState === Constants.ContractTransactionStatus.Failed))
spacing: Style.current.halfPadding
StatusDotsLoadingIndicator {
visible: (root.deployState === Constants.ContractTransactionStatus.InProgress)
}
StatusDotsLoadingIndicator { visible: (root.deployState === Constants.ContractTransactionStatus.InProgress) }
StatusIcon {
visible: (root.deployState === Constants.ContractTransactionStatus.Failed)
@ -138,10 +107,13 @@ StatusScrollView {
Image {
id: image
property rect imageCropRect: root.isAssetView ? asset.artworkCropRect : collectible.artworkCropRect
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
sourceClipRect: root.artworkCropRect ? root.artworkCropRect : undefined
source: root.artworkSource
sourceClipRect: imageCropRect ? imageCropRect : undefined
}
OpacityMask {
@ -234,16 +206,19 @@ StatusScrollView {
id: symbolBox
label: qsTr("Symbol")
value: root.symbol
}
CustomPreviewBox {
id: totalbox
property int supply: root.isAssetView ? asset.supply : collectible.supply
label: qsTr("Total")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.supplyAmount)
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(supply)
isLoading: !root.infiniteSupply &&
((root.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(root.burnState === Constants.ContractTransactionStatus.InProgress))
((!root.isAssetView && collectible.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(d.burnState === Constants.ContractTransactionStatus.InProgress))
}
CustomPreviewBox {
@ -251,32 +226,30 @@ StatusScrollView {
label: qsTr("Remaining")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.remainingTokens)
isLoading: !root.infiniteSupply && (root.burnState === Constants.ContractTransactionStatus.InProgress)
isLoading: !root.infiniteSupply && (d.burnState === Constants.ContractTransactionStatus.InProgress)
}
CustomPreviewBox {
id: decimalsBox
visible: root.isAssetView
label: qsTr("DP")
value: asset.decimals
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Transferable")
value: root.transferable ? qsTr("Yes") : qsTr("No")
value: collectible.transferable ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Remotely destructible")
value: root.selfDestruct ? qsTr("Yes") : qsTr("No")
value: collectible.remotelyDestruct ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
id: accountBox
label: qsTr("Account")
value: root.accountName
}
Rectangle {
@ -294,18 +267,17 @@ StatusScrollView {
spacing: Style.current.padding
SVGImage {
id: chainIcon
Layout.alignment: Qt.AlignVCenter
height: 24
width: height
source: Style.svg(root.chainIcon)
source: Style.svg(root.isAssetView ? asset.chainIcon : collectible.chainIcon)
}
StatusBaseText {
id: chainText
Layout.alignment: Qt.AlignVCenter
text: root.chainName
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
@ -315,9 +287,9 @@ StatusScrollView {
}
StatusBaseText {
id: descriptionItem
Layout.fillWidth: true
text: root.isAssetView ? asset.description : collectible.description
wrapMode: TextEdit.WordWrap
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
@ -352,30 +324,7 @@ StatusScrollView {
Layout.topMargin: Style.current.halfPadding
text: qsTr("Mint")
onClicked: {
if(root.isAssetView) {
root.mintAsset(root.artworkSource,
root.name,
root.symbol,
root.description,
root.supplyAmount,
root.infiniteSupply,
root.assetDecimals,
root.chainId,
root.accountName)
} else {
root.mintCollectible(root.artworkSource,
root.name,
root.symbol,
root.description,
root.supplyAmount,
root.infiniteSupply,
root.transferable,
root.selfDestruct,
root.chainId,
root.accountName)
}
}
onClicked: root.mintClicked()
}
SortableTokenHoldersPanel {
@ -383,7 +332,7 @@ StatusScrollView {
model: root.tokenOwnersModel
tokenName: root.name
showRemotelyDestructMenuItem: !root.isAssetView && root.selfDestruct
showRemotelyDestructMenuItem: !root.isAssetView && collectible.remotelyDestruct
Layout.topMargin: Style.current.padding
Layout.fillWidth: true
@ -393,4 +342,12 @@ StatusScrollView {
onRemoteDestructRequested: root.remoteDestructRequested(address)
}
}
Connections {
target: collectible
function onRemotelyDestructStateChanged() {
if(collectible.remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
}
}
}

View File

@ -23,22 +23,26 @@ QtObject {
signal remoteDestructStateChanged(string communityId, string tokenName, int status, string url)
// Minting tokens:
function deployCollectible(communityId, accountAddress, name, symbol, description, supply,
infiniteSupply, transferable, selfDestruct, chainId, artworkSource, accountName, artworkCropRect)
{
function deployCollectible(communityId, collectibleItem)
{
// TODO: Backend needs to create new role `accountName` and update this call accordingly
// TODO: Backend will need to check if the collectibleItem has a valid tokenKey, so it means a deployment retry,
// otherwise, it is a new deployment.
// TODO: Backend needs to modify the call to expect an image JSON file with cropped artwork information:
const jsonArtworkFile = Utils.getImageAndCropInfoJson(artworkSource, artworkCropRect)
communityTokensModuleInst.deployCollectible(communityId, accountAddress, name, symbol, description, supply,
infiniteSupply, transferable, selfDestruct, chainId, artworkSource/*instead: jsonArtworkFile*/)
const jsonArtworkFile = Utils.getImageAndCropInfoJson(collectibleItem.artworkSource, collectibleItem.artworkCropRect)
communityTokensModuleInst.deployCollectible(communityId, collectibleItem.accountAddress, collectibleItem.name,
collectibleItem.symbol, collectibleItem.description, collectibleItem.supply,
collectibleItem.infiniteSupply, collectibleItem.transferable, collectibleItem.remotelyDestruct,
collectibleItem.chainId, collectibleItem.artworkSource/*instead: jsonArtworkFile*/)
}
function deployAsset(communityId, accountAddress, name, symbol, description, supply,
infiniteSupply, decimals, chainId, artworkSource, accountName, artworkCropRect)
function deployAsset(communityId, assetItem)
{
// TODO: Backend needs to create new role `accountName` and update this call accordingly
// TODO: Backend will need to check if the collectibleItem has a valid tokenKey, so it means a deployment retry,
// otherwise, it is a new deployment.
// TODO: Backend needs to modify the call to expect an image JSON file with cropped artwork information:
const jsonArtworkFile = Utils.getImageAndCropInfoJson(artworkSource, artworkCropRect)
const jsonArtworkFile = Utils.getImageAndCropInfoJson(assetItem.artworkSource, assetItem.artworkCropRect)
console.log("TODO: Deploy Asset backend!")
}
@ -46,10 +50,6 @@ QtObject {
console.log("TODO: Delete token bakend!")
}
function retryMintToken(communityId, contractUniqueKey) {
console.log("TODO: Retry mint token bakend!")
}
readonly property Connections connections: Connections {
target: communityTokensModuleInst
function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode) {
@ -85,7 +85,7 @@ QtObject {
console.warn("TODO: Compute burn fee backend")
}
function burnCollectibles(tokenKey, burnAmount) {
function burnToken(tokenKey, burnAmount) {
// TODO BACKEND
console.warn("TODO: Burn collectible backend")
}