feat(OwnerToken): Create `EditTokenView.qml` for mint owner token flow

- It creates a generic `TokenInfoPanel` that will be reused in different mint token views.
- It creates new `EditOwnerTokenView` and storybook page support.
- It adds new `EditOwnerTokenView` into the minting flow, linking sign transaction flow and adding needed method to the store to do the deployment.

Closes #11296
This commit is contained in:
Noelia 2023-07-18 14:39:38 +02:00 committed by Noelia
parent 32952e4e01
commit c8cb2d6c7c
15 changed files with 768 additions and 232 deletions

View File

@ -85,6 +85,10 @@ ListModel {
title: "EditNetworkView" title: "EditNetworkView"
section: "Views" section: "Views"
} }
ListElement {
title: "EditOwnerTokenView"
section: "Views"
}
ListElement { ListElement {
title: "StatusCommunityCard" title: "StatusCommunityCard"
section: "Panels" section: "Panels"

View File

@ -239,5 +239,9 @@
], ],
"OverviewSettingsChart": [ "OverviewSettingsChart": [
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31281-635619&mode=design&t=RYpVRgwqCjp8fUEX-0" "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31281-635619&mode=design&t=RYpVRgwqCjp8fUEX-0"
],
"EditOwnerTokenView": [
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?type=design&node-id=34794-590207&mode=design&t=ZnwK9yenS5oSgwws-0"
] ]
} }

View File

@ -0,0 +1,95 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import AppLayouts.Communities.views 1.0
import Storybook 1.0
import Models 1.0
import utils 1.0
SplitView {
Logs { id: logs }
SplitView {
orientation: Qt.Vertical
SplitView.fillWidth: true
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
EditOwnerTokenView {
anchors.fill: parent
anchors.margins: 50
communityName: communityName.text
communityLogo: doodles.checked ? ModelsData.collectibles.doodles : ModelsData.collectibles.mana
communityColor: color1.checked ? "#FFC4E9" : "#f44336"
layer1Networks: NetworksModel.layer1Networks
layer2Networks: NetworksModel.layer2Networks
testNetworks: NetworksModel.testNetworks
enabledNetworks: NetworksModel.enabledNetworks
allNetworks: enabledNetworks
accounts: WalletAccountsModel {}
onMintClicked: logs.logEvent("EditOwnerTokenView::onMintClicked")
}
}
LogsAndControlsPanel {
id: logsAndControlsPanel
SplitView.minimumHeight: 100
SplitView.preferredHeight: 150
logsView.logText: logs.logText
ColumnLayout {
RowLayout {
Label {
text: "Community name:"
}
TextInput {
id: communityName
text: "Doodles"
}
}
RowLayout {
RadioButton {
id: color1
text: "Light pink"
checked: true
}
RadioButton {
text: "Orange"
}
}
RowLayout {
RadioButton {
id: doodles
text: "Doodles"
checked: true
}
RadioButton {
text: "Mana"
}
}
}
}
}
}

View File

@ -82,4 +82,14 @@ QtObject {
return "" return ""
} }
} }
// It generates a symbol from a given community name.
// It will be used to autogenerate the Owner and Token Master token symbols.
function autogenerateSymbol(isOwner, communityName) {
const shortName = communityName.substring(0, 3)
if(isOwner)
return "OWN" + shortName.toUpperCase()
else
return "TM" + shortName.toUpperCase()
}
} }

View File

@ -10,6 +10,11 @@ import utils 1.0
QtObject { QtObject {
property int type: Constants.TokenType.ERC20 property int type: Constants.TokenType.ERC20
// Special token (Owner and TMaster tokens):
property bool isPrivilegedToken: false
property bool isOwner: false
property color color
// Unique identifier: // Unique identifier:
property string key property string key
@ -19,7 +24,7 @@ QtObject {
property string description property string description
property bool infiniteSupply: true property bool infiniteSupply: true
property int supply: 1 property int supply: 1
property int remainingTokens property int remainingTokens: supply
// Artwork related properties: // Artwork related properties:
property url artworkSource property url artworkSource

View File

@ -50,6 +50,7 @@ StackView {
signal mintCollectible(var collectibleItem) signal mintCollectible(var collectibleItem)
signal mintAsset(var assetItem) signal mintAsset(var assetItem)
signal mintOwnerToken(var ownerToken, var tMasterToken)
signal signMintTransactionOpened(int chainId, string accountAddress, int tokenType) signal signMintTransactionOpened(int chainId, string accountAddress, int tokenType)
@ -138,11 +139,66 @@ StackView {
title: qsTr("Mint Owner token") title: qsTr("Mint Owner token")
contentItem: OwnerTokenWelcomeView { contentItem: OwnerTokenWelcomeView {
viewWidth: root.viewWidth
communityLogo: root.communityLogo communityLogo: root.communityLogo
communityColor: root.communityColor communityColor: root.communityColor
communityName: root.communityName communityName: root.communityName
onNextClicked: root.push(newTokenViewComponent, StackView.Immediate) // TEMP: It will navigate to new token owner flow. Now, to current minting flow. onNextClicked: root.push(ownerTokenEditViewComponent, StackView.Immediate)
}
}
}
Component {
id: ownerTokenEditViewComponent
SettingsPage {
id: ownerTokenPage
title: qsTr("Mint Owner token")
contentItem: EditOwnerTokenView {
id: editOwnerTokenView
function signMintTransaction() {
root.mintOwnerToken(ownerToken, tMasterToken)
root.resetNavigation()
}
viewWidth: root.viewWidth
communityLogo: root.communityLogo
communityColor: root.communityColor
communityName: root.communityName
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
enabledNetworks: root.testNetworks
allNetworks: root.allNetworks
accounts: root.accounts
onMintClicked: signMintPopup.open()
SignTokenTransactionsPopup {
id: signMintPopup
anchors.centerIn: Overlay.overlay
title: qsTr("Sign transaction - Mint %1 tokens").arg(signMintPopup.tokenName)
tokenName: editOwnerTokenView.communityName
accountName: editOwnerTokenView.ownerToken.accountName
networkName: editOwnerTokenView.ownerToken.chainName
feeText: root.feeText
errorText: root.errorText
isFeeLoading: root.isFeeLoading
onOpened: {
root.setFeeLoading()
root.signMintTransactionOpened(editOwnerTokenView.ownerToken.chainId,
editOwnerTokenView.ownerToken.accountAddress,
Constants.TokenType.ERC721)
}
onCancelClicked: close()
onSignTransactionClicked: editOwnerTokenView.signMintTransaction()
}
} }
} }
} }

View File

@ -11,7 +11,8 @@ import utils 1.0
Control { Control {
id: root id: root
required property bool isOwner // https://bugreports.qt.io/browse/QTBUG-84269
/*required*/ property bool isOwner
property bool showTag: false property bool showTag: false
property int size: PrivilegedTokenArtworkPanel.Size.Small property int size: PrivilegedTokenArtworkPanel.Size.Small

View File

@ -0,0 +1,272 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import AppLayouts.Communities.helpers 1.0
import utils 1.0
import shared.panels 1.0
Control {
id: root
// Panel properties:
property bool preview: false
// Token object properties:
/* required */ property TokenObject token // https://bugreports.qt.io/browse/QTBUG-84269
readonly property bool isAssetPanel: token.type === Constants.TokenType.ERC20
QtObject {
id: d
readonly property int imageSelectorRectSize: root.isAssetPanel ? 104 : 280
readonly property string infiniteSymbol: "∞"
readonly property int burnState: token.burnState
function startAnimation(isBurn) {
totalbox.highlighted = true
if(isBurn)
remainingBox.highlighted = true
}
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
}
implicitWidth: 560 // by design
contentItem: ColumnLayout {
id: mainLayout
spacing: Style.current.padding
// General artwork representation:
Rectangle {
visible: !token.isPrivilegedToken
Layout.preferredHeight: d.imageSelectorRectSize
Layout.preferredWidth: Layout.preferredHeight
radius: root.isAssetPanel ? Layout.preferredWidth / 2 : 8
color:Theme.palette.baseColor2
Image {
id: image
readonly property rect imageCropRect: token.artworkCropRect
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
source: token.artworkSource
sourceClipRect: imageCropRect ? imageCropRect : undefined
}
OpacityMask {
anchors.fill: image
source: image
maskSource: parent
}
}
// Special artwork representation for `Owner and Master Token` tokens:
PrivilegedTokenArtworkPanel {
visible: token.isPrivilegedToken
size: PrivilegedTokenArtworkPanel.Size.Large
artwork: token.artworkSource
color: token.color
isOwner: token.isOwner
}
Flow {
spacing: Style.current.halfPadding
Layout.fillWidth: true
component CustomPreviewBox: Rectangle {
id: previewBox
property string label
property string value
property bool isLoading: false
property bool highlighted: false
radius: 8
border.color: Theme.palette.baseColor2
implicitWidth: Math.min(boxContent.implicitWidth + Style.current.padding, mainLayout.width)
implicitHeight: boxContent.implicitHeight + Style.current.padding
states: [
State {
when: !previewBox.highlighted
PropertyChanges { target: previewBox; color: "transparent" }
},
State {
when: previewBox.highlighted
PropertyChanges { target: previewBox; color: Theme.palette.primaryColor3 }
}
]
onHighlightedChanged: if(highlighted) animation.start()
ColumnLayout {
id: boxContent
anchors.centerIn: parent
spacing: 2
StatusBaseText {
Layout.fillWidth: true
text: previewBox.label
elide: Text.ElideRight
font.pixelSize: Style.current.additionalTextSize
color: Theme.palette.baseColor1
}
RowLayout {
spacing: 3
StatusBaseText {
text: StatusQUtils.Emoji.fromCodePoint("1f525") // :fire: emoji
font.pixelSize: Style.current.tertiaryTextFontSize
visible: previewBox.isLoading
color: Theme.palette.directColor1
}
StatusBaseText {
Layout.maximumWidth: mainLayout.width - Style.current.padding
text: previewBox.value
elide: Text.ElideRight
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.directColor1
}
StatusLoadingIndicator {
Layout.preferredHeight: Theme.primaryTextFontSize
Layout.preferredWidth: Layout.preferredHeight
Layout.leftMargin: 6
Layout.rightMargin: 3
visible: previewBox.isLoading
color: Theme.palette.primaryColor1
}
}
}
Timer {
id: animation
interval: 1500
onRunningChanged: if(!running) previewBox.highlighted = false
}
}
CustomPreviewBox {
id: symbolBox
label: qsTr("Symbol")
value: token.symbol
}
CustomPreviewBox {
id: totalbox
label: qsTr("Total")
value: token.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(token.supply)
isLoading: !token.infiniteSupply &&
((!root.isAssetPanel && token.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(d.burnState === Constants.ContractTransactionStatus.InProgress))
}
CustomPreviewBox {
id: remainingBox
readonly property int remainingTokens: root.preview ? token.supply : token.remainingTokens
label: qsTr("Remaining")
value: token.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(remainingTokens)
isLoading: !token.infiniteSupply && (d.burnState === Constants.ContractTransactionStatus.InProgress)
}
CustomPreviewBox {
visible: root.isAssetPanel
label: qsTr("DP")
value: token.decimals
}
CustomPreviewBox {
visible: !root.isAssetPanel
label: qsTr("Transferable")
value: token.transferable ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !root.isAssetPanel
label: qsTr("Destructible")
value: token.remotelyDestruct ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !token.isPrivilegedToken
label: qsTr("Account")
value: token.accountName
}
Rectangle {
visible: !token.isPrivilegedToken
height: symbolBox.height
width: rowChain.implicitWidth + 2 * Style.current.padding
border.width: 1
radius: 8
border.color: Theme.palette.baseColor2
color: "transparent"
RowLayout {
id: rowChain
anchors.centerIn: parent
spacing: Style.current.padding
SVGImage {
Layout.alignment: Qt.AlignVCenter
height: 24
width: height
source: token.chainIcon ? Style.svg(token.chainIcon) : undefined
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
text: token.chainName
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
}
}
}
}
StatusBaseText {
Layout.fillWidth: true
text: token.description
wrapMode: TextEdit.WordWrap
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
}
}
Connections {
target: token
function onRemotelyDestructStateChanged() {
if(token.remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
}
}
}

View File

@ -28,6 +28,7 @@ SortableTokenHoldersPanel 1.0 SortableTokenHoldersPanel.qml
TagsPanel 1.0 TagsPanel.qml TagsPanel 1.0 TagsPanel.qml
TokenHoldersPanel 1.0 TokenHoldersPanel.qml TokenHoldersPanel 1.0 TokenHoldersPanel.qml
TokenHoldersProxyModel 1.0 TokenHoldersProxyModel.qml TokenHoldersProxyModel 1.0 TokenHoldersProxyModel.qml
TokenInfoPanel 1.0 TokenInfoPanel.qml
WarningPanel 1.0 WarningPanel.qml WarningPanel 1.0 WarningPanel.qml
WelcomeBannerPanel 1.0 WelcomeBannerPanel.qml WelcomeBannerPanel 1.0 WelcomeBannerPanel.qml
EditSettingsPanel 1.0 EditSettingsPanel.qml EditSettingsPanel 1.0 EditSettingsPanel.qml

View File

@ -326,6 +326,10 @@ StatusSectionLayout {
onMintAsset: onMintAsset:
communityTokensStore.deployAsset(root.community.id, assetItem) communityTokensStore.deployAsset(root.community.id, assetItem)
onMintOwnerToken:
communityTokensStore.deployOwnerToken(
root.community.id, ownerToken, tMasterToken)
onSignRemoteDestructTransactionOpened: onSignRemoteDestructTransactionOpened:
communityTokensStore.computeSelfDestructFee( communityTokensStore.computeSelfDestructFee(
remotelyDestructTokensList, tokenKey) remotelyDestructTokensList, tokenKey)

View File

@ -60,19 +60,7 @@ StatusScrollView {
QtObject { QtObject {
id: d id: d
readonly property int imageSelectorRectSize: root.isAssetView ? 104 : 280
readonly property int iconSize: 20 readonly property int iconSize: 20
readonly property string infiniteSymbol: "∞"
readonly property int burnState: root.token.burnState
function startAnimation(isBurn) {
totalbox.highlighted = true
if(isBurn)
remainingBox.highlighted = true
}
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
} }
padding: 0 padding: 0
@ -109,202 +97,10 @@ StatusScrollView {
} }
} }
Rectangle { TokenInfoPanel {
Layout.preferredHeight: d.imageSelectorRectSize
Layout.preferredWidth: Layout.preferredHeight
radius: root.isAssetView ? Layout.preferredWidth / 2 : 8
color:Theme.palette.baseColor2
clip: true
Image {
id: image
readonly property rect imageCropRect: root.artworkCropRect
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
source: root.artworkSource
sourceClipRect: imageCropRect ? imageCropRect : undefined
}
OpacityMask {
anchors.fill: image
source: image
maskSource: parent
}
}
Flow {
spacing: Style.current.halfPadding
Layout.fillWidth: true Layout.fillWidth: true
component CustomPreviewBox: Rectangle { token: root.token
id: previewBox
property string label
property string value
property bool isLoading: false
property bool highlighted: false
radius: 8
border.color: Theme.palette.baseColor2
implicitWidth: Math.min(boxContent.implicitWidth + Style.current.padding, mainLayout.width)
implicitHeight: boxContent.implicitHeight + Style.current.padding
states: [
State {
when: !previewBox.highlighted
PropertyChanges { target: previewBox; color: "transparent" }
},
State {
when: previewBox.highlighted
PropertyChanges { target: previewBox; color: Theme.palette.primaryColor3 }
}
]
onHighlightedChanged: if(highlighted) animation.start()
ColumnLayout {
id: boxContent
anchors.centerIn: parent
spacing: 2
StatusBaseText {
Layout.fillWidth: true
text: previewBox.label
elide: Text.ElideRight
font.pixelSize: 13
color: Theme.palette.baseColor1
}
RowLayout {
spacing: 3
StatusBaseText {
text: StatusQUtils.Emoji.fromCodePoint("1f525") // :fire: emoji
font.pixelSize: Theme.tertiaryTextFontSize
visible: previewBox.isLoading
color: Theme.palette.directColor1
}
StatusBaseText {
Layout.maximumWidth: mainLayout.width - Style.current.padding
text: previewBox.value
elide: Text.ElideRight
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.directColor1
}
StatusLoadingIndicator {
Layout.preferredHeight: Theme.primaryTextFontSize
Layout.preferredWidth: Layout.preferredHeight
Layout.leftMargin: 6
Layout.rightMargin: 3
visible: previewBox.isLoading
color: Theme.palette.primaryColor1
}
}
}
Timer {
id: animation
interval: 1500
onRunningChanged: if(!running) previewBox.highlighted = false
}
}
CustomPreviewBox {
id: symbolBox
label: qsTr("Symbol")
value: root.symbol
}
CustomPreviewBox {
id: totalbox
label: qsTr("Total")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.supply)
isLoading: !root.infiniteSupply &&
((!root.isAssetView && root.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(d.burnState === Constants.ContractTransactionStatus.InProgress))
}
CustomPreviewBox {
id: remainingBox
label: qsTr("Remaining")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.remainingTokens)
isLoading: !root.infiniteSupply && (d.burnState === Constants.ContractTransactionStatus.InProgress)
}
CustomPreviewBox {
visible: root.isAssetView
label: qsTr("DP")
value: root.decimals
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Transferable")
value: root.transferable ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Destructible")
value: root.remotelyDestruct ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
label: qsTr("Account")
value: root.accountName
}
Rectangle {
height: symbolBox.height
width: rowChain.implicitWidth + 2 * Style.current.padding
border.width: 1
radius: 8
border.color: Theme.palette.baseColor2
color: "transparent"
RowLayout {
id: rowChain
anchors.centerIn: parent
spacing: Style.current.padding
SVGImage {
Layout.alignment: Qt.AlignVCenter
height: 24
width: height
source: Style.svg(root.chainIcon)
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
text: root.chainName
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
}
}
}
}
StatusBaseText {
Layout.fillWidth: true
text: root.description
wrapMode: TextEdit.WordWrap
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
} }
RowLayout { RowLayout {
@ -324,7 +120,7 @@ StatusScrollView {
wrapMode: Text.Wrap wrapMode: Text.Wrap
font.pixelSize: Style.current.primaryTextFontSize font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
text: qsTr("Make sure youre happy with your token before minting it as it cant be edited later") text: qsTr("Review token details before minting it as they cant be edited later")
} }
} }
@ -354,12 +150,4 @@ StatusScrollView {
onRemoteDestructRequested: root.remoteDestructRequested(address) onRemoteDestructRequested: root.remoteDestructRequested(address)
} }
} }
Connections {
target: root.token
function onRemotelyDestructStateChanged() {
if(root.remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
}
}
} }

View File

@ -0,0 +1,300 @@
import QtQuick 2.15
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
import StatusQ.Popups 0.1
import utils 1.0
import AppLayouts.Communities.panels 1.0
import AppLayouts.Communities.helpers 1.0
import AppLayouts.Wallet.controls 1.0
import SortFilterProxyModel 0.2
StatusScrollView {
id: root
property int viewWidth: 560 // by design
// Community info:
property string communityName
property url communityLogo
property color communityColor
// Network related properties:
property var layer1Networks
property var layer2Networks
property var testNetworks
property var enabledNetworks
property var allNetworks
// Wallet account expected roles: address, name, color, emoji, walletType
property var accounts
// Privileged tokens:
readonly property TokenObject ownerToken: TokenObject {
type: Constants.TokenType.ERC721
isPrivilegedToken: true
isOwner: true
artworkSource: root.communityLogo
color: root.communityColor
symbol: PermissionsHelpers.autogenerateSymbol(isOwner, root.communityName)
transferable: true
remotelyDestruct: false
supply: 1
infiniteSupply: false
description: qsTr("This is the %1 Owner token. The hodler of this collectible has ultimate control over %1 Community token administration.").arg(root.communityName)
}
readonly property TokenObject tMasterToken: TokenObject {
type: Constants.TokenType.ERC721
isPrivilegedToken: true
artworkSource: root.communityLogo
color: root.communityColor
symbol: PermissionsHelpers.autogenerateSymbol(isOwner, root.communityName)
remotelyDestruct: true
description: qsTr("This is the %1 TokenMaster token. The hodler of this collectible has full admin rights for the %1 Community in Status and can mint and airdrop %1 Community tokens.").arg(root.communityName)
}
signal mintClicked
QtObject {
id: d
readonly property int titleSize: 17
readonly property int iconSize: 20
}
padding: 0
contentWidth: mainLayout.width
contentHeight: mainLayout.height
Component.onCompleted: networkSelector.setChain(ownerToken.chainId)
ColumnLayout {
id: mainLayout
width: root.viewWidth
spacing: Style.current.padding
// Owner token defintion:
StatusBaseText {
Layout.maximumWidth: root.viewWidth
elide: Text.ElideMiddle
font.pixelSize: d.titleSize
font.bold: true
text: qsTr("Owner-%1").arg(root.communityName)
}
TokenInfoPanel {
Layout.fillWidth: true
token: root.ownerToken
}
StatusModalDivider {
Layout.fillWidth: true
topPadding: Style.current.padding
bottomPadding: Style.current.padding
}
// TMaster token definition:
StatusBaseText {
Layout.maximumWidth: root.viewWidth
elide: Text.ElideMiddle
font.pixelSize: d.titleSize
font.bold: true
text: qsTr("TMaster-%1").arg(root.communityName)
}
TokenInfoPanel {
Layout.fillWidth: true
token: root.tMasterToken
}
StatusModalDivider {
Layout.fillWidth: true
topPadding: Style.current.padding
bottomPadding: Style.current.padding
}
// TO BE REMOVED: It will be removed with the new fees panel
CustomLabelDescriptionComponent {
label: qsTr("Select account")
description: qsTr("This account will be where you receive your Owner token and will also be the account that pays the token minting gas fees.")
}
// TO BE REMOVED: It will be removed with the new fees panel
StatusEmojiAndColorComboBox {
id: accountBox
readonly property string address: SQUtils.ModelUtils.get(root.accounts, currentIndex, "address")
readonly property string initAccountName: ownerToken.accountName
readonly property int initIndex: SQUtils.ModelUtils.indexOf(root.accounts, "name", initAccountName)
Layout.fillWidth: true
Layout.topMargin: -Style.current.halfPadding
currentIndex: (initIndex !== -1) ? initIndex : 0
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) }
}
]
filters: ValueFilter {
roleName: "walletType"
value: Constants.watchWalletType
inverted: true
}
}
type: StatusComboBox.Type.Secondary
size: StatusComboBox.Size.Small
implicitHeight: 44
defaultAssetName: "filled-account"
onAddressChanged: {
ownerToken.accountAddress = address
tMasterToken.accountAddress = address
}
control.onDisplayTextChanged: {
ownerToken.accountName = control.displayText
tMasterToken.accountName = control.displayText
}
}
CustomNetworkFilterRowComponent {
id: networkSelector
label: qsTr("Select network")
description: qsTr("The network on which these tokens will be minted.")
}
RowLayout {
Layout.fillWidth: true
Layout.topMargin: Style.current.halfPadding
StatusIcon {
Layout.preferredWidth: d.iconSize
Layout.preferredHeight: d.iconSize
Layout.alignment: Qt.AlignTop
color: Theme.palette.baseColor1
icon: "info"
}
StatusBaseText {
Layout.fillWidth: true
wrapMode: Text.Wrap
font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1
lineHeight: 1.2
text: qsTr("Make sure youre happy with the blockchain network selected before minting these tokens as they cant be moved to a different network later.")
}
}
StatusButton {
Layout.preferredHeight: 44
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
Layout.bottomMargin: Style.current.padding
text: qsTr("Mint")
onClicked: root.mintClicked()
}
}
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 CustomNetworkFilterRowComponent: ColumnLayout {
id: networkComponent
property string label
property string description
function setChain(chainId) { netFilter.setChain(chainId) }
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
spacing: 8
CustomLabelDescriptionComponent {
label: networkComponent.label
description: networkComponent.description
}
NetworkFilter {
id: netFilter
Layout.fillWidth: true
allNetworks: root.allNetworks
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
enabledNetworks: root.enabledNetworks
multiSelection: false
onToggleNetwork: (network) =>
{
// Set Owner Token network properties:
ownerToken.chainId = network.chainId
ownerToken.chainName = network.chainName
ownerToken.chainIcon = network.iconUrl
// Set TMaster Token network properties:
tMasterToken.chainId = network.chainId
tMasterToken.chainName = network.chainName
tMasterToken.chainIcon = network.iconUrl
}
}
}
}

View File

@ -6,6 +6,7 @@ import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import AppLayouts.Communities.panels 1.0 import AppLayouts.Communities.panels 1.0
import AppLayouts.Communities.helpers 1.0
import utils 1.0 import utils 1.0
@ -24,19 +25,6 @@ StatusScrollView {
contentWidth: mainLayout.width contentWidth: mainLayout.width
contentHeight: mainLayout.height contentHeight: mainLayout.height
QtObject {
id: d
function generateSymbol(isOwner) {
// TODO: Add a kind of verification for not repeating symbols
const shortName = root.communityName.substring(0, 3)
if(isOwner)
return "OWN" + shortName.toUpperCase()
else
return "TM" + shortName.toUpperCase()
}
}
ColumnLayout { ColumnLayout {
id: mainLayout id: mainLayout
@ -146,7 +134,7 @@ StatusScrollView {
Layout.alignment: Qt.AlignBottom Layout.alignment: Qt.AlignBottom
text: d.generateSymbol(panel.isOwner) text: PermissionsHelpers.autogenerateSymbol(panel.isOwner, root.communityName)
font.pixelSize: Style.current.primaryTextFontSize font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }

View File

@ -6,6 +6,7 @@ CommunityTokenView 1.0 CommunityTokenView.qml
EditAirdropView 1.0 EditAirdropView.qml EditAirdropView 1.0 EditAirdropView.qml
EditPermissionView 1.0 EditPermissionView.qml EditPermissionView 1.0 EditPermissionView.qml
EditCommunityTokenView 1.0 EditCommunityTokenView.qml EditCommunityTokenView 1.0 EditCommunityTokenView.qml
EditOwnerTokenView 1.0 EditOwnerTokenView.qml
HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml
JoinCommunityView 1.0 JoinCommunityView.qml JoinCommunityView 1.0 JoinCommunityView.qml
MintedTokensView 1.0 MintedTokensView.qml MintedTokensView 1.0 MintedTokensView.qml

View File

@ -45,6 +45,13 @@ QtObject {
assetItem.infiniteSupply, assetItem.decimals, assetItem.chainId, jsonArtworkFile) assetItem.infiniteSupply, assetItem.decimals, assetItem.chainId, jsonArtworkFile)
} }
function deployOwnerToken(communityId, ownerToken, tMasterToken)
{
// NOTE for backend team: `ownerToken` and `tMasterToken` can be used to do an assertion before the deployment process starts, since
// the objects have been created to display the token details to the user and must be the same than backend builds.
console.log("TODO: Backend Owner and Token Master token deployment!")
}
function deleteToken(communityId, contractUniqueKey) { function deleteToken(communityId, contractUniqueKey) {
console.log("TODO: Delete token bakend!") console.log("TODO: Delete token bakend!")
} }