feat(@desktop/wallet): display balance in collectibles view
Closes #12940
This commit is contained in:
parent
96c7795153
commit
af84d788ff
|
@ -1,4 +1,5 @@
|
|||
import NimQml, Tables, strutils, strformat
|
||||
import stint
|
||||
|
||||
import backend/collectibles_types as backend
|
||||
|
||||
|
@ -61,7 +62,7 @@ QtObject:
|
|||
of ModelRole.AccountAddress:
|
||||
result = newQVariant(item.address)
|
||||
of ModelRole.Balance:
|
||||
result = newQVariant($item.balance)
|
||||
result = newQVariant(item.balance.toString(10))
|
||||
of ModelRole.TxTimestamp:
|
||||
result = newQVariant(item.txTimestamp)
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 1
|
||||
},
|
||||
{
|
||||
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 2
|
||||
},
|
||||
]
|
||||
|
@ -56,7 +56,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "8",
|
||||
txTimestamp: 3
|
||||
},
|
||||
]
|
||||
|
@ -76,7 +76,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 3
|
||||
},
|
||||
]
|
||||
|
@ -96,7 +96,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 6
|
||||
},
|
||||
]
|
||||
|
@ -116,12 +116,12 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 50
|
||||
},
|
||||
{
|
||||
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 10
|
||||
},
|
||||
]
|
||||
|
@ -141,7 +141,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 16
|
||||
},
|
||||
]
|
||||
|
@ -161,7 +161,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 19
|
||||
},
|
||||
]
|
||||
|
@ -184,7 +184,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "15",
|
||||
txTimestamp: 20
|
||||
},
|
||||
]
|
||||
|
@ -204,7 +204,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "4",
|
||||
txTimestamp: 21
|
||||
},
|
||||
]
|
||||
|
@ -224,7 +224,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 22
|
||||
},
|
||||
]
|
||||
|
@ -244,7 +244,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 23
|
||||
},
|
||||
]
|
||||
|
@ -264,7 +264,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1000",
|
||||
txTimestamp: 25
|
||||
},
|
||||
]
|
||||
|
@ -284,7 +284,7 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "1",
|
||||
txTimestamp: 26
|
||||
},
|
||||
]
|
||||
|
@ -304,9 +304,14 @@ ListModel {
|
|||
ownership: [
|
||||
{
|
||||
accountAddress: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||
balance: 1,
|
||||
balance: "60",
|
||||
txTimestamp: 27
|
||||
},
|
||||
{
|
||||
accountAddress: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||
balance: "70",
|
||||
txTimestamp: 60
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -123,6 +123,16 @@ QtObject {
|
|||
return divident.div(divisor)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod AmountsArithmetic::sum(amount1, amount2)
|
||||
\brief Returns a Big number whose value is the sum of amount1 and amount2.
|
||||
*/
|
||||
function sum(amount1, amount2) {
|
||||
console.assert(amount1 instanceof Big.Big)
|
||||
console.assert(amount2 instanceof Big.Big)
|
||||
return amount1.plus(amount2)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod AmountsArithmetic::cmp(amount1, amount2)
|
||||
\brief Compares two amounts.
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
property int balance: 1
|
||||
|
||||
implicitHeight: 24
|
||||
horizontalPadding: 8
|
||||
|
||||
background: Rectangle {
|
||||
color: Theme.palette.indirectColor4
|
||||
radius: height / 2
|
||||
}
|
||||
|
||||
contentItem: StatusBaseText {
|
||||
color: Theme.palette.directColor1
|
||||
font.pixelSize: 10
|
||||
font.family: Theme.palette.baseFont.name
|
||||
text: {
|
||||
if (root.balance > 99) {
|
||||
return "99+"
|
||||
} else {
|
||||
return root.balance
|
||||
}
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
|
@ -12,3 +12,4 @@ ManageTokensDelegate 1.0 ManageTokensDelegate.qml
|
|||
ManageTokensGroupDelegate 1.0 ManageTokensGroupDelegate.qml
|
||||
InformationTileAssetDetails 1.0 InformationTileAssetDetails.qml
|
||||
StatusNetworkListItemTag 1.0 StatusNetworkListItemTag.qml
|
||||
CollectibleBalanceTag 1.0 CollectibleBalanceTag.qml
|
||||
|
|
|
@ -10,7 +10,6 @@ import StatusQ.Controls 0.1
|
|||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Internal 0.1
|
||||
import StatusQ.Models 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
@ -124,18 +123,10 @@ ColumnLayout {
|
|||
readonly property var nwFilters: root.networkFilters.split(":")
|
||||
readonly property var addrFilters: root.addressFilters.split(":").map((addr) => addr.toLowerCase())
|
||||
|
||||
function containsAnyAddress(ownership, filterList) {
|
||||
for (let i = 0; i < ownership.count; i++) {
|
||||
let accountAddress = ModelUtils.get(ownership, i, "accountAddress").toLowerCase()
|
||||
if (filterList.includes(accountAddress)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getLatestTimestmap(ownership, filterList) {
|
||||
let latest = 0
|
||||
|
||||
if (!!ownership) {
|
||||
for (let i = 0; i < ownership.count; i++) {
|
||||
let accountAddress = ModelUtils.get(ownership, i, "accountAddress").toLowerCase()
|
||||
if (filterList.includes(accountAddress)) {
|
||||
|
@ -143,8 +134,33 @@ ColumnLayout {
|
|||
latest = Math.max(latest, txTimestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return latest
|
||||
}
|
||||
|
||||
function getBalance(ownership, filterList) {
|
||||
// Balance is a Uint256, so we need to use AmountsArithmetic to handle it
|
||||
let balance = AmountsArithmetic.fromNumber(0)
|
||||
|
||||
if (!!ownership) {
|
||||
for (let i = 0; i < ownership.count; i++) {
|
||||
let accountAddress = ModelUtils.get(ownership, i, "accountAddress").toLowerCase()
|
||||
if (filterList.includes(accountAddress)) {
|
||||
let tokenBalanceStr = ModelUtils.get(ownership, i, "balance")+""
|
||||
if (tokenBalanceStr !== "") {
|
||||
let tokenBalance = AmountsArithmetic.fromString(tokenBalanceStr)
|
||||
balance = AmountsArithmetic.sum(balance, tokenBalance)
|
||||
}
|
||||
}
|
||||
}
|
||||
// For simplicity, we limit the result to the maximum int manageable by QML
|
||||
const maxInt = 2147483647
|
||||
if (AmountsArithmetic.cmp(balance, AmountsArithmetic.fromNumber(maxInt)) === 1) {
|
||||
return maxInt
|
||||
}
|
||||
}
|
||||
return AmountsArithmetic.toNumber(balance)
|
||||
}
|
||||
}
|
||||
|
||||
component CustomSFPM: SortFilterProxyModel {
|
||||
|
@ -157,6 +173,11 @@ ColumnLayout {
|
|||
name: "groupName"
|
||||
roleNames: ["collectionName", "communityName"]
|
||||
},
|
||||
FastExpressionRole {
|
||||
name: "balance"
|
||||
expression: d.addrFilters, d.getBalance(model.ownership, d.addrFilters)
|
||||
expectedRoles: ["ownership"]
|
||||
},
|
||||
FastExpressionRole {
|
||||
name: "lastTxTimestamp"
|
||||
expression: d.addrFilters, d.getLatestTimestmap(model.ownership, d.addrFilters)
|
||||
|
@ -166,10 +187,14 @@ ColumnLayout {
|
|||
filters: [
|
||||
FastExpressionFilter {
|
||||
expression: {
|
||||
d.addrFilters
|
||||
return d.nwFilters.includes(model.chainId+"") && d.containsAnyAddress(model.ownership, d.addrFilters)
|
||||
return d.nwFilters.includes(model.chainId+"")
|
||||
}
|
||||
expectedRoles: ["chainId", "ownership"]
|
||||
expectedRoles: ["chainId"]
|
||||
},
|
||||
ValueFilter {
|
||||
roleName: "balance"
|
||||
value: 0
|
||||
inverted: true
|
||||
},
|
||||
FastExpressionFilter {
|
||||
expression: {
|
||||
|
@ -461,6 +486,7 @@ ColumnLayout {
|
|||
communityId: model.communityId ?? ""
|
||||
communityName: model.communityName ?? ""
|
||||
communityImage: model.communityImage ?? ""
|
||||
balance: model.balance ?? 1
|
||||
|
||||
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.symbol, model.tokenType)
|
||||
onRightClicked: {
|
||||
|
|
|
@ -27,6 +27,7 @@ Control {
|
|||
property string communityId: ""
|
||||
property string communityName
|
||||
property string communityImage
|
||||
property int balance: 1
|
||||
|
||||
// Special Owner and TMaster token properties
|
||||
readonly property bool isCommunityCollectible: communityId !== ""
|
||||
|
@ -65,6 +66,13 @@ Control {
|
|||
cursorShape: !root.isLoading ? Qt.PointingHandCursor : undefined
|
||||
}
|
||||
|
||||
property Component balanceTag: Component {
|
||||
CollectibleBalanceTag {
|
||||
visible: !root.isLoading && (root.balance > 1)
|
||||
balance: root.balance
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
|
@ -89,6 +97,13 @@ Control {
|
|||
active: root.isLoading
|
||||
sourceComponent: LoadingComponent {radius: image.radius}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.margins: Style.current.halfPadding
|
||||
sourceComponent: root.balanceTag
|
||||
}
|
||||
}
|
||||
|
||||
PrivilegedTokenArtworkPanel {
|
||||
|
@ -110,6 +125,13 @@ Control {
|
|||
active: root.isLoading
|
||||
sourceComponent: LoadingComponent {radius: image.radius}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.margins: Style.current.halfPadding
|
||||
sourceComponent: root.balanceTag
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
|
Loading…
Reference in New Issue