feat(FirstTokenReceivedPopup): Created new popup `FirstTokenReceived`

- Created new popup component.
- Created related `storybook` page.
- Integration of the popup into the app.

Closes #12366
This commit is contained in:
Noelia 2024-01-24 12:49:46 +01:00 committed by Noelia
parent ab61784816
commit aaa9937124
7 changed files with 470 additions and 7 deletions

View File

@ -0,0 +1,258 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Storybook 1.0
import Models 1.0
import AppLayouts.Communities.popups 1.0
import AppLayouts.Communities.helpers 1.0
import utils 1.0
SplitView {
Logs { id: logs }
SplitView {
orientation: Qt.Vertical
SplitView.fillWidth: true
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
PopupBackground {
anchors.fill: parent
}
Button {
anchors.centerIn: parent
text: "Reopen"
onClicked: dialog.open()
}
FirstTokenReceivedPopup {
id: dialog
anchors.centerIn: parent
closePolicy: Popup.NoAutoClose
visible: true
modal: false
communityId: "123"
communityName: communityNameText.text
communityLogo: ModelsData.collectibles.doodles
communitiesStore: QtObject {
function navigateToCommunity(id) {
logs.logEvent("FirstTokenReceivedPopup::onNavigateToCommunity: " + id)
}
}
tokenSymbol: tokenSymbolText.text
tokenName: tokenNameText.text
tokenAmount: tokenAmountText.text
tokenType: Constants.TokenType.ERC20
tokenImage: ModelsData.assets.eth
onHideClicked: logs.logEvent("FirstTokenReceivedPopup::onHideClicked")
}
}
LogsAndControlsPanel {
id: logsAndControlsPanel
SplitView.minimumHeight: 100
SplitView.preferredHeight: 150
logsView.logText: logs.logText
}
}
Pane {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 300
Column {
spacing: 12
Label {
text: "Community Name"
font.bold: true
}
TextInput {
id: communityNameText
text: "Doodles"
}
Label {
text: "Community Logo"
font.bold: true
}
Column {
RadioButton {
id: doodleLogo
text: "Doodle"
checked: true
onCheckedChanged: dialog.communityLogo = ModelsData.collectibles.doodles
}
RadioButton {
id: manaLogo
text: "Mana"
onCheckedChanged: dialog.communityLogo = ModelsData.collectibles.mana
}
RadioButton {
id: superRareLogo
text: "Status"
onCheckedChanged: dialog.communityLogo = ModelsData.collectibles.custom
}
}
Label {
text: "Token amount"
font.bold: true
}
TextInput {
id: tokenAmountText
text: "1"
}
Label {
text: "Token name"
font.bold: true
}
TextInput {
id: tokenNameText
text: "DoodleCoin"
}
Label {
text: "Token symbol"
font.bold: true
}
TextInput {
id: tokenSymbolText
text: "DOO"
}
Label {
text: "Token Type"
font.bold: true
}
Column {
RadioButton {
id: assetType
text: "Asset"
checked: true
onCheckedChanged: dialog.tokenType = Constants.TokenType.ERC20
}
RadioButton {
id: collectibleType
text: "Collectible"
onCheckedChanged: dialog.tokenType = Constants.TokenType.ERC721
}
}
Label {
text: "Token Image"
font.bold: true
}
Column {
visible: assetType.checked
onVisibleChanged: {
if(visible) {
eth.checked = true
dialog.tokenImage = ModelsData.assets.eth
}
}
RadioButton {
id: eth
text: "Eth"
checked: true
onCheckedChanged: dialog.tokenImage = ModelsData.assets.eth
}
RadioButton {
text: "SuperRare"
onCheckedChanged: dialog.tokenImage = ModelsData.banners.superRare
}
RadioButton {
text: "SNT"
onCheckedChanged: dialog.tokenImage = ModelsData.assets.snt
}
}
Column {
visible: collectibleType.checked
onVisibleChanged: {
if(visible) {
superrare.checked = true
dialog.tokenImage = ModelsData.banners.superRare
}
}
RadioButton {
id: superrare
text: "SuperRare"
checked: true
onCheckedChanged: dialog.tokenImage = ModelsData.banners.superRare
}
RadioButton {
text: "Coinbase"
onCheckedChanged: dialog.tokenImage = ModelsData.banners.coinbase
}
RadioButton {
text: "Dragonereum"
onCheckedChanged: dialog.tokenImage = ModelsData.banners.dragonereum
}
}
}
}
}
// category: Popups
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=18700%3A276658&mode=design&t=QzoyErtcBX8A54G7-1
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=20765%3A244128&mode=design&t=X279c9Ix6QKMKWjM-1

