From f691c8512729a722a2784dc3eeb7e712a9bb5db8 Mon Sep 17 00:00:00 2001 From: Noelia Date: Fri, 17 Mar 2023 16:09:27 +0100 Subject: [PATCH] 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 --- .../pages/CommunityCollectibleViewPage.qml | 1 + .../CommunityMintTokensSettingsPanelPage.qml | 3 +- .../pages/CommunityNewCollectibleViewPage.qml | 1 + storybook/src/Models/WalletAccountsModel.qml | 6 + storybook/src/Models/qmldir | 1 + .../CommunityMintTokensSettingsPanel.qml | 20 +- .../Chat/stores/CommunityTokensStore.qml | 7 +- .../Chat/views/CommunitySettingsView.qml | 6 +- .../communities/CommunityCollectibleView.qml | 14 +- .../communities/CommunityMintedTokensView.qml | 8 +- .../CommunityNewCollectibleView.qml | 218 +++++++++++------- 11 files changed, 185 insertions(+), 100 deletions(-) create mode 100644 storybook/src/Models/WalletAccountsModel.qml diff --git a/storybook/pages/CommunityCollectibleViewPage.qml b/storybook/pages/CommunityCollectibleViewPage.qml index df20980055..adbcfe631a 100644 --- a/storybook/pages/CommunityCollectibleViewPage.qml +++ b/storybook/pages/CommunityCollectibleViewPage.qml @@ -38,6 +38,7 @@ SplitView { chainId: 1 chainName: "Ethereum Mainnet" chainIcon: ModelsData.networks.ethereum + accountName: "helloworld" onMintCollectible: logs.logEvent("CommunityCollectibleView::mintCollectible: \n" + "artworkSource: " + artworkSource + "\n" diff --git a/storybook/pages/CommunityMintTokensSettingsPanelPage.qml b/storybook/pages/CommunityMintTokensSettingsPanelPage.qml index 9a2e3dd45c..0095349984 100644 --- a/storybook/pages/CommunityMintTokensSettingsPanelPage.qml +++ b/storybook/pages/CommunityMintTokensSettingsPanelPage.qml @@ -29,7 +29,8 @@ SplitView { layer2Networks: NetworksModel.layer2Networks testNetworks: NetworksModel.testNetworks enabledNetworks: NetworksModel.enabledNetworks - allNetworks: enabledNetworks + allNetworks: enabledNetworks + accounts: WalletAccountsModel {} onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible") } diff --git a/storybook/pages/CommunityNewCollectibleViewPage.qml b/storybook/pages/CommunityNewCollectibleViewPage.qml index 428dcf6dfc..e430efb55a 100644 --- a/storybook/pages/CommunityNewCollectibleViewPage.qml +++ b/storybook/pages/CommunityNewCollectibleViewPage.qml @@ -32,6 +32,7 @@ SplitView { testNetworks: NetworksModel.testNetworks enabledNetworks: NetworksModel.enabledNetworks allNetworks: enabledNetworks + accounts: WalletAccountsModel {} onPreviewClicked: logs.logEvent("CommunityNewCollectibleView::previewClicked") } diff --git a/storybook/src/Models/WalletAccountsModel.qml b/storybook/src/Models/WalletAccountsModel.qml new file mode 100644 index 0000000000..544f69c1ea --- /dev/null +++ b/storybook/src/Models/WalletAccountsModel.qml @@ -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" } +} diff --git a/storybook/src/Models/qmldir b/storybook/src/Models/qmldir index 16e3ad2858..2a94161226 100644 --- a/storybook/src/Models/qmldir +++ b/storybook/src/Models/qmldir @@ -10,3 +10,4 @@ ChannelsModel 1.0 ChannelsModel.qml AssetsCollectiblesIconsModel 1.0 AssetsCollectiblesIconsModel.qml MintedCollectiblesModel 1.0 MintedCollectiblesModel.qml TokenHoldersModel 1.0 TokenHoldersModel.qml +WalletAccountsModel 1.0 WalletAccountsModel.qml diff --git a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml index 2d5fab4407..4aa44395f3 100644 --- a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml @@ -27,6 +27,9 @@ SettingsPageLayout { property var enabledNetworks property var allNetworks + // Account expected roles: address, name, color, emoji + property var accounts + property int viewWidth: 560 // by design signal mintCollectible(url artworkSource, @@ -37,7 +40,9 @@ SettingsPageLayout { bool infiniteSupply, bool transferable, bool selfDestruct, - int chainId) + int chainId, + string accountName, + string accountAddress) function navigateBack() { stackManager.pop(StackView.Immediate) @@ -59,6 +64,7 @@ SettingsPageLayout { property bool preview: false property string collectibleName + property string accountAddress readonly property var initialItem: (root.tokensModel && root.tokensModel.count > 0) ? mintedTokensView : welcomeView } @@ -145,9 +151,11 @@ SettingsPageLayout { testNetworks: root.testNetworks enabledNetworks: root.testNetworks allNetworks: root.allNetworks + accounts: root.accounts onPreviewClicked: { d.collectibleName = name + d.accountAddress = accountAddress stackManager.push(d.previewCollectibleViewState, collectibleView, { @@ -161,7 +169,8 @@ SettingsPageLayout { selfDestruct, chainId, chainName, - chainIcon + chainIcon, + accountName }, StackView.Immediate) } @@ -186,7 +195,9 @@ SettingsPageLayout { infiniteSupply, transferable, selfDestruct, - chainId) + chainId, + accountName, + d.accountAddress) stackManager.clear(d.initialViewState, StackView.Immediate) } @@ -226,7 +237,8 @@ SettingsPageLayout { remoteSelfDestruct, chainId, chainName, - chainIcon + chainIcon, + accountName }, StackView.Immediate) } diff --git a/ui/app/AppLayouts/Chat/stores/CommunityTokensStore.qml b/ui/app/AppLayouts/Chat/stores/CommunityTokensStore.qml index 10a29d2303..d73cb61491 100644 --- a/ui/app/AppLayouts/Chat/stores/CommunityTokensStore.qml +++ b/ui/app/AppLayouts/Chat/stores/CommunityTokensStore.qml @@ -7,10 +7,11 @@ QtObject { property var communityTokensModuleInst: communityTokensModule ?? null // Minting tokens: - function deployCollectible(communityId, address, name, symbol, description, supply, - infiniteSupply, transferable, selfDestruct, chainId, artworkSource) + function deployCollectible(communityId, accountAddress, name, symbol, description, supply, + 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) } diff --git a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml index 336b06a300..84a82d4ec2 100644 --- a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml +++ b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml @@ -293,11 +293,12 @@ StatusSectionLayout { testNetworks: communityTokensStore.testNetworks enabledNetworks: communityTokensStore.enabledNetworks allNetworks: communityTokensStore.allNetworks + accounts: root.rootStore.accounts onPreviousPageNameChanged: root.backButtonName = previousPageName onMintCollectible: { communityTokensStore.deployCollectible(root.community.id, - root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/ + accountAddress, name, symbol, description, @@ -306,7 +307,8 @@ StatusSectionLayout { transferable, selfDestruct, chainId, - artworkSource) + artworkSource, + accountName) } } diff --git a/ui/app/AppLayouts/Chat/views/communities/CommunityCollectibleView.qml b/ui/app/AppLayouts/Chat/views/communities/CommunityCollectibleView.qml index e87be87819..437eba346c 100644 --- a/ui/app/AppLayouts/Chat/views/communities/CommunityCollectibleView.qml +++ b/ui/app/AppLayouts/Chat/views/communities/CommunityCollectibleView.qml @@ -31,6 +31,7 @@ StatusScrollView { property int chainId property string chainIcon property int deployState + property alias accountName: accountBox.value signal mintCollectible(url artworkSource, string name, @@ -40,7 +41,8 @@ StatusScrollView { bool infiniteSupply, bool transferable, bool selfDestruct, - int chainId) + int chainId, + string accountName) QtObject { id: d @@ -167,6 +169,13 @@ StatusScrollView { leftAlignment: false } + CustomPreviewBox { + id: accountBox + + label: qsTr("Account") + leftAlignment: false + } + Rectangle { height: symbolBox.height width: rowChain.implicitWidth + 2 * Style.current.padding @@ -240,7 +249,8 @@ StatusScrollView { root.infiniteSupply, root.transferable, root.selfDestruct, - root.chainId) + root.chainId, + root.accountName) } } diff --git a/ui/app/AppLayouts/Chat/views/communities/CommunityMintedTokensView.qml b/ui/app/AppLayouts/Chat/views/communities/CommunityMintedTokensView.qml index 0aab1c54d5..cb1d401ab6 100644 --- a/ui/app/AppLayouts/Chat/views/communities/CommunityMintedTokensView.qml +++ b/ui/app/AppLayouts/Chat/views/communities/CommunityMintedTokensView.qml @@ -26,7 +26,8 @@ StatusScrollView { bool remoteSelfDestruct, int chainId, string chainName, - string chainIcon) + string chainIcon, + string accountName) enum DeployState { @@ -81,7 +82,7 @@ StatusScrollView { subTitle: d.getStateText(model.deployState) imageUrl: model.image ? model.image : "" backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent" // TODO BACKEND - isLoading: false// model.isLoading // TODO BACKEND + isLoading: false navigationIconVisible: true onClicked: root.itemClicked(model.deployState, @@ -95,7 +96,8 @@ StatusScrollView { model.remoteSelfDestruct, model.chainId, model.chainName, - model.chainIcon) + model.chainIcon, + model.accountName) } diff --git a/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml b/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml index 46b2a5b807..bf8712ca13 100644 --- a/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml +++ b/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml @@ -5,6 +5,8 @@ import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 import StatusQ.Controls.Validators 0.1 +import StatusQ.Components 0.1 +import StatusQ.Core.Utils 0.1 import utils 1.0 @@ -17,13 +19,13 @@ StatusScrollView { property int viewWidth: 560 // by design // Collectible properties - property alias name: nameInput.text - property alias symbol: symbolInput.text - property alias description: descriptionInput.text - property alias supplyText: supplyInput.text - property alias infiniteSupply: unlimitedSupplyChecker.checked - property alias transferable: transferableChecker.checked - property alias selfDestruct: selfDestructChecker.checked + readonly property alias name: nameInput.text + readonly property alias symbol: symbolInput.text + readonly property alias description: descriptionInput.text + readonly property alias supplyText: supplyInput.text + readonly property alias infiniteSupply: unlimitedSupplyChecker.checked + readonly property alias transferable: transferableChecker.checked + readonly property alias selfDestruct: selfDestructChecker.checked property url artworkSource property int chainId property string chainName @@ -36,6 +38,12 @@ 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 @@ -74,25 +82,6 @@ StatusScrollView { 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 { id: nameInput @@ -125,71 +114,31 @@ StatusScrollView { errorText: qsTr("Token symbol") } - component CustomRowComponent: RowLayout { - id: rowComponent + CustomLabelDescriptionComponent { + Layout.topMargin: Style.current.padding + label: qsTr("Select account") + description: qsTr("The account on which this token will be minted") + } - property string label - property string description - property bool checked - property bool isSwitchCase: true + StatusEmojiAndColorComboBox { + id: accountsComboBox + + readonly property string address: ModelUtils.get(root.accounts, currentIndex, "address") Layout.fillWidth: true - Layout.topMargin: 24 - spacing: rowComponent.isSwitchCase ? 64 : 32 - - ColumnLayout { - Layout.fillWidth: true - - 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 - } - } + model: root.accounts + type: StatusComboBox.Type.Secondary + size: StatusComboBox.Size.Small + implicitHeight: 44 + defaultAssetName: "filled-account" } - CustomRowComponent { + CustomNetworkFilterRowComponent { label: qsTr("Select network") description: qsTr("The network on which this token will be minted") - checked: true - isSwitchCase: false } - CustomRowComponent { + CustomSwitchRowComponent { id: unlimitedSupplyChecker label: qsTr("Unlimited supply") @@ -206,15 +155,15 @@ StatusScrollView { validators: StatusIntValidator{bottom: 1; top: 999999999;} } - CustomRowComponent { + CustomSwitchRowComponent { 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") checked: true } - CustomRowComponent { + CustomSwitchRowComponent { id: selfDestructChecker label: qsTr("Remote self-destruct") @@ -234,4 +183,103 @@ StatusScrollView { 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 + } + } + } }