feat(MintAssets): Update minted tokens view with assets

- Added assets list UI.
- Added shape rectangle for empty lists.
- Added filter by asset / by collectible
- Updated storybook accordingly.
- Added flow to open token view depending on type

Closes #10625
This commit is contained in:
Noelia 2023-05-25 16:45:46 +02:00 committed by Noelia
parent b557274dff
commit 86a0e8b9ec
8 changed files with 197 additions and 26 deletions

View File

@ -28,7 +28,7 @@ SplitView {
CommunityMintTokensSettingsPanel {
anchors.fill: parent
anchors.topMargin: 50
tokensModel: editorModelChecked.checked ? emptyModel : MintedCollectiblesModel.mintedCollectibleModel
tokensModel: editorModelChecked.checked ? emptyModel : MintedTokensModel.mintedTokensModel
layer1Networks: NetworksModel.layer1Networks
layer2Networks: NetworksModel.layer2Networks
testNetworks: NetworksModel.testNetworks
@ -71,9 +71,9 @@ SplitView {
checked: true
onCheckedChanged:{
if(checked)
MintedCollectiblesModel.changeAllMintingStates(1/*In progress*/)
MintedTokensModel.changeAllMintingStates(1/*In progress*/)
else
MintedCollectiblesModel.changeAllMintingStates(2/*Deployed*/)
MintedTokensModel.changeAllMintingStates(2/*Deployed*/)
}
}

View File

@ -27,7 +27,7 @@ SplitView {
CommunityMintedTokensView {
anchors.fill: parent
anchors.margins: 50
model: MintedCollectiblesModel.mintedCollectibleModel
model: MintedTokensModel.mintedTokensModel
onItemClicked: logs.logEvent("CommunityMintedTokensView::itemClicked")
}
}
@ -39,6 +39,25 @@ SplitView {
SplitView.preferredHeight: 150
logsView.logText: logs.logText
RowLayout {
RadioButton {
text: "Assets and collectibles"
checked: true
onCheckedChanged: if(checked) MintedTokensModel.buildMintedTokensModel(true, true)
}
RadioButton {
text: "Only assets"
onCheckedChanged: if(checked) MintedTokensModel.buildMintedTokensModel(true, false)
}
RadioButton {
text: "Only collectibles"
onCheckedChanged: if(checked) MintedTokensModel.buildMintedTokensModel(false, true)
}
}
}
}
}

View File

@ -34,7 +34,7 @@ SplitView {
enabledNetworks: NetworksModel.enabledNetworks
allNetworks: enabledNetworks
accounts: WalletAccountsModel {}
tokensModel: MintedCollectiblesModel.mintedCollectibleModel
tokensModel: MintedTokensModel.mintedTokensModel
onPreviewClicked: logs.logEvent("CommunityNewTokenView::previewClicked")
}

View File