View File

@ -0,0 +1,146 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml.Models 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import AppLayouts.Communities.panels 1.0
import utils 1.0
StatusDialog {
id: root
// Community related props:
required property var communitiesStore
required property string communityId
required property string communityName
required property string communityLogo
// Token related props:
required property string tokenName
required property string tokenSymbol
required property string tokenImage
required property string tokenAmount
required property int tokenType // ERC20 or ERC721
readonly property bool isAssetType : tokenType === Constants.TokenType.ERC20
signal hideClicked
QtObject {
id: d
readonly property string contentText: root.isAssetType ? qsTr("Congratulations on receiving your first community asset: <br><b>%1 %2 (%3) minted by %4</b>. Community assets are assets that have been minted by a community. As these assets cannot be verified, always double check their origin and validity before interacting with them. If in doubt, ask a trusted member or admin of the relevant community.").arg(root.tokenAmount).arg(root.tokenName).arg(root.tokenSymbol).arg(root.communityName)
: qsTr("Congratulations on receiving your first community collectible: <br><b>%1 %2 minted by %3</b>. Community collectibles are collectibles that have been minted by a community. As these collectibles cannot be verified, always double check their origin and validity before interacting with them. If in doubt, ask a trusted member or admin of the relevant community.").arg(root.tokenAmount).arg(root.tokenName).arg(root.communityName)
}
width: 521 // by design
padding: 0
contentItem: StatusScrollView {
id: scrollView
contentWidth: availableWidth
padding: Style.current.padding
ColumnLayout {
spacing: Style.current.padding
width: scrollView.availableWidth
StatusRoundedImage {
Layout.alignment: Qt.AlignHCenter
Layout.margins: Style.current.padding
Layout.preferredWidth: 68
Layout.preferredHeight: Layout.preferredWidth
radius: root.isAssetType ? width / 2 : 8
image.source: root.tokenImage
showLoadingIndicator: false
image.fillMode: Image.PreserveAspectCrop
}
StatusBaseText {
Layout.fillWidth: true
text: d.contentText
textFormat: Text.RichText
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
lineHeight: 1.2
}
// Navigate to community button
StatusListItem {
Layout.fillWidth: true
Layout.bottomMargin: Style.current.halfPadding
title: root.communityName
border.color: Theme.palette.baseColor2
asset.name: root.communityLogo
asset.isImage: true
asset.isLetterIdenticon: !asset.name
components: [
RowLayout {
StatusIcon {
Layout.alignment: Qt.AlignVCenter
icon: "arrow-right"
color: Theme.palette.primaryColor1
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: Style.current.padding
text: qsTr("Visit Community")
font.pixelSize: Style.current.additionalTextSize
color: Theme.palette.primaryColor1
}
}
]
onClicked: {
root.close()
root.communitiesStore.navigateToCommunity(root.communityId)
}
}
}
}
header: StatusDialogHeader {
headline.title: root.isAssetType ? qsTr("You received your first community asset") : qsTr("You received your first community collectible")
actions.closeButton.onClicked: root.close()
}
footer: StatusDialogFooter {
spacing: Style.current.padding
rightButtons: ObjectModel {
StatusFlatButton {
id: hideBtn
visible: false // TODO: #13293
text: root.isAssetType ? qsTr("Hide this asset") : qsTr("Hide this collectible")
onClicked: {
root.close()
root.hideClicked()
}
}
StatusButton {
id: acceptBtn
text: qsTr("Got it!")
onClicked: root.close()
}
}
}
}

