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:
parent
02baf36070
commit
f58f82d4c6
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
singleton CommunityPermissionsHelpers 1.0 CommunityPermissionsHelpers.qml
|
||||
AssetObject 1.0 AssetObject.qml
|
||||
CollectibleObject 1.0 CollectibleObject.qml
|
||||
TokenObject 1.0 TokenObject.qml
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
[])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ StatusDialog {
|
|||
|
||||
property string collectibleName
|
||||
|
||||
signal remotelyDestructClicked(int tokenCount, var selfDestructTokensList)
|
||||
signal remotelyDestructClicked(int tokenCount, var remotelyDestructTokensList)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue