From 3a0954c5dad6e75359c03517fa7e5f8b56014483 Mon Sep 17 00:00:00 2001 From: Noelia Date: Mon, 10 Jul 2023 16:12:25 +0200 Subject: [PATCH] feat(OwnerToken): Add Mint Owner token view - Created new `Owner Token` and `TokenMaster Token` welcome screen. - Navigations added. - Storybook support added. Closes #11292 --- storybook/PagesModel.qml | 4 + storybook/figma.json | 3 + .../pages/MintTokensSettingsPanelPage.qml | 10 + storybook/pages/OwnerTokenWelcomeViewPage.qml | 79 +++++++ .../panels/MintTokensSettingsPanel.qml | 44 +++- .../views/CommunitySettingsView.qml | 3 + .../views/OwnerTokenWelcomeView.qml | 199 ++++++++++++++++++ ui/app/AppLayouts/Communities/views/qmldir | 1 + .../shared/controls/DisabledTooltipButton.qml | 4 +- 9 files changed, 339 insertions(+), 8 deletions(-) create mode 100644 storybook/pages/OwnerTokenWelcomeViewPage.qml create mode 100644 ui/app/AppLayouts/Communities/views/OwnerTokenWelcomeView.qml diff --git a/storybook/PagesModel.qml b/storybook/PagesModel.qml index 41b839849f..d3fb2bb0c9 100644 --- a/storybook/PagesModel.qml +++ b/storybook/PagesModel.qml @@ -77,6 +77,10 @@ ListModel { title: "CommunitiesView" section: "Views" } + ListElement { + title: "OwnerTokenWelcomeView" + section: "Views" + } ListElement { title: "StatusCommunityCard" section: "Panels" diff --git a/storybook/figma.json b/storybook/figma.json index 8636074a88..b5b395b304 100644 --- a/storybook/figma.json +++ b/storybook/figma.json @@ -233,5 +233,8 @@ ], "OverviewSettingsPanel": [ "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31229-627216&mode=design&t=KoQOW7vmoNc7f41m-0" + ], + "OwnerTokenWelcomeView": [ + "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?type=design&node-id=34794%3A590064&mode=design&t=eabTmd6JZbuycoy8-1" ] } diff --git a/storybook/pages/MintTokensSettingsPanelPage.qml b/storybook/pages/MintTokensSettingsPanelPage.qml index da02bf1971..3916862cfb 100644 --- a/storybook/pages/MintTokensSettingsPanelPage.qml +++ b/storybook/pages/MintTokensSettingsPanelPage.qml @@ -53,7 +53,10 @@ SplitView { tokensModel: editorModelChecked.checked ? emptyModel : mintedTokensModel isAdmin: adminChecked.checked isOwner: ownerChecked.checked + communityLogo: ModelsData.collectibles.doodles + communityColor: "#FFC4E9" communityName: communityNameText.text + isTokenMasterOwner: masterTokenOwnerChecked.checked layer1Networks: NetworksModel.layer1Networks layer2Networks: NetworksModel.layer2Networks testNetworks: NetworksModel.testNetworks @@ -102,6 +105,13 @@ SplitView { text: "Is owner?" } + CheckBox { + id: masterTokenOwnerChecked + checked: true + + text: "Is TMaster token owner?" + } + CheckBox { id: adminChecked checked: true diff --git a/storybook/pages/OwnerTokenWelcomeViewPage.qml b/storybook/pages/OwnerTokenWelcomeViewPage.qml new file mode 100644 index 0000000000..955b310984 --- /dev/null +++ b/storybook/pages/OwnerTokenWelcomeViewPage.qml @@ -0,0 +1,79 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.14 + +import AppLayouts.Communities.views 1.0 + +import StatusQ.Core.Theme 0.1 + +import Storybook 1.0 +import Models 1.0 + +SplitView { + orientation: Qt.Vertical + SplitView.fillWidth: true + + Logs { id: logs } + + OwnerTokenWelcomeView { + id: view + + SplitView.fillWidth: true + SplitView.fillHeight: true + + padding: 50 + anchors.margins: 50 + communityLogo: doodles.checked ? ModelsData.collectibles.doodles : ModelsData.collectibles.mana + communityColor: color1.checked ? "#FFC4E9" : "#f44336" + communityName: communityName.text + + onNextClicked: logs.logEvent("OwnerTokenWelcomeView::onNextClicked") + } + + LogsAndControlsPanel { + id: logsAndControlsPanel + + SplitView.minimumHeight: 100 + SplitView.preferredHeight: 200 + + logsView.logText: logs.logText + + ColumnLayout { + RowLayout { + RadioButton { + id: color1 + + text: "Light pink" + checked: true + } + + RadioButton { + text: "Orange" + } + } + + RowLayout { + RadioButton { + id: doodles + text: "Doodles" + checked: true + } + + RadioButton { + text: "Mana" + } + } + + RowLayout { + Label { + text: "Community name:" + } + + TextInput { + id: communityName + text: "Doodles" + } + } + } + } +} diff --git a/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml b/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml index 90658e9345..5ddd037267 100644 --- a/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml +++ b/ui/app/AppLayouts/Communities/panels/MintTokensSettingsPanel.qml @@ -22,8 +22,12 @@ StackView { // General properties: required property bool isOwner + required property bool isTokenMasterOwner required property bool isAdmin required property string communityName + required property string communityLogo + required property color communityColor + property int viewWidth: 560 // by design // Models: @@ -74,19 +78,29 @@ StackView { function openNewTokenForm(isAssetView) { resetNavigation() - const properties = { isAssetView } - root.push(newTokenViewComponent, properties, StackView.Immediate) + if(d.isTokenOwnerDeployed) { + const properties = { isAssetView } + root.push(newTokenViewComponent, properties, StackView.Immediate) + } else { + root.push(ownerTokenViewComponent, StackView.Immediate) + } } property string previousPageName: depth > 1 ? qsTr("Back") : "" + QtObject { + id: d + + readonly property bool isTokenOwnerDeployed: root.tokensModel.count > 0 // TODO: Checker to ensure owner token is deployed + } + initialItem: SettingsPage { implicitWidth: 0 title: qsTr("Tokens") buttons: DisabledTooltipButton { - readonly property bool onlyAdmin: root.isAdmin && !root.isOwner - readonly property bool buttonEnabled: root.isOwner && root.tokensModel.count > 0 /*TODO: Replace last comparison to checker to ensure owner token is deployed*/ + property bool onlyAdmin: root.isAdmin && !root.isOwner + property bool buttonEnabled: (root.isOwner || root.isTokenMasterOwner) && d.isTokenOwnerDeployed buttonType: DisabledTooltipButton.Normal aliasedObjectName: "addNewItemButton" @@ -94,7 +108,7 @@ StackView { enabled: onlyAdmin || buttonEnabled interactive: buttonEnabled onClicked: root.push(newTokenViewComponent, StackView.Immediate) - tooltipText: qsTr("In order to mint, you must Hodl the TokenMaster token for %1").arg(root.communityName) + tooltipText: qsTr("In order to mint, you must hodl the TokenMaster token for %1").arg(root.communityName) } contentItem: MintedTokensView { @@ -102,7 +116,7 @@ StackView { isOwner: root.isOwner onItemClicked: root.push(tokenViewComponent, { tokenKey }, StackView.Immediate) - onMintOwnerTokenClicked: root.push(newTokenViewComponent, StackView.Immediate) // TEMP: It will navigate to new token owner flow. Now, to current minting flow. + onMintOwnerTokenClicked: root.push(ownerTokenViewComponent, StackView.Immediate) } } @@ -113,6 +127,24 @@ StackView { } // Mint tokens possible view contents: + Component { + id: ownerTokenViewComponent + + SettingsPage { + id: ownerTokenPage + + title: qsTr("Mint Owner token") + + contentItem: OwnerTokenWelcomeView { + communityLogo: root.communityLogo + communityColor: root.communityColor + communityName: root.communityName + + onNextClicked: root.push(newTokenViewComponent, StackView.Immediate) // TEMP: It will navigate to new token owner flow. Now, to current minting flow. + } + } + } + Component { id: newTokenViewComponent diff --git a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml index 03f36b1458..6879898b92 100644 --- a/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml +++ b/ui/app/AppLayouts/Communities/views/CommunitySettingsView.qml @@ -301,8 +301,11 @@ StatusSectionLayout { } communityName: root.community.name + communityLogo: root.community.image + communityColor: root.community.color isOwner: root.isOwner isAdmin: root.isAdmin + isTokenMasterOwner: false // TODO: Backend tokensModel: root.community.communityTokens tokensModelWallet: root.rootStore.tokensModelWallet layer1Networks: communityTokensStore.layer1Networks diff --git a/ui/app/AppLayouts/Communities/views/OwnerTokenWelcomeView.qml b/ui/app/AppLayouts/Communities/views/OwnerTokenWelcomeView.qml new file mode 100644 index 0000000000..d7883fc215 --- /dev/null +++ b/ui/app/AppLayouts/Communities/views/OwnerTokenWelcomeView.qml @@ -0,0 +1,199 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.14 + +import StatusQ.Core 0.1 +import StatusQ.Controls 0.1 +import StatusQ.Core.Theme 0.1 + +import AppLayouts.Communities.panels 1.0 + +import utils 1.0 + +StatusScrollView { + id: root + + property int viewWidth: 560 // by design + + required property string communityLogo + required property color communityColor + required property string communityName + + signal nextClicked + + padding: 0 + contentWidth: mainLayout.width + 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 { + id: mainLayout + + width: root.viewWidth + spacing: 20 + + StatusBaseText { + id: introPanel + + Layout.fillWidth: true + + wrapMode: Text.WordWrap + lineHeight: 1.2 + font.pixelSize: Style.current.primaryTextFontSize + text: qsTr("Your Owner token will give you permissions to access the token management features for your community. This token is very important - only one will ever exist, and if this token gets lost then access to the permissions it enables for your community will be lost forever as well.