View File

@ -9,6 +9,7 @@ EnableShardingPopup 1.0 EnableShardingPopup.qml
ExportControlNodePopup 1.0 ExportControlNodePopup.qml ExportControlNodePopup 1.0 ExportControlNodePopup.qml
FinaliseOwnershipDeclinePopup 1.0 FinaliseOwnershipDeclinePopup.qml FinaliseOwnershipDeclinePopup 1.0 FinaliseOwnershipDeclinePopup.qml
FinaliseOwnershipPopup 1.0 FinaliseOwnershipPopup.qml FinaliseOwnershipPopup 1.0 FinaliseOwnershipPopup.qml
FirstTokenReceivedPopup 1.0 FirstTokenReceivedPopup.qml
HoldingsDropdown 1.0 HoldingsDropdown.qml HoldingsDropdown 1.0 HoldingsDropdown.qml
ImportControlNodePopup 1.0 ImportControlNodePopup.qml ImportControlNodePopup 1.0 ImportControlNodePopup.qml
InDropdown 1.0 InDropdown.qml InDropdown 1.0 InDropdown.qml

View File

@ -78,6 +78,7 @@ QtObject {
Global.openTransferOwnershipPopup.connect(openTransferOwnershipPopup) Global.openTransferOwnershipPopup.connect(openTransferOwnershipPopup)
Global.openFinaliseOwnershipPopup.connect(openFinaliseOwnershipPopup) Global.openFinaliseOwnershipPopup.connect(openFinaliseOwnershipPopup)
Global.openDeclineOwnershipPopup.connect(openDeclineOwnershipPopup) Global.openDeclineOwnershipPopup.connect(openDeclineOwnershipPopup)
Global.openFirstTokenReceivedPopup.connect(openFirstTokenReceivedPopup)
} }
property var currentPopup property var currentPopup
@ -318,6 +319,20 @@ QtObject {
openPopup(declineOwnershipPopup, { communityName: communityName, communityId: communityId }) openPopup(declineOwnershipPopup, { communityName: communityName, communityId: communityId })
} }
function openFirstTokenReceivedPopup(communityId, communityName, communityLogo, tokenSymbol, tokenName, tokenAmount, tokenType, tokenImage) {
openPopup(firstTokenReceivedPopup,
{
communityId: communityId,
communityName: communityName,
communityLogo: communityLogo,
tokenSymbol: tokenSymbol,
tokenName: tokenName,
tokenAmount: tokenAmount,
tokenType: tokenType,
tokenImage: tokenImage
})
}
readonly property list<Component> _components: [ readonly property list<Component> _components: [
Component { Component {
id: removeContactConfirmationDialog id: removeContactConfirmationDialog
@ -933,7 +948,17 @@ QtObject {
onDeclineClicked: root.ownershipDeclined() onDeclineClicked: root.ownershipDeclined()
} }
} },
// End of components related to transfer community ownership flow. // End of components related to transfer community ownership flow.
Component {
id: firstTokenReceivedPopup
FirstTokenReceivedPopup {
communitiesStore: root.communitiesStore
onHideClicked: console.warn("TODO: OPEN HIDE POPUP")
}
}
] ]
} }

View File

