feat(MintTokens): Create new collectible screen
Created new form screen for minting collectibles. Closes #8733
This commit is contained in:
parent
83bdc7f104
commit
db3be56d42
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,13 +8,12 @@ import utils 1.0
|
||||||
SettingsPageLayout {
|
SettingsPageLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property string communityId
|
||||||
property var tokensModel
|
property var tokensModel
|
||||||
|
property var communitiesStore
|
||||||
property var transactionStore
|
property var transactionStore
|
||||||
property int viewWidth: 560 // by design
|
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() {
|
function navigateBack() {
|
||||||
if (root.state === d.newCollectibleViewState) {
|
if (root.state === d.newCollectibleViewState) {
|
||||||
root.state = d.welcomeViewState
|
root.state = d.welcomeViewState
|
||||||
|
@ -75,12 +74,23 @@ SettingsPageLayout {
|
||||||
Component {
|
Component {
|
||||||
id: newCollectiblesView
|
id: newCollectiblesView
|
||||||
|
|
||||||
CommunityMintTokenPanel {
|
CommunityNewCollectibleView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
transactionStore: root.transactionStore
|
store: root.communitiesStore
|
||||||
tokensModel: root.tokensModel
|
tokensModel: root.tokensModel
|
||||||
onMintCollectible: root.mintCollectible(address, name, symbol, description, supply,
|
onMintCollectible: {
|
||||||
infiniteSupply, transferable, selfDestruct, network)
|
root.communitiesStore.mintCollectible(root.communityId,
|
||||||
|
root.transactionStore.currentAccount.address, /*TODO use address from SendModal*/
|
||||||
|
artworkSource,
|
||||||
|
name,
|
||||||
|
symbol,
|
||||||
|
description,
|
||||||
|
supply,
|
||||||
|
infiniteSupply,
|
||||||
|
transferable,
|
||||||
|
selfDestruct,
|
||||||
|
chainId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,11 +177,18 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minting tokens:
|
// Minting tokens:
|
||||||
|
function mintCollectible(communityId, address, artworkSource, name, symbol, description, supply,
|
||||||
function mintCollectible(communityId, address, name, symbol, description, supply,
|
infiniteSupply, transferable, selfDestruct, chainId)
|
||||||
infiniteSupply, transferable, selfDestruct, network)
|
|
||||||
{
|
{
|
||||||
|
// TODO: Backend needs to add `artworkSource` param
|
||||||
mintingModuleInst.mintCollectible(communityId, address, name, symbol, description, supply,
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,12 +254,11 @@ StatusSectionLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunityMintTokensSettingsPanel {
|
CommunityMintTokensSettingsPanel {
|
||||||
|
communityId: root.community.id
|
||||||
|
communitiesStore: root.communityStore
|
||||||
transactionStore: root.transactionStore
|
transactionStore: root.transactionStore
|
||||||
tokensModel: root.community.communityTokens
|
tokensModel: root.community.communityTokens
|
||||||
onMintCollectible: {
|
|
||||||
root.communityStore.mintCollectible(root.community.id, address, name, symbol, description, supply,
|
|
||||||
infiniteSupply, transferable, selfDestruct, network)
|
|
||||||
}
|
|
||||||
onPreviousPageNameChanged: root.backButtonName = previousPageName
|
onPreviousPageNameChanged: root.backButtonName = previousPageName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,3 +4,4 @@ CommunityWelcomePermissionsView 1.0 CommunityWelcomePermissionsView.qml
|
||||||
HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml
|
HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml
|
||||||
JoinCommunityView 1.0 JoinCommunityView.qml
|
JoinCommunityView 1.0 JoinCommunityView.qml
|
||||||
CommunityWelcomeSettingsView 1.0 CommunityWelcomeSettingsView.qml
|
CommunityWelcomeSettingsView 1.0 CommunityWelcomeSettingsView.qml
|
||||||
|
CommunityNewCollectibleView 1.0 CommunityNewCollectibleView.qml
|
||||||
|
|
Loading…
Reference in New Issue