diff --git a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokenPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokenPanel.qml deleted file mode 100644 index 0208017d02..0000000000 --- a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokenPanel.qml +++ /dev/null @@ -1,100 +0,0 @@ -import QtQuick 2.14 -import QtQuick.Layouts 1.14 - -import StatusQ.Core 0.1 -import StatusQ.Controls 0.1 - -import utils 1.0 -import shared.popups 1.0 - -Item { - id: root - - property var transactionStore - property var tokensModel - - signal mintCollectible(string address, string name, string symbol, string description, int supply, - bool infiniteSupply, bool transferable, bool selfDestruct, string network) - - ColumnLayout { - id: layout - anchors.left: parent.left - - spacing: Style.current.padding - - StatusInput { - id: name - width: 200 - label: qsTr("Name") - } - - StatusInput { - id: symbol - width: 100 - label: qsTr("Symbol") - } - - StatusInput { - id: description - width: 200 - label: qsTr("Description") - } - - StatusInput { - id: supply - width: 100 - label: qsTr("Total finite supply") - text: "0" - } - - StatusCheckBox { - id: transferable - text: qsTr("Transferable") - } - - StatusCheckBox { - id: selfDestruct - text: qsTr("Remote self-destruct") - } - - StatusComboBox { - id: network - Layout.alignment: Qt.AlignVCenter - Layout.maximumWidth: 200 - label: qsTr("Select network") - model: ListModel { - ListElement { - name: "Goerli" - } - ListElement { - name: "Optimism Goerli" - } - } - } - - StatusButton { - id: mintButton - text: "Mint" - //TODO use address from SendModal - onClicked: root.mintCollectible(root.transactionStore.currentAccount.address, name.text, symbol.text, description.text, parseInt(supply.text), - false, transferable.checked, selfDestruct.checked, network.currentValue) - } - - StatusBaseText { - text: "Minted collectibles" - } - - ListView { - id: collectibles - - width: 200 - height: 100 - - model: root.tokensModel - - delegate: Text { - text: "name: " + name + ", descr: " + description + ", supply: " + supply + ", status: " + deployState - } - } - } -} diff --git a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml index faee077cfe..2a46f811a0 100644 --- a/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityMintTokensSettingsPanel.qml @@ -8,13 +8,12 @@ import utils 1.0 SettingsPageLayout { id: root + property string communityId property var tokensModel + property var communitiesStore property var transactionStore property int viewWidth: 560 // by design - signal mintCollectible(string address, string name, string symbol, string description, int supply, - bool infiniteSupply, bool transferable, bool selfDestruct, string network) - function navigateBack() { if (root.state === d.newCollectibleViewState) { root.state = d.welcomeViewState @@ -75,12 +74,23 @@ SettingsPageLayout { Component { id: newCollectiblesView - CommunityMintTokenPanel { + CommunityNewCollectibleView { anchors.fill: parent - transactionStore: root.transactionStore + store: root.communitiesStore tokensModel: root.tokensModel - onMintCollectible: root.mintCollectible(address, name, symbol, description, supply, - infiniteSupply, transferable, selfDestruct, network) + onMintCollectible: { + root.communitiesStore.mintCollectible(root.communityId, + root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/ + artworkSource, + name, + symbol, + description, + supply, + infiniteSupply, + transferable, + selfDestruct, + chainId) + } } } } diff --git a/ui/app/AppLayouts/Chat/stores/CommunitiesStore.qml b/ui/app/AppLayouts/Chat/stores/CommunitiesStore.qml index 4f794374ef..05580cb864 100644 --- a/ui/app/AppLayouts/Chat/stores/CommunitiesStore.qml +++ b/ui/app/AppLayouts/Chat/stores/CommunitiesStore.qml @@ -177,11 +177,18 @@ QtObject { } // Minting tokens: - - function mintCollectible(communityId, address, name, symbol, description, supply, - infiniteSupply, transferable, selfDestruct, network) + function mintCollectible(communityId, address, artworkSource, name, symbol, description, supply, + infiniteSupply, transferable, selfDestruct, chainId) { + // TODO: Backend needs to add `artworkSource` param mintingModuleInst.mintCollectible(communityId, address, name, symbol, description, supply, - infiniteSupply, transferable, selfDestruct, network) + infiniteSupply, transferable, selfDestruct, chainId) } + + // Network selection properties: + property var layer1Networks: networksModule.layer1 + property var layer2Networks: networksModule.layer2 + property var testNetworks: networksModule.test + property var enabledNetworks: networksModule.enabled + property var allNetworks: networksModule.all } diff --git a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml index 8ab9ca6cd8..d7b9d6a18d 100644 --- a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml +++ b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml @@ -254,12 +254,11 @@ StatusSectionLayout { } CommunityMintTokensSettingsPanel { + communityId: root.community.id + communitiesStore: root.communityStore transactionStore: root.transactionStore tokensModel: root.community.communityTokens - onMintCollectible: { - root.communityStore.mintCollectible(root.community.id, address, name, symbol, description, supply, - infiniteSupply, transferable, selfDestruct, network) - } + onPreviousPageNameChanged: root.backButtonName = previousPageName } diff --git a/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml b/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml new file mode 100644 index 0000000000..be6eaf12e2 --- /dev/null +++ b/ui/app/AppLayouts/Chat/views/communities/CommunityNewCollectibleView.qml @@ -0,0 +1,262 @@ +import QtQuick 2.14 +import QtQuick.Layouts 1.14 + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Controls 0.1 +import StatusQ.Controls.Validators 0.1 + +import utils 1.0 + +import "../../../Wallet/controls" +import shared.panels 1.0 + +StatusScrollView { + id: root + + property var store + property var tokensModel // TEMPORARY + property int viewWidth: 560 // by design + + signal chooseArtWork + signal previewClicked + + // TEMPORAL + signal mintCollectible(url artworkSource, + string name, + string symbol, + string description, + int supply, + bool infiniteSupply, + bool transferable, + bool selfDestruct, + int chainId) + + QtObject { + id: d + + readonly property bool isFullyFilled: d.artworkSource.toString().length > 0 + && !!nameInput.text + && !!symbolInput.text + && !!descriptionInput.text + && (unlimitedSupplyItem.checked || (!unlimitedSupplyItem.checked && supplyInput.text.length > 0)) + + + readonly property int imageSelectorRectWidth: 280 + + property url artworkSource + property int networkSelected + } + + contentWidth: mainLayout.width + contentHeight: mainLayout.height + padding: 0 + + ColumnLayout { + id: mainLayout + + width: root.viewWidth + spacing: Style.current.padding + + StatusImageSelector { + Layout.preferredHeight: d.imageSelectorRectWidth + headerHeight + Layout.preferredWidth: d.imageSelectorRectWidth + buttonsInsideOffset + labelText: qsTr("Artwork") + uploadText: qsTr("Drag and Drop or Upload Artwork") + additionalText: qsTr("Images only") + acceptedImageExtensions: Constants.acceptedDragNDropImageExtensions + + onFileSelected: d.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 + + label: qsTr("Name") + charLimit: 30 + placeholderText: qsTr("Name") + errorText: qsTr("Collectible name") + } + + CustomStatusInput { + id: descriptionInput + + label: qsTr("Description") + charLimit: 280 + placeholderText: qsTr("Describe your collectible") + input.multiline: true + input.verticalAlignment: Qt.AlignTop + input.placeholder.verticalAlignment: Qt.AlignTop + minimumHeight: 108 + maximumHeight: minimumHeight + errorText: qsTr("Collectible description") + } + + CustomStatusInput { + id: symbolInput + + label: qsTr("Token symbol") + placeholderText: qsTr("Letter token abbreviation e.g. ABC") + errorText: qsTr("Token symbol") + } + + component CustomRowComponent: RowLayout { + id: rowComponent + + property string label + property string description + property bool checked + property bool isSwitchCase: true + + 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 + store: root.store + isChainVisible: false + multiSelection: false + + onSingleNetworkSelected: d.networkSelected = chainId + } + } + + CustomRowComponent { + label: qsTr("Select network") + description: qsTr("The network on which this token will be minted") + checked: true + isSwitchCase: false + } + + CustomRowComponent { + id: unlimitedSupplyItem + + label: qsTr("Unlimited supply") + description: qsTr("Enable to allow the minting of additional collectibles in the future. Disable to specify a finite supply") + checked: true + } + + StatusInput { + id: supplyInput + + visible: !unlimitedSupplyItem.checked + label: qsTr("Total finite supply") + placeholderText: "1" + validators: StatusIntValidator{bottom: 1; top: 999999999;} + } + + CustomRowComponent { + id: transferibleChecker + + label: qsTr("Not transferable (Soulbound)") + 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 { + id: selfDestructChecker + + label: qsTr("Remote self-destruct") + description: qsTr("Enable to allow you to destroy tokens remotely. Useful for revoking permissions from individuals") + checked: true + } + + StatusButton { + Layout.preferredHeight: 44 + Layout.alignment: Qt.AlignHCenter + Layout.fillWidth: true + Layout.topMargin: Style.current.padding + text: qsTr("Preview") + enabled: d.isFullyFilled + + onClicked: { + root.previewClicked() + + // TEMPORAL + root.mintCollectible(d.artworkSource, + nameInput.text, + symbolInput.text, + descriptionInput.text, + parseInt(supplyInput.text), + unlimitedSupplyItem.checked, + transferibleChecker.checked, + selfDestructChecker.checked, + d.networkSelected) + } + } + + // TEMPORAL: + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: backendChecker.implicitHeight + color: "darkgrey" + radius: 8 + + ColumnLayout { + id: backendChecker + + StatusBaseText { + Layout.margins: 16 + text: "Backend checker - Minted collectibles" + font.bold: true + } + + ListView { + Layout.preferredWidth: 200 + Layout.preferredHeight: 100 + model: root.tokensModel + delegate: Text { + text: "name: " + name + ", descr: " + description + ", supply: " + supply + ", status: " + deployState + } + } + } + } + } +} diff --git a/ui/app/AppLayouts/Chat/views/communities/qmldir b/ui/app/AppLayouts/Chat/views/communities/qmldir index 35a6f9612a..94174248f9 100644 --- a/ui/app/AppLayouts/Chat/views/communities/qmldir +++ b/ui/app/AppLayouts/Chat/views/communities/qmldir @@ -4,3 +4,4 @@ CommunityWelcomePermissionsView 1.0 CommunityWelcomePermissionsView.qml HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml JoinCommunityView 1.0 JoinCommunityView.qml CommunityWelcomeSettingsView 1.0 CommunityWelcomeSettingsView.qml +CommunityNewCollectibleView 1.0 CommunityNewCollectibleView.qml