@ -129,7 +129,7 @@ QtObject {
} }
// Community token received in the user wallet: // Community token received in the user wallet:
function onCommunityTokenReceived(name, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName) { function onCommunityTokenReceived(name, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName, symbol) {
// Some error control: // Some error control:
if(tokenType !== Constants.TokenType.ERC20 && tokenType !== Constants.TokenType.ERC721) { if(tokenType !== Constants.TokenType.ERC20 && tokenType !== Constants.TokenType.ERC721) {
@ -139,9 +139,14 @@ QtObject {
var data = { var data = {
communityId: communityId, communityId: communityId,
communityName: communityName,
chainId: chainId, chainId: chainId,
txHash: txHash, txHash: txHash,
tokenType: tokenType tokenType: tokenType,
tokenName: name,
tokenSymbol: symbol,
tokenImage: image,
tokenAmount: balance
} }
if(isFirst) { if(isFirst) {
@ -216,7 +221,24 @@ QtObject {
console.warn("Unexpected transaction hash while trying to navigate to the details page: " + txHash) console.warn("Unexpected transaction hash while trying to navigate to the details page: " + txHash)
return return
case ToastsManager.ActionType.OpenFirstCommunityTokenPopup: case ToastsManager.ActionType.OpenFirstCommunityTokenPopup:
console.warn("TODO: #12366") if(actionData) {
var data = JSON.parse(actionData)
var communityId = data.communityId
var communityName = data.communityName
var tokenType = data.tokenType
var tokenName = data.tokenName
var tokenSymbol = data.tokenSymbol
var tokenImage = data.tokenImage
var tokenAmount = data.tokenAmount
Global.openFirstTokenReceivedPopup(communityId,
communityName,
rootChatStore.getCommunityDetailsAsJson(communityId).image,
tokenSymbol,
tokenName,
tokenAmount,
tokenType,
tokenImage);
}
return return
default: default:
console.warn("ToastsManager: Action type is not defined") console.warn("ToastsManager: Action type is not defined")

View File

@ -38,7 +38,8 @@ QtObject {
string communityId, string communityName, string communityId, string communityName,
string balance, int chainId, string balance, int chainId,
string txHash, bool isFirst, string txHash, bool isFirst,
int tokenType, string walletAccountName) int tokenType, string walletAccountName,
string symbol)
// Minting tokens: // Minting tokens:
function deployCollectible(communityId, collectibleItem) function deployCollectible(communityId, collectibleItem)
@ -136,16 +137,18 @@ QtObject {
root.ownerTokenReceived(communityId, communityName) root.ownerTokenReceived(communityId, communityName)
} }
function onCommunityTokenReceived(name, image, communityId, communityName, communityColor /*Unused, can be removed*/, balance, chainId, txHash/*, isFirst, tokenType, walletAccountName*/) { function onCommunityTokenReceived(name, image, communityId, communityName, communityColor /*Unused, can be removed*/, balance, chainId, txHash/*, isFirst, tokenType, walletAccountName, symbol*/) {
// TODO BACKEND: #13250 // TODO BACKEND: #13250
// ** `isFirst` property will be true if it's the first time the user receives a community asset and a community collectible // ** `isFirst` property will be true if it's the first time the user receives a community asset and a community collectible
// ** `tokenType` property will determine if the received minted token is an ERC20 or an ERC720 // ** `tokenType` property will determine if the received minted token is an ERC20 or an ERC720
// ** `walletAccountName` property will provide the wallet account name where the token was received // ** `walletAccountName` property will provide the wallet account name where the token was received
// ** `symbol` property will provide the token symbol
var isFirst = false var isFirst = false
var tokenType = Constants.TokenType.ERC20 var tokenType = Constants.TokenType.ERC20
var walletAccountName = "Status account" var walletAccountName = "Status account"
root.communityTokenReceived(name, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName) var symbol = "NON"
root.communityTokenReceived(name, image, communityId, communityName, balance, chainId, txHash, isFirst, tokenType, walletAccountName, symbol)
} }
function onSetSignerStateChanged(communityId, communityName, status, url) { function onSetSignerStateChanged(communityId, communityName, status, url) {

View File

@ -58,6 +58,14 @@ QtObject {
var sendModalPopup) var sendModalPopup)
signal openFinaliseOwnershipPopup(string communityId) signal openFinaliseOwnershipPopup(string communityId)
signal openDeclineOwnershipPopup(string communityId, string communityName) signal openDeclineOwnershipPopup(string communityId, string communityName)
signal openFirstTokenReceivedPopup(string communityId,
string communityName,
string communityLogo,
string tokenSymbol,
string tokenName,
string tokenAmount,
int tokenType,
string tokenImage)
signal openLink(string link) signal openLink(string link)
signal openLinkWithConfirmation(string link, string domain) signal openLinkWithConfirmation(string link, string domain)