2023-02-22 17:10:46 +00:00
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
2023-03-17 15:09:27 +00:00
import StatusQ . Components 0.1
2023-05-22 15:47:06 +00:00
import StatusQ . Core . Utils 0.1 as SQUtils
2023-02-22 17:10:46 +00:00
import utils 1.0
2023-05-04 10:01:59 +00:00
import AppLayouts . Wallet . controls 1.0
2023-02-22 17:10:46 +00:00
import shared . panels 1.0
2023-05-04 10:01:59 +00:00
import shared . popups 1.0
2023-02-22 17:10:46 +00:00
2023-06-08 12:50:33 +00:00
import SortFilterProxyModel 0.2
2023-02-22 17:10:46 +00:00
StatusScrollView {
id: root
property int viewWidth: 560 // by design
2023-05-22 13:00:40 +00:00
property bool isAssetView: false
2023-02-22 17:10:46 +00:00
2023-05-22 13:00:40 +00:00
// Token properties
2023-03-17 15:09:27 +00:00
readonly property alias name: nameInput . text
readonly property alias symbol: symbolInput . text
readonly property alias description: descriptionInput . text
readonly property alias infiniteSupply: unlimitedSupplyChecker . checked
2023-03-28 07:47:12 +00:00
readonly property int supplyAmount: supplyInput . text ? parseInt ( supplyInput . text ) : 0
2023-05-16 15:07:21 +00:00
property alias artworkSource: dropAreaItem . artworkSource
property alias artworkCropRect: dropAreaItem . artworkCropRect
2023-03-07 11:32:45 +00:00
property int chainId
property string chainName
property string chainIcon
2023-05-22 15:47:06 +00:00
property var tokensModel
2023-03-07 11:32:45 +00:00
2023-05-25 10:30:16 +00:00
// Collectible properties (ERC721)
2023-05-22 13:00:40 +00:00
readonly property alias notTransferable: transferableChecker . checked
readonly property alias selfDestruct: selfDestructChecker . checked
2023-05-25 10:30:16 +00:00
// Asset properties (ERC20)
2023-05-22 13:00:40 +00:00
readonly property int assetDecimals: assetDecimalsInput . text ? parseInt ( assetDecimalsInput . text ) : 0
2023-03-08 13:44:47 +00:00
// Network related properties:
property var layer1Networks
property var layer2Networks
property var testNetworks
property var enabledNetworks
property var allNetworks
2023-03-17 15:09:27 +00:00
// 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
2023-02-22 17:10:46 +00:00
signal chooseArtWork
signal previewClicked
QtObject {
id: d
2023-03-07 11:32:45 +00:00
readonly property bool isFullyFilled: root . artworkSource . toString ( ) . length > 0
2023-05-22 15:47:06 +00:00
&& nameInput . valid
&& descriptionInput . valid
&& symbolInput . valid
&& ( root . infiniteSupply || ( ! root . infiniteSupply && root . supplyAmount > 0 ) )
&& ( ! root . isAssetView || ( root . isAssetView && assetDecimalsInput . valid ) )
2023-02-22 17:10:46 +00:00
2023-05-22 15:47:06 +00:00
readonly property int imageSelectorRectWidth: root . isAssetView ? 128 : 290
2023-02-22 17:10:46 +00:00
}
padding: 0
ColumnLayout {
id: mainLayout
width: root . viewWidth
spacing: Style . current . padding
2023-05-04 10:01:59 +00:00
StatusBaseText {
elide: Text . ElideRight
font.pixelSize: Theme . primaryTextFontSize
2023-05-22 13:00:40 +00:00
text: root . isAssetView ? qsTr ( "Icon" ) : qsTr ( "Artwork" )
2023-05-04 10:01:59 +00:00
}
2023-05-16 15:07:21 +00:00
DropAndEditImagePanel {
id: dropAreaItem
Layout.fillWidth: true
2023-05-04 10:01:59 +00:00
Layout.preferredHeight: d . imageSelectorRectWidth
2023-05-22 15:47:06 +00:00
editorAnchorLeft: ! root . isAssetView
editorRoundedImage: root . isAssetView
uploadTextLabel.uploadText: root . isAssetView ? qsTr ( "Upload" ) : qsTr ( "Drag and Drop or Upload Artwork" )
2023-05-16 15:07:21 +00:00
uploadTextLabel.additionalText: qsTr ( "Images only" )
2023-05-22 15:47:06 +00:00
uploadTextLabel.showAdditionalInfo: ! root . isAssetView
editorTitle: root . isAssetView ? qsTr ( "Asset icon" ) : qsTr ( "Collectible artwork" )
acceptButtonText: root . isAssetView ? qsTr ( "Upload asset icon" ) : qsTr ( "Upload collectible artwork" )
2023-02-22 17:10:46 +00:00
}
CustomStatusInput {
id: nameInput
label: qsTr ( "Name" )
2023-05-11 15:51:50 +00:00
charLimit: 15
2023-02-22 17:10:46 +00:00
placeholderText: qsTr ( "Name" )
2023-05-22 15:47:06 +00:00
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" )
2023-02-22 17:10:46 +00:00
}
CustomStatusInput {
id: descriptionInput
label: qsTr ( "Description" )
charLimit: 280
2023-05-22 13:00:40 +00:00
placeholderText: root . isAssetView ? qsTr ( "Describe your asset" ) : qsTr ( "Describe your collectible" )
2023-02-22 17:10:46 +00:00
input.multiline: true
input.verticalAlignment: Qt . AlignTop
input.placeholder.verticalAlignment: Qt . AlignTop
minimumHeight: 108
maximumHeight: minimumHeight
2023-05-22 15:47:06 +00:00
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" )
2023-02-22 17:10:46 +00:00
}
CustomStatusInput {
id: symbolInput
2023-05-11 15:51:50 +00:00
label: qsTr ( "Symbol" )
charLimit: 6
placeholderText: qsTr ( "e.g. DOODLE" )
2023-05-22 15:47:06 +00:00
minLengthValidator.errorMessage: qsTr ( "Please enter your token symbol (use A-Z only)" )
regexValidator.errorMessage: qsTr ( "Your token symbol contains invalid characters (use A-Z only)" )
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" )
2023-02-22 17:10:46 +00:00
}
2023-03-17 15:09:27 +00:00
CustomLabelDescriptionComponent {
Layout.topMargin: Style . current . padding
label: qsTr ( "Select account" )
2023-05-11 15:51:50 +00:00
description: qsTr ( "Account will be required for all subsequent interactions with this token. Remember everybody in your community will be able to see this address." )
2023-03-17 15:09:27 +00:00
}
2023-02-22 17:10:46 +00:00
2023-03-17 15:09:27 +00:00
StatusEmojiAndColorComboBox {
id: accountsComboBox
2023-02-22 17:10:46 +00:00
2023-05-22 13:00:40 +00:00
readonly property string address: SQUtils . ModelUtils . get ( root . accounts , currentIndex , "address" )
2023-02-22 17:10:46 +00:00
2023-03-17 15:09:27 +00:00
Layout.fillWidth: true
2023-06-08 12:50:33 +00:00
model: SortFilterProxyModel {
sourceModel: root . accounts
proxyRoles: [
ExpressionRole {
name: "color"
function getColor ( colorId ) {
return Utils . getColorForId ( colorId )
}
// Direct call for singleton function is not handled properly by
// SortFilterProxyModel that's why helper function is used instead.
expression: { return getColor ( model . colorId ) }
}
]
}
2023-03-17 15:09:27 +00:00
type: StatusComboBox . Type . Secondary
size: StatusComboBox . Size . Small
implicitHeight: 44
defaultAssetName: "filled-account"
2023-02-22 17:10:46 +00:00
}
2023-03-17 15:09:27 +00:00
CustomNetworkFilterRowComponent {
2023-02-22 17:10:46 +00:00
label: qsTr ( "Select network" )
description: qsTr ( "The network on which this token will be minted" )
}
2023-03-17 15:09:27 +00:00
CustomSwitchRowComponent {
2023-03-07 11:32:45 +00:00
id: unlimitedSupplyChecker
2023-02-22 17:10:46 +00:00
label: qsTr ( "Unlimited supply" )
2023-05-11 15:51:50 +00:00
description: qsTr ( "Enable to allow the minting of additional tokens in the future. Disable to specify a finite supply" )
2023-02-22 17:10:46 +00:00
checked: true
2023-05-11 15:51:50 +00:00
onCheckedChanged: if ( ! checked ) supplyInput . forceActiveFocus ( )
2023-02-22 17:10:46 +00:00
}
2023-05-22 15:47:06 +00:00
CustomStatusInput {
2023-02-22 17:10:46 +00:00
id: supplyInput
2023-03-07 11:32:45 +00:00
visible: ! unlimitedSupplyChecker . checked
2023-02-22 17:10:46 +00:00
label: qsTr ( "Total finite supply" )
2023-05-11 15:51:50 +00:00
placeholderText: qsTr ( "e.g. 300" )
2023-05-22 15:47:06 +00:00
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" )
2023-02-22 17:10:46 +00:00
}
2023-03-17 15:09:27 +00:00
CustomSwitchRowComponent {
2023-03-07 11:32:45 +00:00
id: transferableChecker
2023-05-22 13:00:40 +00:00
visible: ! root . isAssetView
2023-03-17 15:09:27 +00:00
label: checked ? qsTr ( "Not transferable (Soulbound)" ) : qsTr ( "Transferable" )
2023-02-22 17:10:46 +00:00
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
}
2023-03-17 15:09:27 +00:00
CustomSwitchRowComponent {
2023-02-22 17:10:46 +00:00
id: selfDestructChecker
2023-05-22 13:00:40 +00:00
visible: ! root . isAssetView
2023-05-11 15:51:50 +00:00
label: qsTr ( "Remotely destructible" )
2023-02-22 17:10:46 +00:00
description: qsTr ( "Enable to allow you to destroy tokens remotely. Useful for revoking permissions from individuals" )
checked: true
}
2023-05-16 15:07:21 +00:00
CustomStatusInput {
2023-05-22 13:00:40 +00:00
id: assetDecimalsInput
visible: root . isAssetView
2023-05-25 10:31:32 +00:00
label: qsTr ( "Decimals (DP)" )
2023-05-22 13:00:40 +00:00
charLimit: 2
charLimitLabel: qsTr ( "Max 10" )
placeholderText: "2"
text: "2" // Default value
validationMode: StatusInput . ValidationMode . Always
2023-05-22 15:47:06 +00:00
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
2023-05-16 15:07:21 +00:00
}
2023-02-22 17:10:46 +00:00
StatusButton {
Layout.preferredHeight: 44
Layout.alignment: Qt . AlignHCenter
Layout.fillWidth: true
Layout.topMargin: Style . current . padding
2023-03-10 15:55:50 +00:00
Layout.bottomMargin: Style . current . padding
2023-02-22 17:10:46 +00:00
text: qsTr ( "Preview" )
enabled: d . isFullyFilled
2023-03-07 11:32:45 +00:00
onClicked: root . previewClicked ( )
2023-02-22 17:10:46 +00:00
}
}
2023-03-17 15:09:27 +00:00
// Inline components definition:
component CustomStatusInput: StatusInput {
id: customInput
2023-05-22 15:47:06 +00:00
property alias minLengthValidator: minLengthValidatorItem
property alias regexValidator: regexValidatorItem
property alias extraValidator: extraValidatorItem
2023-03-17 15:09:27 +00:00
Layout.fillWidth: true
validators: [
StatusMinLengthValidator {
2023-05-22 15:47:06 +00:00
id: minLengthValidatorItem
2023-03-17 15:09:27 +00:00
minLength: 1
} ,
StatusRegularExpressionValidator {
2023-05-22 15:47:06 +00:00
id: regexValidatorItem
regularExpression: Constants . regularExpressions . alphanumerical
} ,
StatusValidator {
id: extraValidatorItem
2023-03-17 15:09:27 +00:00
}
]
}
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
2023-04-05 11:10:44 +00:00
allNetworks: root . allNetworks
2023-03-17 15:09:27 +00:00
layer1Networks: root . layer1Networks
layer2Networks: root . layer2Networks
testNetworks: root . testNetworks
enabledNetworks: root . enabledNetworks
2023-04-05 11:10:44 +00:00
2023-03-17 15:09:27 +00:00
multiSelection: false
2023-05-04 10:01:59 +00:00
onToggleNetwork: ( network ) = >
{
root . chainId = network . chainId
root . chainName = network . chainName
root . chainIcon = network . iconUrl
}
2023-03-17 15:09:27 +00:00
}
}
2023-02-22 17:10:46 +00:00
}