feat(@desktop/wallet): Collectible Details balance tag

fixes #13809
This commit is contained in:
Khushboo Mehta 2024-03-27 22:49:46 +01:00 committed by Khushboo-dev-cpp
parent 21b884e5ed
commit 2d20a2e1b7
9 changed files with 484 additions and 379 deletions

View File

@ -19,10 +19,23 @@ import utils 1.0
SplitView { SplitView {
id: root id: root
QtObject {
function isValidURL(url) {
return true
}
Component.onCompleted: {
Utils.globalUtilsInst = this
}
Component.onDestruction: {
Utils.globalUtilsInst = {}
}
}
QtObject { QtObject {
id: d id: d
readonly property QtObject collectiblesModel: WalletCollectiblesModel { readonly property QtObject collectiblesModel: ManageCollectiblesModel {
Component.onCompleted: { Component.onCompleted: {
d.refreshCurrentCollectible() d.refreshCurrentCollectible()
} }
@ -34,6 +47,15 @@ SplitView {
} }
readonly property QtObject transactionsModel: WalletTransactionsModel{} readonly property QtObject transactionsModel: WalletTransactionsModel{}
readonly property string addressesSelected: {
let supportedAddresses = ""
for (let i =0; i< accountsRepeater.count; i++) {
if (accountsRepeater.itemAt(i).checked && accountsRepeater.itemAt(i).visible)
supportedAddresses += accountsRepeater.itemAt(i).address + ":"
}
return supportedAddresses
}
} }
SplitView { SplitView {
@ -62,6 +84,7 @@ SplitView {
collectible: d.currentCollectible collectible: d.currentCollectible
isCollectibleLoading: isLoadingCheckbox.checked isCollectibleLoading: isLoadingCheckbox.checked
activityModel: d.transactionsModel activityModel: d.transactionsModel
addressFilters: d.addressesSelected
rootStore: QtObject { rootStore: QtObject {
readonly property string currentCurrency: "EUR" readonly property string currentCurrency: "EUR"
@ -83,6 +106,26 @@ SplitView {
} }
readonly property bool showAllAccounts: true readonly property bool showAllAccounts: true
function getExplorerUrl(networkShortName, contractAddress, tokenId) {
let link = Constants.networkExplorerLinks.etherscan
if (networkShortName === Constants.networkShortChainNames.mainnet) {
return "%1/nft/%2/%3".arg(link).arg(contractAddress).arg(tokenId)
}
else {
return "%1/token/%2?a=%3".arg(link).arg(contractAddress).arg(tokenId)
}
}
function getOpenSeaCollectionUrl(networkShortName, contractAddress) {
let baseLink = root.areTestNetworksEnabled ? Constants.openseaExplorerLinks.testnetLink : Constants.openseaExplorerLinks.mainnetLink
return "%1/assets/%2/%3".arg(baseLink).arg(networkShortName).arg(contractAddress)
}
function getOpenSeaCollectibleUrl(networkShortName, contractAddress, tokenId) {
let baseLink = root.areTestNetworksEnabled ? Constants.openseaExplorerLinks.testnetLink : Constants.openseaExplorerLinks.mainnetLink
return "%1/assets/%2/%3/%4".arg(baseLink).arg(networkShortName).arg(contractAddress).arg(tokenId)
}
} }
communitiesStore: QtObject { communitiesStore: QtObject {
function getCommunityDetailsAsJson(communityId) { function getCommunityDetailsAsJson(communityId) {
@ -130,6 +173,23 @@ SplitView {
text: "isLoading" text: "isLoading"
checked: false checked: false
} }
ColumnLayout {
Layout.fillWidth: true
Text {
text: "select account(s)"
}
Repeater {
id: accountsRepeater
model: WalletAccountsModel {}
delegate: CheckBox {
property string address: model.address
checked: true
visible: index<2
width: parent.width
text: name
}
}
}
} }
} }
} }

View File

@ -117,7 +117,7 @@ Item {
const lvOther = findChild(controlUnderTest, "otherTokensListView") const lvOther = findChild(controlUnderTest, "otherTokensListView")
verify(!!lvOther) verify(!!lvOther)
tryCompare(lvOther, "count", 7) tryCompare(lvOther, "count", 9)
const delegate0 = findChild(lvOther, "manageTokensDelegate-0") const delegate0 = findChild(lvOther, "manageTokensDelegate-0")
verify(!!delegate0) verify(!!delegate0)
const title = delegate0.title const title = delegate0.title
@ -127,7 +127,7 @@ Item {
tryCompare(notificationSpy, "count", 1) tryCompare(notificationSpy, "count", 1)
// verify we now have -1 regular tokens after the "hide" operation // verify we now have -1 regular tokens after the "hide" operation
tryCompare(lvOther, "count", 6) tryCompare(lvOther, "count", 8)
} }
function test_showHideCommunityGroup() { function test_showHideCommunityGroup() {
@ -149,7 +149,7 @@ Item {
verify(!!lvCommunity) verify(!!lvCommunity)
// verify we have 2 community collectible groups // verify we have 2 community collectible groups
tryCompare(lvCommunity, "count", 4) tryCompare(lvCommunity, "count", 6)
tryCompare(notificationSpy, "count", 0) tryCompare(notificationSpy, "count", 0)
triggerDelegateMenuAction(lvCommunity, 0, "miHideTokenGroup", true) triggerDelegateMenuAction(lvCommunity, 0, "miHideTokenGroup", true)
// verify the signal to show the notification toast got fired // verify the signal to show the notification toast got fired
@ -157,7 +157,7 @@ Item {
// verify we have one less group // verify we have one less group
waitForItemPolished(lvCommunity) waitForItemPolished(lvCommunity)
tryCompare(lvCommunity, "count", 3) tryCompare(lvCommunity, "count", 5)
} }
function test_dnd() { function test_dnd() {
@ -200,7 +200,7 @@ Item {
const lvCommunity = findChild(controlUnderTest, "communityTokensListView") const lvCommunity = findChild(controlUnderTest, "communityTokensListView")
verify(!!lvCommunity) verify(!!lvCommunity)
waitForItemPolished(lvCommunity) waitForItemPolished(lvCommunity)
tryCompare(lvCommunity, "count", 4) tryCompare(lvCommunity, "count", 6)
const group0 = findChild(lvCommunity, "manageTokensGroupDelegate-0") const group0 = findChild(lvCommunity, "manageTokensGroupDelegate-0")
const title0 = group0.title const title0 = group0.title
@ -235,7 +235,7 @@ Item {
const lvCommunity = findChild(controlUnderTest, "communityTokensListView") const lvCommunity = findChild(controlUnderTest, "communityTokensListView")
verify(!!lvCommunity) verify(!!lvCommunity)
waitForItemPolished(lvCommunity) waitForItemPolished(lvCommunity)
tryCompare(lvCommunity, "count", 4) tryCompare(lvCommunity, "count", 6)
// get the "Bearz" group at index 1 // get the "Bearz" group at index 1
var bearzGroupTokenDelegate = findChild(lvCommunity, "manageTokensGroupDelegate-1") var bearzGroupTokenDelegate = findChild(lvCommunity, "manageTokensGroupDelegate-1")

View File

@ -22,7 +22,7 @@ ListModel {
userHas: 9, userHas: 9,
name: "Punx not dead!", name: "Punx not dead!",
collectionUid: "", collectionUid: "",
collectionName: "", collectionName: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
communityId: "", communityId: "",
communityName: "", communityName: "",
communityImage: ModelsData.icons.status, communityImage: ModelsData.icons.status,
@ -40,7 +40,26 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 2 txTimestamp: 2
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "Punx not dead is a very rare CryptoKitty. It's a Gen 0 and has a lot of special traits.",
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Blue"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
tokenId: "403"
}, },
{ {
uid: "pp23", uid: "pp23",
@ -61,7 +80,26 @@ ListModel {
balance: "8", balance: "8",
txTimestamp: 3 txTimestamp: 3
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "pepepunk not dead is a very rare CryptoKitty. It's a Gen 0 and has a lot of special traits.",
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
tokenId: "123"
}, },
{ {
uid: "34545656768", uid: "34545656768",
@ -82,7 +120,26 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 3 txTimestamp: 3
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "Furbeard is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
tokenId: "7123"
}, },
{ {
uid: "123456", uid: "123456",
@ -103,7 +160,29 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 6 txTimestamp: 6
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Furbeard is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
tokenId: "403123"
}, },
{ {
uid: "12345645459537432", uid: "12345645459537432",
@ -129,7 +208,26 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 10 txTimestamp: 10
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Big Kitty is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Blue"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
tokenId: "1"
}, },
{ {
uid: "pp21", uid: "pp21",
@ -150,7 +248,18 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 16 txTimestamp: 16
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "pepepunk not dead is a very rare nft. It's a Gen 0 and has a lot of special traits.",
traits: [
{
traitType: "Type",
value: "Special"
}
],
tokenId: "12568"
}, },
{ {
uid: "lp#666a", uid: "lp#666a",
@ -171,7 +280,18 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 19 txTimestamp: 19
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Lonely Panda #666 is a very rare NFT. It's a Gen 0 and has a lot of special traits.likie sjasja sajhash jhasjas",
traits: [
{
traitType: "Type",
value: "Rare"
}
],
tokenId: "1445"
}, },
] ]
@ -194,7 +314,13 @@ ListModel {
balance: "15", balance: "15",
txTimestamp: 20 txTimestamp: 20
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Frenly Pandas is a community for all the fiendly pandas! Welcome onboard and enjoy :)",
traits: [],
tokenId: "4"
}, },
{ {
uid: "691", uid: "691",
@ -214,7 +340,13 @@ ListModel {
balance: "4", balance: "4",
txTimestamp: 21 txTimestamp: 21
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Bearz is a community for all the ferocious Bearz! Welcome onboard and enjoy :)",
traits: [],
tokenId: "3"
}, },
{ {
uid: "8876", uid: "8876",
@ -234,7 +366,13 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 22 txTimestamp: 22
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "Bearz is a community for all the ferocious Bearz! Welcome onboard and enjoy :)",
traits: [],
tokenId: "341"
}, },
{ {
uid: "fp#3195", uid: "fp#3195",
@ -254,7 +392,13 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 23 txTimestamp: 23
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "Frenly Pandas is a community for all the fiendly pandas! Welcome onboard and enjoy :)",
traits: [],
tokenId: "765"
}, },
{ {
uid: "fp#4297", uid: "fp#4297",
@ -274,7 +418,13 @@ ListModel {
balance: "1000", balance: "1000",
txTimestamp: 25 txTimestamp: 25
}, },
] ],
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum,
description: "Frenly Pandas is a community for all the fiendly pandas! Welcome onboard and enjoy :)",
traits: [],
tokenId: "166"
}, },
{ {
uid: "fp#909", uid: "fp#909",
@ -294,7 +444,13 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 26 txTimestamp: 26
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Frenly Pandas is a community for all the fiendly pandas! Welcome onboard and enjoy :)",
traits: [],
tokenId: "1111"
}, },
{ {
uid: "lb#666", uid: "lb#666",
@ -319,7 +475,13 @@ ListModel {
balance: "70", balance: "70",
txTimestamp: 60 txTimestamp: 60
} }
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Bearz is a community for all the ferocious Bearz! Welcome onboard and enjoy",
traits: [],
tokenId: "6"
}, },
{ {
uid: "lb#777", uid: "lb#777",
@ -339,8 +501,114 @@ ListModel {
balance: "1", balance: "1",
txTimestamp: 27 txTimestamp: 27
}, },
] ],
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism,
description: "Lonely Turtle is a community for all of us to talk and communicate! Welcome onboard and enjoy",
traits: [],
tokenId: "7"
}, },
{
uid: "ID-Custom",
chainId: 1,
contractAddress: "0x04",
tokenId: "403",
name: "Custom Collectible",
imageUrl: ModelsData.collectibles.custom,
backgroundColor: "transparent",
description: "This is a custom collectible. It's a unique piece of art.",
collectionUid: "custom",
collectionName: "Custom",
collectionImageUrl: "",
traits: [],
ownership: [
{
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
balance: "1",
txTimestamp: 27
},
],
communityId: "",
networkShortName: "ARB",
networkColor: "blue",
networkIconUrl: ModelsData.networks.arbitrum
},
{
uid: "ID-MissingMetadata",
chainId: 1,
contractAddress: "0x05",
tokenId: "405",
name: "",
imageUrl: "",
backgroundColor: "transparent",
description: "",
collectionUid: "missing",
collectionName: "",
collectionImageUrl: "",
traits: [],
ownership: [
{
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
balance: "1",
txTimestamp: 27
},
],
communityId: "",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-Community1",
chainId: 1,
contractAddress: "0x06",
tokenId: "406",
name: "Community Admin Token",
imageUrl: ModelsData.collectibles.mana,
backgroundColor: "transparent",
description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
collectionUid: "community-uid-1",
collectionName: "",
collectionImageUrl: "",
traits: [],
ownership: [
{
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
balance: "1",
txTimestamp: 27
},
],
communityId: "community-id-1",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-Community-Unknown",
chainId: 1,
contractAddress: "0x07",
tokenId: "407",
name: "Removed community token",
imageUrl: ModelsData.collectibles.mana,
backgroundColor: "transparent",
description: "This is unkown community community token",
collectionUid: "community-uid-unknown",
collectionName: "",
collectionImageUrl: "",
traits: [],
ownership: [
{
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
balance: "1",
txTimestamp: 27
},
],
communityId: "community-id-unknown",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
}
] ]
Component.onCompleted: { Component.onCompleted: {

View File

@ -1,284 +0,0 @@
import QtQuick 2.15
import StatusQ.Core 0.1
import utils 1.0
ListModel {
readonly property var rootData: [
{
uid: "ID-Kitty1",
chainId: 1,
contractAddress: "0x1",
tokenId: "1",
name: "Furbeard",
imageUrl: ModelsData.collectibles.kitty1Big,
backgroundColor: "#f5f5f5",
description: "Furbeard is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
collectionUid: "cryptokitties",
collectionName: "CryptoKitties",
collectionImageUrl: ModelsData.collectibles.cryptoKitties,
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
communityId: "",
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum
},
{
uid: "ID-Kitty2",
chainId: 1,
contractAddress: "0x1",
tokenId: "2",
name: "Magicat",
imageUrl: ModelsData.collectibles.kitty2Big,
backgroundColor: "transparent",
description: "Magicat is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
collectionUid: "cryptokitties",
collectionName: "CryptoKitties",
collectionImageUrl: ModelsData.collectibles.cryptoKitties,
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Blue"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
communityId: "",
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum
},
{
uid: "ID-Kitty3",
chainId: 1,
contractAddress: "0x1",
tokenId: "3",
name: "Happy Meow",
imageUrl: ModelsData.collectibles.kitty3Big,
backgroundColor: "blue",
description: "Happy Meow is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
collectionUid: "cryptokitties",
collectionName: "CryptoKitties",
collectionImageUrl: ModelsData.collectibles.cryptoKitties,
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
communityId: "",
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum
},
{
uid: "ID-Kitty4",
chainId: 1,
contractAddress: "0x1",
tokenId: "4",
name: "Furbeard-2",
imageUrl: ModelsData.collectibles.kitty4Big,
backgroundColor: "red",
description: "Furbeard-2 is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
collectionUid: "cryptokitties",
collectionName: "CryptoKitties",
collectionImageUrl: ModelsData.collectibles.cryptoKitties,
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Green"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
communityId: "",
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum
},
{
uid: "ID-Kitty5",
chainId: 1,
contractAddress: "0x1",
tokenId: "4",
name: "Magicat-3",
imageUrl: ModelsData.collectibles.kitty5Big,
backgroundColor: "yellow",
description: "Magicat-3 is a very rare CryptoKitty. It's a Gen 0 cat and has a lot of special traits.",
collectionUid: "cryptokitties",
collectionName: "CryptoKitties",
collectionImageUrl: ModelsData.collectibles.cryptoKitties,
traits: [
{
traitType: "Fur",
value: "White"
},
{
traitType: "Eyes",
value: "Blue"
},
{
traitType: "Pattern",
value: "Tigerpunk"
}
],
communityId: "",
networkShortName: "ETH",
networkColor: "blue",
networkIconUrl: ModelsData.networks.ethereum
},
{
uid: "ID-Anniversary",
chainId: 1,
contractAddress: "0x2",
tokenId: "1",
name: "Anniversary",
imageUrl: ModelsData.collectibles.anniversary,
backgroundColor: "black",
description: "This is a special collectible to celebrate the anniversary of the platform.",
collectionUid: "anniversary",
collectionName: "Anniversary",
collectionImageUrl: ModelsData.collectibles.anniversary,
traits: [
{
traitType: "Type",
value: "Special"
}
],
communityId: "",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-SuperRare",
chainId: 1,
contractAddress: "0x3",
tokenId: "101",
name: "SuperRare",
imageUrl: ModelsData.collectibles.superRare,
backgroundColor: "transparent",
description: "This is a very rare collectible. It's a unique piece of art.",
collectionUid: "super-rare",
collectionName: "SuperRare",
collectionImageUrl: ModelsData.collectibles.doodles,
traits: [
{
traitType: "Type",
value: "Rare"
}
],
communityId: "",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-Custom",
chainId: 1,
contractAddress: "0x04",
tokenId: "403",
name: "Custom Collectible",
imageUrl: ModelsData.collectibles.custom,
backgroundColor: "transparent",
description: "This is a custom collectible. It's a unique piece of art.",
collectionUid: "custom",
collectionName: "Custom",
collectionImageUrl: "",
traits: [],
communityId: "",
networkShortName: "ARB",
networkColor: "blue",
networkIconUrl: ModelsData.networks.arbitrum
},
{
uid: "ID-MissingMetadata",
chainId: 1,
contractAddress: "0x05",
tokenId: "405",
name: "",
imageUrl: "",
backgroundColor: "transparent",
description: "",
collectionUid: "missing",
collectionName: "",
collectionImageUrl: "",
traits: [],
communityId: "",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-Community1",
chainId: 1,
contractAddress: "0x06",
tokenId: "406",
name: "Community Admin Token",
imageUrl: ModelsData.collectibles.mana,
backgroundColor: "transparent",
description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
collectionUid: "community-uid-1",
collectionName: "",
collectionImageUrl: "",
traits: [],
communityId: "community-id-1",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
},
{
uid: "ID-Community-Unknown",
chainId: 1,
contractAddress: "0x07",
tokenId: "407",
name: "Removed community token",
imageUrl: ModelsData.collectibles.mana,
backgroundColor: "transparent",
description: "This is unkown community community token",
collectionUid: "community-uid-unknown",
collectionName: "",
collectionImageUrl: "",
traits: [],
communityId: "community-id-unknown",
networkShortName: "OPT",
networkColor: "red",
networkIconUrl: ModelsData.networks.optimism
}
]
Component.onCompleted: append(rootData)
}

View File

@ -16,7 +16,6 @@ TokenHoldersModel 1.0 TokenHoldersModel.qml
UsersModel 1.0 UsersModel.qml UsersModel 1.0 UsersModel.qml
WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml
WalletAccountsModel 1.0 WalletAccountsModel.qml WalletAccountsModel 1.0 WalletAccountsModel.qml
WalletCollectiblesModel 1.0 WalletCollectiblesModel.qml
WalletKeyPairModel 1.0 WalletKeyPairModel.qml WalletKeyPairModel 1.0 WalletKeyPairModel.qml
WalletNestedCollectiblesModel 1.0 WalletNestedCollectiblesModel.qml WalletNestedCollectiblesModel 1.0 WalletNestedCollectiblesModel.qml
WalletTransactionsModel 1.0 WalletTransactionsModel.qml WalletTransactionsModel 1.0 WalletTransactionsModel.qml

View File

@ -28,7 +28,7 @@ QtObject {
property var fromNetworksModel: NetworksModel.sendFromNetworks property var fromNetworksModel: NetworksModel.sendFromNetworks
property var toNetworksModel: NetworksModel.sendToNetworks property var toNetworksModel: NetworksModel.sendToNetworks
property var selectedSenderAccount: senderAccounts.get(0) property var selectedSenderAccount: senderAccounts.get(0)
readonly property QtObject collectiblesModel: WalletCollectiblesModel {} readonly property QtObject collectiblesModel: ManageCollectiblesModel {}
readonly property QtObject nestedCollectiblesModel: WalletNestedCollectiblesModel {} readonly property QtObject nestedCollectiblesModel: WalletNestedCollectiblesModel {}
readonly property QtObject walletSectionSendInst: QtObject { readonly property QtObject walletSectionSendInst: QtObject {

View File

@ -15,7 +15,7 @@ Control {
horizontalPadding: 8 horizontalPadding: 8
background: Rectangle { background: Rectangle {
color: Theme.palette.indirectColor4 color: Theme.palette.indirectColor2
radius: height / 2 radius: height / 2
} }

View File

@ -232,6 +232,7 @@ RightTabBaseView {
collectible: RootStore.collectiblesStore.detailedCollectible collectible: RootStore.collectiblesStore.detailedCollectible
isCollectibleLoading: RootStore.collectiblesStore.isDetailedCollectibleLoading isCollectibleLoading: RootStore.collectiblesStore.isDetailedCollectibleLoading
activityModel: d.detailedCollectibleActivityController.model activityModel: d.detailedCollectibleActivityController.model
addressFilters: RootStore.addressFilters
rootStore: SharedStores.RootStore rootStore: SharedStores.RootStore
walletRootStore: RootStore walletRootStore: RootStore
communitiesStore: root.communitiesStore communitiesStore: root.communitiesStore

View File

@ -1,6 +1,8 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import SortFilterProxyModel 0.2
import StatusQ 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
@ -28,6 +30,7 @@ Item {
required property var collectible required property var collectible
property var activityModel property var activityModel
property bool isCollectibleLoading property bool isCollectibleLoading
required property string addressFilters
// Community related token props: // Community related token props:
readonly property bool isCommunityCollectible: !!collectible ? collectible.communityId !== "" : false readonly property bool isCommunityCollectible: !!collectible ? collectible.communityId !== "" : false
@ -38,9 +41,34 @@ Item {
QtObject { QtObject {
id: d id: d
readonly property string collectibleLink: root.walletRootStore.getOpenSeaCollectibleUrl(collectible.networkShortName, collectible.contractAddress, collectible.tokenId) readonly property string collectibleLink: !!collectible ? root.walletRootStore.getOpenSeaCollectibleUrl(collectible.networkShortName, collectible.contractAddress, collectible.tokenId): ""
readonly property string collectionLink: root.walletRootStore.getOpenSeaCollectionUrl(collectible.networkShortName, collectible.contractAddress) readonly property string collectionLink: !!collectible ? root.walletRootStore.getOpenSeaCollectionUrl(collectible.networkShortName, collectible.contractAddress): ""
readonly property string blockExplorerLink: root.walletRootStore.getExplorerUrl(collectible.networkShortName, collectible.contractAddress, collectible.tokenId) readonly property string blockExplorerLink: !!collectible ? root.walletRootStore.getExplorerUrl(collectible.networkShortName, collectible.contractAddress, collectible.tokenId): ""
readonly property var addrFilters: root.addressFilters.split(":").map((addr) => addr.toLowerCase())
readonly property int imageStackSpacing: 4
property Component balanceTag: Component {
CollectibleBalanceTag {
balance: d.balanceAggregator.value
}
}
property SortFilterProxyModel filteredBalances: SortFilterProxyModel {
sourceModel: !!collectible ? collectible.ownership : null
filters: [
FastExpressionFilter {
expression: {
d.addrFilters
return d.addrFilters.includes(model.accountAddress.toLowerCase())
}
expectedRoles: ["accountAddress"]
}
]
}
property SumAggregator balanceAggregator: SumAggregator {
model: d.filteredBalances
roleName: "balance"
}
} }
CollectibleDetailsHeader { CollectibleDetailsHeader {
@ -48,16 +76,16 @@ Item {
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
collectibleName: !!collectible.name ? collectible.name : qsTr("Unknown") collectibleName: !!collectible && !!collectible.name ? collectible.name : qsTr("Unknown")
collectibleId: "#" + collectible.tokenId collectibleId: !!collectible ? "#" + collectible.tokenId : ""
communityName: !!communityDetails ? communityDetails.name : "" communityName: !!communityDetails ? communityDetails.name : ""
communityId: collectible.communityId communityId: !!collectible ? collectible.communityId : ""
collectionName: collectible.collectionName collectionName: !!collectible ? collectible.collectionName : ""
communityImage: !!communityDetails ? communityDetails.image: "" communityImage: !!communityDetails ? communityDetails.image : ""
networkShortName: collectible.networkShortName networkShortName: !!collectible ? collectible.networkShortName : ""
networkColor: collectible.networkColor networkColor: !!collectible ?collectible.networkColor : ""
networkIconURL: collectible.networkIconUrl networkIconURL: !!collectible ? collectible.networkIconUrl : ""
networkExplorerName: root.walletRootStore.getExplorerNameForNetwork(collectible.networkShortName) networkExplorerName: !!collectible ? root.walletRootStore.getExplorerNameForNetwork(collectible.networkShortName): ""
collectibleLinkEnabled: Utils.getUrlStatus(d.collectibleLink) collectibleLinkEnabled: Utils.getUrlStatus(d.collectibleLink)
collectionLinkEnabled: (!!communityDetails && communityDetails.name) || Utils.getUrlStatus(d.collectionLink) collectionLinkEnabled: (!!communityDetails && communityDetails.name) || Utils.getUrlStatus(d.collectionLink)
explorerLinkEnabled: Utils.getUrlStatus(d.blockExplorerLink) explorerLinkEnabled: Utils.getUrlStatus(d.blockExplorerLink)
@ -78,7 +106,6 @@ Item {
anchors.top: collectibleHeader.bottom anchors.top: collectibleHeader.bottom
anchors.topMargin: 25 anchors.topMargin: 25
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 52
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -87,62 +114,41 @@ Item {
Row { Row {
id: collectibleImageDetails id: collectibleImageDetails
readonly property real visibleImageHeight: (collectibleimage.visible ? collectibleimage.height : privilegedCollectibleImage.height) readonly property real visibleImageHeight: artwork.height
readonly property real visibleImageWidth: (collectibleimage.visible ? collectibleimage.width : privilegedCollectibleImage.width) readonly property real visibleImageWidth: artwork.width
height: collectibleImageDetails.visibleImageHeight height: collectibleImageDetails.visibleImageHeight
width: parent.width width: parent.width
spacing: 24 spacing: 24
// Special artwork representation for community `Owner and Master Token` token types: ColumnLayout {
PrivilegedTokenArtworkPanel { id: artwork
id: privilegedCollectibleImage spacing: 0
Repeater {
visible: root.isCommunityCollectible && (root.isOwnerTokenType || root.isTMasterTokenType) id: repeater
size: PrivilegedTokenArtworkPanel.Size.Large model: Math.min(3, d.balanceAggregator.value)
artwork: root.collectible.imageUrl Item {
color: !!root.collectible && !!root.communityDetails ? root.communityDetails.color : "transparent" Layout.preferredWidth: childrenRect.width
isOwner: root.isOwnerTokenType Layout.preferredHeight: childrenRect.height
} Layout.leftMargin: index * d.imageStackSpacing
Layout.topMargin: index === 0 ? 0 : -Layout.preferredHeight + d.imageStackSpacing
StatusRoundedMedia { opacity: index === 0 ? 1: 0.4/index
id: collectibleimage // so that the first item remains on top in the stack
z: -index
readonly property bool isEmpty: !mediaUrl.toString() && !fallbackImageUrl.toString() Loader {
visible: !privilegedCollectibleImage.visible property int modelIndex: index
width: 248 anchors.top: parent.top
height: width anchors.left: parent.left
radius: Style.current.radius sourceComponent: root.isCommunityCollectible && (root.isOwnerTokenType || root.isTMasterTokenType) ? privilegedCollectibleImage: collectibleimage
color: isError || isEmpty ? Theme.palette.baseColor5 : collectible.backgroundColor active: root.visible
border.color: Theme.palette.directColor8 }
border.width: 1 Loader {
mediaUrl: collectible.mediaUrl ?? "" anchors.top: parent.top
mediaType: collectible.mediaType ?? "" anchors.left: parent.left
fallbackImageUrl: collectible.imageUrl anchors.margins: Style.current.padding
sourceComponent: d.balanceTag
Column { // only show balance tag on top of the first image in stack
anchors.centerIn: parent active: index === 0 && d.balanceAggregator.value > 1 && root.visible
visible: collectibleimage.isError || collectibleimage.isEmpty
spacing: 10
StatusIcon {
anchors.horizontalCenter: parent.horizontalCenter
icon: "frowny"
opacity: 0.1
color: Theme.palette.directColor1
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Qt.AlignHCenter
color: Theme.palette.directColor6
text: {
if (collectibleimage.isError && collectibleimage.componentMediaType === StatusRoundedMedia.MediaType.Unkown) {
return qsTr("Unsupported\nfile format")
}
if (!collectible.description && !collectible.name) {
return qsTr("Info can't\nbe fetched")
}
return qsTr("Failed\nto load")
} }
} }
} }
@ -159,7 +165,8 @@ Item {
width: parent.width width: parent.width
height: 24 height: 24
text: root.isCommunityCollectible && !!communityDetails ? qsTr("Minted by %1").arg(root.communityDetails.name): root.collectible.collectionName text: root.isCommunityCollectible && !!communityDetails ? qsTr("Minted by %1").arg(root.communityDetails.name):
!!collectible ? collectible.collectionName: ""
color: Theme.palette.directColor1 color: Theme.palette.directColor1
font.pixelSize: 17 font.pixelSize: 17
lineHeight: 24 lineHeight: 24
@ -174,7 +181,7 @@ Item {
height: collectibleImageDetails.height - collectibleName.height - parent.spacing height: collectibleImageDetails.height - collectibleName.height - parent.spacing
clip: true clip: true
text: collectible.description text: !!collectible ? collectible.description : ""
textFormat: Text.MarkdownText textFormat: Text.MarkdownText
color: Theme.palette.directColor4 color: Theme.palette.directColor4
font.pixelSize: 15 font.pixelSize: 15
@ -190,7 +197,7 @@ Item {
id: collectiblesDetailsTab id: collectiblesDetailsTab
width: parent.width width: parent.width
topPadding: Style.current.xlPadding topPadding: Style.current.xlPadding
visible: collectible.traits.count > 0 visible: !!collectible && collectible.traits.count > 0
StatusTabButton { StatusTabButton {
leftPadding: 0 leftPadding: 0
@ -228,7 +235,7 @@ Item {
width: scrollView.availableWidth width: scrollView.availableWidth
spacing: 10 spacing: 10
Repeater { Repeater {
model: collectible.traits model: !!collectible ? collectible.traits: null
InformationTile { InformationTile {
maxWidth: parent.width maxWidth: parent.width
primaryText: model.traitType primaryText: model.traitType
@ -240,7 +247,7 @@ Item {
Component { Component {
id: activityView id: activityView
StatusListView { StatusListView {
width: scrollView.availableWidth width: scrollView.availableWidth
height: scrollView.availableHeight height: scrollView.availableHeight
model: root.activityModel model: root.activityModel
@ -269,4 +276,58 @@ Item {
} }
} }
} }
Component {
id: privilegedCollectibleImage
// Special artwork representation for community `Owner and Master Token` token types:
PrivilegedTokenArtworkPanel {
size: PrivilegedTokenArtworkPanel.Size.Large
artwork: collectible.imageUrl ?? ""
color: !!root.collectible && !!root.communityDetails ? root.communityDetails.color : "transparent"
isOwner: root.isOwnerTokenType
}
}
Component {
id: collectibleimage
StatusRoundedMedia {
id: collectibleImage
readonly property bool isEmpty: !mediaUrl.toString() && !fallbackImageUrl.toString()
width: 248
height: width
radius: Style.current.radius
color: isError || isEmpty ? Theme.palette.baseColor5 : collectible.backgroundColor
border.color: Theme.palette.directColor8
border.width: 1
mediaUrl: collectible.mediaUrl ?? ""
mediaType: modelIndex === 0 && !!collectible ? collectible.mediaType : ""
fallbackImageUrl: collectible.imageUrl
Column {
anchors.centerIn: parent
visible: collectibleImage.isError || collectibleImage.isEmpty
spacing: 10
StatusIcon {
anchors.horizontalCenter: parent.horizontalCenter
icon: "frowny"
opacity: 0.1
color: Theme.palette.directColor1
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Qt.AlignHCenter
color: Theme.palette.directColor6
text: {
if (collectibleImage.isError && collectibleImage.componentMediaType === StatusRoundedMedia.MediaType.Unkown) {
return qsTr("Unsupported\nfile format")
}
if (!collectible.description && !collectible.name) {
return qsTr("Info can't\nbe fetched")
}
return qsTr("Failed\nto load")
}
}
}
}
}
} }