feat(MintToken) Add select wallet account option

- Added accounts selector in `Create new token` page.
- Added account name box in `Preview` page.
- Updated `storybook` with new account data.
- Updated `deployCollectible` method call account address property.

Closes #9842
This commit is contained in:
Noelia 2023-03-17 16:09:27 +01:00 committed by Noelia
parent 87f42e6074
commit f691c85127
11 changed files with 185 additions and 100 deletions

View File

@ -38,6 +38,7 @@ SplitView {
chainId: 1 chainId: 1
chainName: "Ethereum Mainnet" chainName: "Ethereum Mainnet"
chainIcon: ModelsData.networks.ethereum chainIcon: ModelsData.networks.ethereum
accountName: "helloworld"
onMintCollectible: logs.logEvent("CommunityCollectibleView::mintCollectible: \n" onMintCollectible: logs.logEvent("CommunityCollectibleView::mintCollectible: \n"
+ "artworkSource: " + artworkSource + "\n" + "artworkSource: " + artworkSource + "\n"

View File

@ -29,7 +29,8 @@ SplitView {
layer2Networks: NetworksModel.layer2Networks layer2Networks: NetworksModel.layer2Networks
testNetworks: NetworksModel.testNetworks testNetworks: NetworksModel.testNetworks
enabledNetworks: NetworksModel.enabledNetworks enabledNetworks: NetworksModel.enabledNetworks
allNetworks: enabledNetworks allNetworks: enabledNetworks
accounts: WalletAccountsModel {}
onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible") onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible")
} }

View File

@ -32,6 +32,7 @@ SplitView {
testNetworks: NetworksModel.testNetworks testNetworks: NetworksModel.testNetworks
enabledNetworks: NetworksModel.enabledNetworks enabledNetworks: NetworksModel.enabledNetworks
allNetworks: enabledNetworks allNetworks: enabledNetworks
accounts: WalletAccountsModel {}
onPreviewClicked: logs.logEvent("CommunityNewCollectibleView::previewClicked") onPreviewClicked: logs.logEvent("CommunityNewCollectibleView::previewClicked")
} }

View File

@ -0,0 +1,6 @@
import QtQuick 2.15
ListModel {
ListElement { name: "Test account"; emoji: "😋"; color: "red"; address: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240" }
ListElement { name: "Another account"; emoji: "🚗"; color: "blue"; address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8888" }
}

View File

@ -10,3 +10,4 @@ ChannelsModel 1.0 ChannelsModel.qml
AssetsCollectiblesIconsModel 1.0 AssetsCollectiblesIconsModel.qml AssetsCollectiblesIconsModel 1.0 AssetsCollectiblesIconsModel.qml
MintedCollectiblesModel 1.0 MintedCollectiblesModel.qml MintedCollectiblesModel 1.0 MintedCollectiblesModel.qml
TokenHoldersModel 1.0 TokenHoldersModel.qml TokenHoldersModel 1.0 TokenHoldersModel.qml
WalletAccountsModel 1.0 WalletAccountsModel.qml

View File

@ -27,6 +27,9 @@ SettingsPageLayout {
property var enabledNetworks property var enabledNetworks
property var allNetworks property var allNetworks
// Account expected roles: address, name, color, emoji
property var accounts
property int viewWidth: 560 // by design property int viewWidth: 560 // by design
signal mintCollectible(url artworkSource, signal mintCollectible(url artworkSource,
@ -37,7 +40,9 @@ SettingsPageLayout {
bool infiniteSupply, bool infiniteSupply,
bool transferable, bool transferable,
bool selfDestruct, bool selfDestruct,
int chainId) int chainId,
string accountName,
string accountAddress)
function navigateBack() { function navigateBack() {
stackManager.pop(StackView.Immediate) stackManager.pop(StackView.Immediate)
@ -59,6 +64,7 @@ SettingsPageLayout {
property bool preview: false property bool preview: false
property string collectibleName property string collectibleName
property string accountAddress
readonly property var initialItem: (root.tokensModel && root.tokensModel.count > 0) ? mintedTokensView : welcomeView readonly property var initialItem: (root.tokensModel && root.tokensModel.count > 0) ? mintedTokensView : welcomeView
} }
@ -145,9 +151,11 @@ SettingsPageLayout {
testNetworks: root.testNetworks testNetworks: root.testNetworks
enabledNetworks: root.testNetworks enabledNetworks: root.testNetworks
allNetworks: root.allNetworks allNetworks: root.allNetworks
accounts: root.accounts
onPreviewClicked: { onPreviewClicked: {
d.collectibleName = name d.collectibleName = name
d.accountAddress = accountAddress
stackManager.push(d.previewCollectibleViewState, stackManager.push(d.previewCollectibleViewState,
collectibleView, collectibleView,
{ {
@ -161,7 +169,8 @@ SettingsPageLayout {
selfDestruct, selfDestruct,
chainId, chainId,
chainName, chainName,
chainIcon chainIcon,
accountName
}, },
StackView.Immediate) StackView.Immediate)
} }
@ -186,7 +195,9 @@ SettingsPageLayout {
infiniteSupply, infiniteSupply,
transferable, transferable,
selfDestruct, selfDestruct,
chainId) chainId,
accountName,
d.accountAddress)
stackManager.clear(d.initialViewState, StackView.Immediate) stackManager.clear(d.initialViewState, StackView.Immediate)
} }
@ -226,7 +237,8 @@ SettingsPageLayout {
remoteSelfDestruct, remoteSelfDestruct,
chainId, chainId,
chainName, chainName,
chainIcon chainIcon,
accountName
}, },
StackView.Immediate) StackView.Immediate)
} }

