Lukáš Tinkl a12a6a4894 feat[UI - Wallet Stability] Create generic/reusable assets listview component
TLDR: later this should form a basic building block for a new
TokenSelector picker component, potentially replacing the current
HoldingSelector* and TokenListView components (support for collectibles
TBD as part of https://github.com/status-im/status-desktop/issues/15121)

- create reusable `TokenSelectorAssetDelegate` and `TokenSelectorView`
- add corresponding SB page, showcasing the flow/integration and the
separation of concerns between the view, adaptor and delegate layers
- add QML testcase for TokenSelectorView
- don't display crypto symbol for token balances per chain tags
- update the stores and SB pages
- add some missing formatter functions to LocaleUtils and CurrenciesStore

Fixes #14716
2024-06-18 23:09:20 +02:00

154 lines
5.7 KiB
QML

import QtQuick 2.15
import SortFilterProxyModel 0.2
import StatusQ 0.1
import utils 1.0
QtObject {
id: root
/* PRIVATE: Modules used to get data from backend */
readonly property var _allTokensModule: !!walletSectionAllTokens ? walletSectionAllTokens : null
readonly property var _networksModule: !!networksModule ? networksModule : null
readonly property double tokenListUpdatedAt: root._allTokensModule.tokenListUpdatedAt
/* This contains the different sources for the tokens list
ex. uniswap list, status tokens list */
readonly property var sourcesOfTokensModel: SortFilterProxyModel {
sourceModel: !!root._allTokensModule ? root._allTokensModule.sourcesOfTokensModel : null
proxyRoles: FastExpressionRole {
function sourceImage(sourceKey) {
return Constants.getSupportedTokenSourceImage(sourceKey)
}
name: "image"
expression: sourceImage(model.key)
expectedRoles: ["key"]
}
filters: AnyOf {
ValueFilter {
roleName: "key"
value: Constants.supportedTokenSources.uniswap
}
ValueFilter {
roleName: "key"
value: Constants.supportedTokenSources.status
}
}
}
/* This list contains the complete list of tokens with separate
entry per token which has a unique [address + network] pair */
readonly property var flatTokensModel: !!root._allTokensModule ? root._allTokensModule.flatTokensModel : null
/* PRIVATE: This model just combines tokens and network information in one */
readonly property LeftJoinModel _joinFlatTokensModel : LeftJoinModel {
leftModel: root.flatTokensModel
rightModel: root._networksModule.flatNetworks
joinRole: "chainId"
}
/* This list contains the complete list of tokens with separate
entry per token which has a unique [address + network] pair including extended information
about the specific network per entry */
readonly property var extendedFlatTokensModel: SortFilterProxyModel {
sourceModel: root._joinFlatTokensModel
proxyRoles: [
JoinRole {
name: "explorerUrl"
roleNames: ["blockExplorerURL", "address"]
separator: "/token/"
},
FastExpressionRole {
function tokenIcon(symbol) {
return Constants.tokenIcon(symbol)
}
name: "image"
expression: tokenIcon(model.symbol)
expectedRoles: ["symbol"]
}
]
}
/* This list contains list of tokens grouped by symbol
EXCEPTION: We may have different entries for the same symbol in case
of symbol clash when minting community tokens, so in case of community tokens
there will be one entry per address + network pair */
// TODO in #12513
readonly property var plainTokensBySymbolModel: !!root._allTokensModule ? root._allTokensModule.tokensBySymbolModel : null
readonly property var assetsBySymbolModel: SortFilterProxyModel {
sourceModel: plainTokensBySymbolModel
proxyRoles: [
FastExpressionRole {
function tokenIcon(symbol) {
return Constants.tokenIcon(symbol)
}
name: "iconSource"
expression: tokenIcon(model.symbol)
expectedRoles: ["symbol"]
},
// TODO: Review if it can be removed
FastExpressionRole {
name: "shortName"
expression: model.symbol
expectedRoles: ["symbol"]
},
FastExpressionRole {
function getCategory(index) {
return 0
}
name: "category"
expression: getCategory(model.communityId)
expectedRoles: ["communityId"]
}
]
}
// Property and methods below are used to apply advanced token management settings to the SendModal
readonly property bool showCommunityAssetsInSend: root._allTokensModule.showCommunityAssetWhenSendingTokens
readonly property bool displayAssetsBelowBalance: root._allTokensModule.displayAssetsBelowBalance
signal displayAssetsBelowBalanceThresholdChanged()
function getDisplayAssetsBelowBalanceThresholdCurrency() {
return root._allTokensModule.displayAssetsBelowBalanceThreshold
}
function getDisplayAssetsBelowBalanceThresholdDisplayAmount() {
const thresholdCurrency = getDisplayAssetsBelowBalanceThresholdCurrency()
return thresholdCurrency.amount / Math.pow(10, thresholdCurrency.displayDecimals)
}
function setDisplayAssetsBelowBalanceThreshold(rawValue) {
// rawValue - raw amount (multiplied by displayDecimals)`
root._allTokensModule.setDisplayAssetsBelowBalanceThreshold(rawValue)
}
function toggleShowCommunityAssetsInSend() {
root._allTokensModule.toggleShowCommunityAssetWhenSendingTokens()
}
function toggleDisplayAssetsBelowBalance() {
root._allTokensModule.toggleDisplayAssetsBelowBalance()
}
readonly property Connections allTokensConnections: Connections {
target: root._allTokensModule
function onDisplayAssetsBelowBalanceThresholdChanged() {
root.displayAssetsBelowBalanceThresholdChanged()
}
}
function updateTokenPreferences(jsonData) {
root._allTokensModule.updateTokenPreferences(jsonData)
}
function getTokenPreferencesJson(jsonData) {
return root._allTokensModule.getTokenPreferencesJson(jsonData)
}
}