+ Minting your Owner token also automatically mints your community’s TokenMaster token. You can airdrop your community’s TokenMaster token to anybody you wish to grant both Admin permissions and permission to access your community’s token management functions to.

+ Only the hodler of the Owner token can airdrop TokenMaster tokens. TokenMaster tokens are soulbound (meaning they can’t be transferred), and you (the hodler of the Owner token) can remotely destruct a TokenMaster token at any time, to revoke TokenMaster permissions from any individual.") + } + + InfoPanel { + isOwner: true + checkersModel: [ + qsTr("Only 1 will ever exist"), + qsTr("Hodler is the owner of the Community"), + qsTr("Ability to airdrop / destroy TokenMaster token"), + qsTr("Ability to mint and airdrop Community tokens") + ] + } + + InfoPanel { + isOwner: false + showTag: true + checkersModel: [ + qsTr("Unlimited supply"), + qsTr("Grants full Community admin rights"), + qsTr("Ability to mint and airdrop Community tokens"), + qsTr("Non-transferrable"), + qsTr("Remotely destructible by the Owner token hodler") + ] + } + + component InfoPanel : Rectangle { + id: panel + + property bool isOwner + property bool showTag + property alias checkersModel: checkersItems.model + readonly property int margins: Style.current.bigPadding + + Layout.fillWidth: true + Layout.preferredHeight: panelRow.implicitHeight + + color: "transparent" + radius: 8 + border.color: Theme.palette.baseColor2 + + RowLayout { + id: panelRow + + width: parent.width + spacing: panel.margins + + PrivilegedTokenArtworkPanel { + Layout.alignment: Qt.AlignTop + Layout.topMargin: panel.margins + Layout.leftMargin: Layout.topMargin + + isOwner: panel.isOwner + artwork: root.communityLogo + color: root.communityColor + showTag: panel.showTag + } + + ColumnLayout { + id: col + + Layout.alignment: Qt.AlignTop + Layout.topMargin: panel.margins + Layout.bottomMargin: panel.margins + Layout.fillWidth: true + + Item { + id: panelTextHeader + + Layout.fillWidth: true + Layout.preferredHeight: headerRow.implicitHeight + Layout.rightMargin: panel.margins + + RowLayout { + id: headerRow + + spacing: Style.current.halfPadding + + StatusBaseText { + Layout.alignment: Qt.AlignBottom + Layout.maximumWidth: panelTextHeader.width - symbol.width + + text: panel.isOwner ? qsTr("%1 Owner token").arg(root.communityName) : + qsTr("%1 TokenMaster token").arg(root.communityName) + font.bold: true + font.pixelSize: 17 + elide: Text.ElideMiddle + } + + StatusBaseText { + id: symbol + + Layout.alignment: Qt.AlignBottom + + text: d.generateSymbol(panel.isOwner) + font.pixelSize: Style.current.primaryTextFontSize + color: Theme.palette.baseColor1 + } + } + } + + ColumnLayout { + id: checkersColumn + + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + Layout.topMargin: 6 + + Repeater { + id: checkersItems + + RowLayout { + StatusIcon { + icon: "tiny/checkmark" + color: Theme.palette.successColor1 + width: 20 + height: width + } + + StatusBaseText { + Layout.fillWidth: true + Layout.rightMargin: panel.margins + + text: modelData + lineHeight: 1.2 + font.pixelSize: Style.current.additionalTextSize + wrapMode: Text.WordWrap + } + } + } + } + } + } + } + + StatusButton { + Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: Style.current.bigPadding + + text: qsTr("Next") + + onClicked: root.nextClicked() + } + } +} diff --git a/ui/app/AppLayouts/Communities/views/qmldir b/ui/app/AppLayouts/Communities/views/qmldir index a73e015877..8697923373 100644 --- a/ui/app/AppLayouts/Communities/views/qmldir +++ b/ui/app/AppLayouts/Communities/views/qmldir @@ -9,5 +9,6 @@ EditCommunityTokenView 1.0 EditCommunityTokenView.qml HoldingsSelectionModel 1.0 HoldingsSelectionModel.qml JoinCommunityView 1.0 JoinCommunityView.qml MintedTokensView 1.0 MintedTokensView.qml +OwnerTokenWelcomeView 1.0 OwnerTokenWelcomeView.qml PermissionsView 1.0 PermissionsView.qml WelcomeSettingsView 1.0 WelcomeSettingsView.qml diff --git a/ui/imports/shared/controls/DisabledTooltipButton.qml b/ui/imports/shared/controls/DisabledTooltipButton.qml index c9407e7386..99c9c8ae58 100644 --- a/ui/imports/shared/controls/DisabledTooltipButton.qml +++ b/ui/imports/shared/controls/DisabledTooltipButton.qml @@ -17,8 +17,8 @@ Item { Flat // 1 } - implicitWidth: buttonLoader.item.width - implicitHeight: buttonLoader.item.height + implicitWidth: !!buttonLoader.item ? buttonLoader.item.width : 0 + implicitHeight: !!buttonLoader.item ? buttonLoader.item.height : 0 Loader { id: buttonLoader