@ -14,11 +14,26 @@ QtObject {
}
}
readonly property ListModel mintedCollectibleModel: ListModel {
id: model
function buildMintedTokensModel(isAssets, isCollectibles) {
model.clear()
if(isAssets) {
for(var i = 0; i < mintedAssetsModel.count; i++)
model.append(mintedAssetsModel.get(i))
}
if(isCollectibles) {
for(var j = 0; j < collectiblesModel.count; j++)
model.append(collectiblesModel.get(j))
}
}
readonly property ListModel mintedCollectiblesModel: ListModel {
id: collectiblesModel
Component.onCompleted: append([
{
tokenType: 2,
name: "SuperRare artwork",
image: ModelsData.banners.superRare,
deployState: 0,
@ -35,6 +50,7 @@ QtObject {
accountName: "Status Account"
},
{
tokenType: 2,
name: "Kitty artwork",
image: ModelsData.collectibles.kitty1Big,
deployState: 2,
@ -51,6 +67,7 @@ QtObject {
accountName: "Status New Account"
},
{
tokenType: 2,
name: "More artwork",
image: ModelsData.banners.status,
deployState: 1,
@ -67,6 +84,7 @@ QtObject {
accountName: "Other Account"
},
{
tokenType: 2,
name: "Crypto Punks artwork",
image: ModelsData.banners.cryptPunks,
deployState: 2,
@ -84,4 +102,49 @@ QtObject {
}
])
}
readonly property ListModel mintedAssetsModel: ListModel {
id: assetsModel
Component.onCompleted: append([
{
tokenType: 1,
name: "Unisocks",
image: ModelsData.assets.socks,
deployState: 2,
symbol: "SOCKS",
description: "Socks description",
supply: 14,
remainingTokens: 2,
infiniteSupply: false,
decimals: 2,
chainId: 2,
chainName: "Optimism",
chainIcon: ModelsData.networks.optimism,
accountName: "Status SNT Account"
},
{
tokenType: 1,
name: "Dai",
image: ModelsData.assets.dai,
deployState: 0,
symbol: "DAI",
description: "Desc",
supply: 1,
remainingTokens: 1,
infiniteSupply: true,
decimals: 1,
chainId: 1,
chainName: "Testnet",
chainIcon: ModelsData.networks.testnet,
accountName: "Status Account"
}
])
}
readonly property ListModel mintedTokensModel: ListModel {
id: model
Component.onCompleted: buildMintedTokensModel(true, true)
}
}

View File

@ -9,7 +9,7 @@ TokenHoldersModel 1.0 TokenHoldersModel.qml
UsersModel 1.0 UsersModel.qml
WalletAccountsModel 1.0 WalletAccountsModel.qml
WalletAssetsModel 1.0 WalletAssetsModel.qml
singleton MintedCollectiblesModel 1.0 MintedCollectiblesModel.qml
singleton MintedTokensModel 1.0 MintedTokensModel.qml
singleton ModelsData 1.0 ModelsData.qml
singleton NetworksModel 1.0 NetworksModel.qml
singleton PermissionsModel 1.0 PermissionsModel.qml

View File

@ -96,7 +96,7 @@ SettingsPageLayout {
readonly property string initialViewState: "WELCOME_OR_LIST_TOKENS"
readonly property string newTokenViewState: "NEW_TOKEN"
readonly property string previewTokenViewState: "PREVIEW_TOKEN"
readonly property string collectibleViewState: "VIEW_COLLECTIBLE"
readonly property string tokenViewState: "VIEW_TOKEN"
readonly property string welcomePageTitle: qsTr("Tokens")
readonly property string newCollectiblePageTitle: qsTr("Mint collectible")
@ -166,7 +166,7 @@ SettingsPageLayout {
PropertyChanges {target: root; headerWidth: 0}
},
State {
name: d.collectibleViewState
name: d.tokenViewState
PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; headerButtonVisible: false}
PropertyChanges {target: root; headerWidth: 0}
@ -226,7 +226,7 @@ SettingsPageLayout {
Binding {
target: root
property: "title"
value: optionsTab.currentItem == collectiblesTab ? d.newCollectiblePageTitle : d.newAssetPageTitle
value: optionsTab.currentItem === collectiblesTab ? d.newCollectiblePageTitle : d.newAssetPageTitle
}
}
@ -494,8 +494,8 @@ SettingsPageLayout {
d.chainName = chainName
d.accountName = accountName
//d.tokenKey = key // TODO: Backend key role
stackManager.push(d.collectibleViewState,
collectibleView,
stackManager.push(d.tokenViewState,
tokenView,
{
preview: false,
index
@ -506,7 +506,7 @@ SettingsPageLayout {
}
Component {
id: collectibleView
id: tokenView
CommunityTokenView {
id: view
@ -573,6 +573,7 @@ SettingsPageLayout {
delegate: QtObject {
component Bind: Binding { target: view }
readonly property list<Binding> bindings: [
Bind { property: "isAssetView"; value: model.tokenType === Constants.TokenType.ERC20 },
Bind { property: "deployState"; value: model.deployState },
Bind { property: "remotelyDestructState"; value: model.remotelyDestructState },
Bind { property: "burnState"; value: model.burnState },
@ -588,7 +589,8 @@ SettingsPageLayout {
Bind { property: "chainName"; value: model.chainName },
Bind { property: "chainIcon"; value: model.chainIcon },
Bind { property: "accountName"; value: model.accountName },
Bind { property: "tokenOwnersModel"; value: model.tokenOwnersModel }
Bind { property: "tokenOwnersModel"; value: model.tokenOwnersModel },
Bind { property: "assetDecimals"; value: model.decimals }
]
}
}

View File

@ -5,7 +5,9 @@ import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import SortFilterProxyModel 0.2
import utils 1.0
import shared.controls 1.0
import AppLayouts.Wallet.views.collectibles 1.0
@ -25,7 +27,9 @@ StatusScrollView {
QtObject {
id: d
function getSubtitle(deployState, remainingTokens, supply) {
readonly property int delegateAssetsHeight: 64
function getSubtitle(deployState, remainingTokens, supply, isCollectible) {
if(deployState === Constants.ContractTransactionStatus.Failed) {
return qsTr("Minting failed")
}
@ -39,7 +43,7 @@ StatusScrollView {
remainingTokens = 0
if(supply === 0)
supply = "∞"
return qsTr("%1 / %2 remaining").arg(remainingTokens).arg(supply)
return isCollectible ? qsTr("%1 / %2 remaining").arg(remainingTokens).arg(supply) : ""
}
}
@ -49,35 +53,111 @@ StatusScrollView {
id: mainLayout
width: root.viewWidth
spacing: Style.current.padding
spacing: Style.current.halfPadding
StatusBaseText {
Layout.leftMargin: Style.current.padding
text: qsTr("Assets")
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.baseColor1
}
StatusListView {
id: assetsList
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
visible: count > 0
model: SortFilterProxyModel {
sourceModel: root.model
filters: ValueFilter {
roleName: "tokenType"
value: Constants.TokenType.ERC20
}
}
delegate: StatusListItem {
height: 64
width: mainLayout.width
title: model.name
subTitle: model.symbol
asset.name: model.image ? model.image : ""
asset.isImage: true
components: [
StatusBaseText {
anchors.verticalCenter: parent.verticalCenter
text: d.getSubtitle(model.deployState, model.remainingTokens, model.supply, false)
color: (model.deployState === Constants.ContractTransactionStatus.Failed) ? Theme.palette.dangerColor1 : Theme.palette.baseColor1
font.pixelSize: 13
},
StatusIcon {
anchors.verticalCenter: parent.verticalCenter
icon: "next"
color: Theme.palette.baseColor1
}
]
onClicked: root.itemClicked(model.index, model.chainId, model.chainName, model.accountName, model.address) // TODO: Replace to model.key when role exists in backend
}
}
// Empty placeholder when no assets; dashed rounded rectangle
ShapeRectangle {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: parent.width - 4 // The rectangular path is rendered outside
Layout.preferredHeight: 44
visible: assetsList.count === 0
text: qsTr("You currently have no minted assets")
}
StatusBaseText {
Layout.leftMargin: Style.current.padding
Layout.topMargin: Style.current.halfPadding
text: qsTr("Collectibles")
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.baseColor1
}
StatusGridView {
id: gridView
id: collectiblesGrid
Layout.fillWidth: true
Layout.preferredHeight: 500 // TODO
model: root.model
Layout.preferredHeight: childrenRect.height
visible: count > 0
model: SortFilterProxyModel {
sourceModel: root.model
filters: ValueFilter {
roleName: "tokenType"
value: Constants.TokenType.ERC721
}
}
cellHeight: 229
cellWidth: 176
leftMargin: 16
delegate: CollectibleView {
height: gridView.cellHeight
width: gridView.cellWidth
height: collectiblesGrid.cellHeight
width: collectiblesGrid.cellWidth
title: model.name ? model.name : "..."
subTitle: d.getSubtitle(model.deployState, model.remainingTokens, model.supply)
subTitle: d.getSubtitle(model.deployState, model.remainingTokens, model.supply, true)
subTitleColor: (model.deployState === Constants.ContractTransactionStatus.Failed) ? Theme.palette.dangerColor1 : Theme.palette.baseColor1
fallbackImageUrl: model.image ? model.image : ""
backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent" // TODO BACKEND
backgroundColor: "transparent"
isLoading: false
navigationIconVisible: true
onClicked: root.itemClicked(model.index, model.chainId, model.contractUniqueKey, model.chainName, model.accountName, model.address)
}
}
// Empty placeholder when no collectibles; dashed rounded rectangle
ShapeRectangle {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: parent.width - 4 // The rectangular path is rendered outside
Layout.preferredHeight: 44
visible: collectiblesGrid.count == 0
text: qsTr("You currently have no minted collectibles")
}
}
}

View File

@ -910,6 +910,13 @@ QtObject {
Dismissed = 4
}
enum TokenType {
Unknown = 0,
ERC20 = 1,
ERC721 = 2
}
readonly property QtObject walletSection: QtObject {
readonly property string cancelledMessage: "cancelled"
}