View File

@ -7,10 +7,11 @@ QtObject {
property var communityTokensModuleInst: communityTokensModule ?? null property var communityTokensModuleInst: communityTokensModule ?? null
// Minting tokens: // Minting tokens:
function deployCollectible(communityId, address, name, symbol, description, supply, function deployCollectible(communityId, accountAddress, name, symbol, description, supply,
infiniteSupply, transferable, selfDestruct, chainId, artworkSource) infiniteSupply, transferable, selfDestruct, chainId, artworkSource, accountName)
{ {
communityTokensModuleInst.deployCollectible(communityId, address, name, symbol, description, supply, // TODO: Backend needs to create new role `accountName` and update this call accordingly
communityTokensModuleInst.deployCollectible(communityId, accountAddress, name, symbol, description, supply,
infiniteSupply, transferable, selfDestruct, chainId, artworkSource) infiniteSupply, transferable, selfDestruct, chainId, artworkSource)
} }

View File

@ -293,11 +293,12 @@ StatusSectionLayout {
testNetworks: communityTokensStore.testNetworks testNetworks: communityTokensStore.testNetworks
enabledNetworks: communityTokensStore.enabledNetworks enabledNetworks: communityTokensStore.enabledNetworks
allNetworks: communityTokensStore.allNetworks allNetworks: communityTokensStore.allNetworks
accounts: root.rootStore.accounts
onPreviousPageNameChanged: root.backButtonName = previousPageName onPreviousPageNameChanged: root.backButtonName = previousPageName
onMintCollectible: { onMintCollectible: {
communityTokensStore.deployCollectible(root.community.id, communityTokensStore.deployCollectible(root.community.id,
root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/ accountAddress,
name, name,
symbol, symbol,
description, description,
@ -306,7 +307,8 @@ StatusSectionLayout {
transferable, transferable,
selfDestruct, selfDestruct,
chainId, chainId,
artworkSource) artworkSource,
accountName)
} }
} }

View File

@ -31,6 +31,7 @@ StatusScrollView {
property int chainId property int chainId
property string chainIcon property string chainIcon
property int deployState property int deployState
property alias accountName: accountBox.value
signal mintCollectible(url artworkSource, signal mintCollectible(url artworkSource,
string name, string name,
@ -40,7 +41,8 @@ StatusScrollView {
bool infiniteSupply, bool infiniteSupply,
bool transferable, bool transferable,
bool selfDestruct, bool selfDestruct,
int chainId) int chainId,
string accountName)
QtObject { QtObject {
id: d id: d
@ -167,6 +169,13 @@ StatusScrollView {
leftAlignment: false leftAlignment: false
} }
CustomPreviewBox {
id: accountBox
label: qsTr("Account")
leftAlignment: false
}
Rectangle { Rectangle {
height: symbolBox.height height: symbolBox.height
width: rowChain.implicitWidth + 2 * Style.current.padding width: rowChain.implicitWidth + 2 * Style.current.padding
@ -240,7 +249,8 @@ StatusScrollView {
root.infiniteSupply, root.infiniteSupply,
root.transferable, root.transferable,
root.selfDestruct, root.selfDestruct,
root.chainId) root.chainId,
root.accountName)
} }
} }

View File

@ -26,7 +26,8 @@ StatusScrollView {
bool remoteSelfDestruct, bool remoteSelfDestruct,
int chainId, int chainId,
string chainName, string chainName,
string chainIcon) string chainIcon,
string accountName)
enum DeployState { enum DeployState {
@ -81,7 +82,7 @@ StatusScrollView {
subTitle: d.getStateText(model.deployState) subTitle: d.getStateText(model.deployState)
imageUrl: model.image ? model.image : "" imageUrl: model.image ? model.image : ""
backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent" // TODO BACKEND backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent" // TODO BACKEND
isLoading: false// model.isLoading // TODO BACKEND isLoading: false
navigationIconVisible: true navigationIconVisible: true
onClicked: root.itemClicked(model.deployState, onClicked: root.itemClicked(model.deployState,
@ -95,7 +96,8 @@ StatusScrollView {
model.remoteSelfDestruct, model.remoteSelfDestruct,
model.chainId, model.chainId,
model.chainName, model.chainName,
model.chainIcon) model.chainIcon,
model.accountName)
} }

View File

@ -5,6 +5,8 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1 import StatusQ.Controls.Validators 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
import utils 1.0 import utils 1.0
@ -17,13 +19,13 @@ StatusScrollView {
property int viewWidth: 560 // by design property int viewWidth: 560 // by design
// Collectible properties // Collectible properties
property alias name: nameInput.text readonly property alias name: nameInput.text
property alias symbol: symbolInput.text readonly property alias symbol: symbolInput.text
property alias description: descriptionInput.text readonly property alias description: descriptionInput.text
property alias supplyText: supplyInput.text readonly property alias supplyText: supplyInput.text
property alias infiniteSupply: unlimitedSupplyChecker.checked readonly property alias infiniteSupply: unlimitedSupplyChecker.checked
property alias transferable: transferableChecker.checked readonly property alias transferable: transferableChecker.checked
property alias selfDestruct: selfDestructChecker.checked readonly property alias selfDestruct: selfDestructChecker.checked
property url artworkSource property url artworkSource
property int chainId property int chainId
property string chainName property string chainName
@ -36,6 +38,12 @@ StatusScrollView {
property var enabledNetworks property var enabledNetworks
property var allNetworks 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 chooseArtWork
signal previewClicked signal previewClicked
@ -74,25 +82,6 @@ StatusScrollView {
onFileSelected: root.artworkSource = file onFileSelected: root.artworkSource = file
} }
component CustomStatusInput: StatusInput {
id: customInput
property string errorText
Layout.fillWidth: true
validators: [
StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(root.errors,
customInput.errorText)
},
StatusRegularExpressionValidator {
regularExpression: Constants.regularExpressions.alphanumericalExpanded
errorMessage: Constants.errorMessages.alphanumericalExpandedRegExp
}
]
}
CustomStatusInput { CustomStatusInput {
id: nameInput id: nameInput
@ -125,71 +114,31 @@ StatusScrollView {
errorText: qsTr("Token symbol") errorText: qsTr("Token symbol")
} }
component CustomRowComponent: RowLayout { CustomLabelDescriptionComponent {
id: rowComponent Layout.topMargin: Style.current.padding
label: qsTr("Select account")
description: qsTr("The account on which this token will be minted")
}
property string label StatusEmojiAndColorComboBox {
property string description id: accountsComboBox
property bool checked
property bool isSwitchCase: true readonly property string address: ModelUtils.get(root.accounts, currentIndex, "address")
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 24 model: root.accounts
spacing: rowComponent.isSwitchCase ? 64 : 32 type: StatusComboBox.Type.Secondary
size: StatusComboBox.Size.Small
ColumnLayout { implicitHeight: 44
Layout.fillWidth: true defaultAssetName: "filled-account"
StatusBaseText {
text: rowComponent.label
color: Theme.palette.directColor1
font.pixelSize: Theme.primaryTextFontSize
}
StatusBaseText {
Layout.fillWidth: true
Layout.fillHeight: true
text: rowComponent.description
color: Theme.palette.baseColor1
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
wrapMode: Text.WordWrap
}
}
StatusSwitch {
visible: rowComponent.isSwitchCase
checked: rowComponent.checked
onToggled: rowComponent.checked = checked
}
NetworkFilter {
visible: !rowComponent.isSwitchCase
Layout.preferredWidth: 160
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
enabledNetworks: root.enabledNetworks
allNetworks: root.allNetworks
isChainVisible: false
multiSelection: false
onSingleNetworkSelected: {
root.chainId = chainId
root.chainName = chainName
root.chainIcon = chainIcon
}
}
} }
CustomRowComponent { CustomNetworkFilterRowComponent {
label: qsTr("Select network") label: qsTr("Select network")
description: qsTr("The network on which this token will be minted") description: qsTr("The network on which this token will be minted")
checked: true
isSwitchCase: false
} }
CustomRowComponent { CustomSwitchRowComponent {
id: unlimitedSupplyChecker id: unlimitedSupplyChecker
label: qsTr("Unlimited supply") label: qsTr("Unlimited supply")
@ -206,15 +155,15 @@ StatusScrollView {
validators: StatusIntValidator{bottom: 1; top: 999999999;} validators: StatusIntValidator{bottom: 1; top: 999999999;}
} }
CustomRowComponent { CustomSwitchRowComponent {
id: transferableChecker id: transferableChecker
label: qsTr("Not transferable (Soulbound)") 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") 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: true
} }
CustomRowComponent { CustomSwitchRowComponent {
id: selfDestructChecker id: selfDestructChecker
label: qsTr("Remote self-destruct") label: qsTr("Remote self-destruct")
@ -234,4 +183,103 @@ StatusScrollView {
onClicked: root.previewClicked() onClicked: root.previewClicked()
} }
} }
// Inline components definition:
component CustomStatusInput: StatusInput {
id: customInput
property string errorText
Layout.fillWidth: true
validators: [
StatusMinLengthValidator {
minLength: 1
errorMessage: Utils.getErrorMessage(customInput.errors,
customInput.errorText)
},
StatusRegularExpressionValidator {
regularExpression: Constants.regularExpressions.alphanumericalExpanded
errorMessage: Constants.errorMessages.alphanumericalExpandedRegExp
}
]
}
component CustomLabelDescriptionComponent: ColumnLayout {
id: labelDescComponent
property string label
property string description
Layout.fillWidth: true
StatusBaseText {
text: labelDescComponent.label
color: Theme.palette.directColor1
font.pixelSize: Theme.primaryTextFontSize
}
StatusBaseText {
Layout.fillWidth: true
Layout.fillHeight: true
text: labelDescComponent.description
color: Theme.palette.baseColor1
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
wrapMode: Text.WordWrap
}
}
component CustomSwitchRowComponent: RowLayout {
id: rowComponent
property string label
property string description
property alias checked: switch_.checked
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
spacing: 64
CustomLabelDescriptionComponent {
label: rowComponent.label
description: rowComponent.description
}
StatusSwitch {
id: switch_
}
}
component CustomNetworkFilterRowComponent: RowLayout {
id: networkComponent
property string label
property string description
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
spacing: 32
CustomLabelDescriptionComponent {
label: networkComponent.label
description: networkComponent.description
}
NetworkFilter {
Layout.preferredWidth: 160
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
enabledNetworks: root.enabledNetworks
allNetworks: root.allNetworks
isChainVisible: false
multiSelection: false
onSingleNetworkSelected: {
root.chainId = chainId
root.chainName = chainName
root.chainIcon = chainIcon
}
}
}
} }