fix(@desktop/wallet): Prepare send modal to display community assets

fixes #12378
This commit is contained in:
Khushboo Mehta 2024-01-30 14:15:58 +01:00 committed by Khushboo-dev-cpp
parent 6f25499380
commit 7dcc704d29
20 changed files with 420 additions and 235 deletions

View File

@ -31,8 +31,9 @@ SplitView {
submodelRoleName: "balances" submodelRoleName: "balances"
delegateModel: SortFilterProxyModel { delegateModel: SortFilterProxyModel {
sourceModel: submodel sourceModel: submodel
filters: ExpressionFilter { filters: FastExpressionFilter {
expression: txStore.selectedSenderAccount.address === account expression: txStore.selectedSenderAccount.address === model.account
expectedRoles: ["account"]
} }
} }
} }
@ -40,6 +41,9 @@ SplitView {
TransactionStore { TransactionStore {
id: txStore id: txStore
walletAssetStore: root.walletAssetStore walletAssetStore: root.walletAssetStore
showCommunityAssetsInSend: showCommunityAssetsCheckBox.checked
balanceThresholdEnabled: balanceThresholdCheckbox.checked
balanceThresholdAmount: Number(balanceThresholdValue.text)
} }
QtObject { QtObject {
@ -274,6 +278,32 @@ SplitView {
loader.item.open() loader.item.open()
} }
} }
CheckBox {
id: showCommunityAssetsCheckBox
text: "Show community assets when sending tokens"
checked: true
}
CheckBox {
id: balanceThresholdCheckbox
text: "Turn on balance threshold"
checked: false
}
Rectangle {
border.width: 1
Layout.preferredWidth: 100
Layout.preferredHeight: 50
color: "lightgrey"
TextInput {
id: balanceThresholdValue
anchors.fill: parent
enabled: balanceThresholdCheckbox.checked
text: "0.10"
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
}
} }
} }
} }

View File

@ -10,13 +10,25 @@ import AppLayouts.Wallet.stores 1.0
import StatusQ.Core.Utils 0.1 import StatusQ.Core.Utils 0.1
import shared.stores 1.0
import shared.stores.send 1.0
SplitView { SplitView {
id: root
orientation: Qt.Vertical orientation: Qt.Vertical
readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore {
assetsWithFilteredBalances: groupedAccountsAssetsModel assetsWithFilteredBalances: groupedAccountsAssetsModel
} }
TransactionStore {
id: txStore
walletAssetStore: root.walletAssetStore
}
readonly property CurrenciesStore currencyStore: CurrenciesStore {}
Item { Item {
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.fillHeight: true SplitView.fillHeight: true
@ -31,26 +43,16 @@ SplitView {
width: 400 width: 400
assets: walletAssetStore.groupedAccountAssetsModel assets: txStore.processedAssetsModel
collectibles: WalletNestedCollectiblesModel {} collectibles: WalletNestedCollectiblesModel {}
networksModel: NetworksModel.allNetworks networksModel: NetworksModel.allNetworks
getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ formatCurrentCurrencyAmount: function(balance){
let bigIntBalance = AmountsArithmetic.fromString(balance) return currencyStore.formatCurrencyAmount(balance, "USD")
let balance123 = AmountsArithmetic.toNumber(bigIntBalance, decimals)
return ({
amount: balance123,
symbol: symbol,
displayDecimals: 2,
stripTrailingZeroes: false
})
} }
getCurrentCurrencyAmount: function(balance){ formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
return ({ let bigIntBalance = AmountsArithmetic.fromString(balance)
amount: balance, let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals)
symbol: "USD", return currencyStore.formatCurrencyAmount(decimalBalance, symbol)
displayDecimals: 2,
stripTrailingZeroes: false
})
} }
} }
} }

View File

@ -104,7 +104,7 @@ ListModel {
addressPerChain: [ addressPerChain: [
{ chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271e0f"} { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271e0f"}
], ],
decimals: 18, decimals: 0,
type: 1, type: 1,
communityId: "ddls", communityId: "ddls",
description: "", description: "",
@ -130,7 +130,7 @@ ListModel {
addressPerChain: [ addressPerChain: [
{ chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271p0f"} { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271p0f"}
], ],
decimals: 18, decimals: 0,
type: 1, type: 1,
communityId: "sox", communityId: "sox",
description: "", description: "",
@ -156,7 +156,7 @@ ListModel {
addressPerChain: [ addressPerChain: [
{ chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271d0f"} { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271d0f"}
], ],
decimals: 18, decimals: 0,
type: 1, type: 1,
communityId: "ddls", communityId: "ddls",
description: "", description: "",
@ -182,7 +182,7 @@ ListModel {
addressPerChain: [ addressPerChain: [
{ chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271a0f"} { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271a0f"}
], ],
decimals: 18, decimals: 0,
type: 1, type: 1,
communityId: "ast", communityId: "ast",
description: "", description: "",

View File

@ -1,5 +1,7 @@
import QtQuick 2.15 import QtQuick 2.15
import StatusQ.Core 0.1
QtObject { QtObject {
id: root id: root
@ -7,7 +9,11 @@ QtObject {
property string currentCurrencySymbol: "$" property string currentCurrencySymbol: "$"
function formatCurrencyAmount(amount, symbol, options = null, locale = null) { function formatCurrencyAmount(amount, symbol, options = null, locale = null) {
return amount if (isNaN(amount)) {
return "N/A"
}
var currencyAmount = getCurrencyAmount(amount, symbol)
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options, locale)
} }
function getFiatValue(balance, cryptoSymbol, fiatSymbol) { function getFiatValue(balance, cryptoSymbol, fiatSymbol) {

View File

@ -90,7 +90,7 @@ QtObject {
function getHolding(holdingId, holdingType) { function getHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) { if (holdingType === Constants.TokenType.ERC20) {
return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721) { } else if (holdingType === Constants.TokenType.ERC721) {
return getCollectible(holdingId) return getCollectible(holdingId)
} else { } else {
@ -100,7 +100,7 @@ QtObject {
function getSelectorHolding(holdingId, holdingType) { function getSelectorHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) { if (holdingType === Constants.TokenType.ERC20) {
return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721) { } else if (holdingType === Constants.TokenType.ERC721) {
return getSelectorCollectible(holdingId) return getSelectorCollectible(holdingId)
} else { } else {
@ -255,14 +255,96 @@ QtObject {
return SQUtils.ModelUtils.getByKey(NetworksModel.allNetworks, "chainId", chainId, "chainName") return SQUtils.ModelUtils.getByKey(NetworksModel.allNetworks, "chainId", chainId, "chainName")
} }
function getCurrencyAmountFromBigInt(balance, symbol, decimals) { function formatCurrencyAmountFromBigInt(balance, symbol, decimals) {
let bigIntBalance = SQUtils.AmountsArithmetic.fromString(balance) let bigIntBalance = SQUtils.AmountsArithmetic.fromString(balance)
let balance123 = SQUtils.AmountsArithmetic.toNumber(bigIntBalance, decimals) let decimalBalance = SQUtils.AmountsArithmetic.toNumber(bigIntBalance, decimals)
return currencyStore.getCurrencyAmount(balance123, symbol) return currencyStore.formatCurrencyAmount(decimalBalance, symbol)
} }
function getCurrentCurrencyAmount(balance) { // Property and methods below are used to apply advanced token management settings to the SendModal
return currencyStore.getCurrencyAmount(balance, currencyStore.currentCurrency) property bool showCommunityAssetsInSend: true
property bool balanceThresholdEnabled: true
property real balanceThresholdAmount
// Property set from TokenLIstView and HoldingSelector to search token by name, symbol or contract address
property string assetSearchString
// Model prepared to provide filtered and sorted assets as per the advanced Settings in token management
property var processedAssetsModel: SortFilterProxyModel {
sourceModel: walletAssetStore.groupedAccountAssetsModel
proxyRoles: [
FastExpressionRole {
name: "isCommunityAsset"
expression: !!model.communityId
expectedRoles: ["communityId"]
},
FastExpressionRole {
name: "currentBalance"
expression: __getTotalBalance(model.balances, model.decimals, model.symbol, root.selectedSenderAccount)
expectedRoles: ["balances", "decimals", "symbol"]
},
FastExpressionRole {
name: "currentCurrencyBalance"
expression: {
if (!!model.marketDetails) {
return model.currentBalance * model.marketDetails.currencyPrice.amount
}
return 0
}
expectedRoles: ["marketDetails", "currentBalance"]
}
]
filters: [
FastExpressionFilter {
function search(symbol, name, addressPerChain, searchString) {
return (
symbol.startsWith(searchString.toUpperCase()) ||
name.toUpperCase().startsWith(searchString.toUpperCase()) || __searchAddressInList(addressPerChain, searchString)
)
}
expression: search(symbol, name, addressPerChain, root.assetSearchString)
expectedRoles: ["symbol", "name", "addressPerChain"]
},
ValueFilter {
roleName: "isCommunityAsset"
value: false
enabled: !showCommunityAssetsInSend
},
FastExpressionFilter {
expression: {
if (model.isCommunityAsset)
return true
return model.currentCurrencyBalance > balanceThresholdAmount
}
expectedRoles: ["isCommunityAsset", "currentCurrencyBalance"]
enabled: balanceThresholdEnabled
}
]
sorters: RoleSorter {
roleName: "isCommunityAsset"
}
} }
/* Internal function to search token address */
function __searchAddressInList(addressPerChain, searchString) {
let addressFound = false
let tokenAddresses = SQUtils.ModelUtils.modelToFlatArray(addressPerChain, "address")
for (let i =0; i< tokenAddresses.length; i++){
if(tokenAddresses[i].toUpperCase().startsWith(searchString.toUpperCase())) {
addressFound = true
break;
}
}
return addressFound
}
/* Internal function to calculate total balance */
function __getTotalBalance(balances, decimals, symbol) {
let totalBalance = 0
for(let i=0; i<balances.count; i++) {
let balancePerAddressPerChain = SQUtils.ModelUtils.get(balances, i)
totalBalance+=SQUtils.AmountsArithmetic.toNumber(balancePerAddressPerChain.balance, decimals)
}
return totalBalance
}
} }

View File

@ -15,6 +15,7 @@ Item {
property alias count: comboBox.count property alias count: comboBox.count
property alias delegate: comboBox.delegate property alias delegate: comboBox.delegate
property alias contentItem: comboBox.contentItem property alias contentItem: comboBox.contentItem
property alias comboBoxListViewSection: listView.section
property alias currentIndex: comboBox.currentIndex property alias currentIndex: comboBox.currentIndex
property alias currentValue: comboBox.currentValue property alias currentValue: comboBox.currentValue

View File

@ -98,4 +98,9 @@ QtObject {
} }
] ]
} }
// 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 balanceThresholdEnabled: root._allTokensModule.displayAssetsBelowBalance
readonly property real balanceThresholdAmount: root._allTokensModule.displayAssetsBelowBalanceThreshold
} }

View File

@ -72,8 +72,8 @@ Item {
primaryText: token && token.name ? token.name : Constants.dummyText primaryText: token && token.name ? token.name : Constants.dummyText
secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(root.currencyStore.getCurrencyAmount(token.currentBalance, token.symbol)) : Constants.dummyText secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(root.currencyStore.getCurrencyAmount(token.currentBalance, token.symbol)) : Constants.dummyText
tertiaryText: { tertiaryText: {
let totalCurrencyBalance = token && token.currentCurrencyBalance ? token.currentCurrencyBalance : 0 let totalCurrencyBalance = token && token.currentCurrencyBalance && token.symbol ? token.currentCurrencyBalance : 0
return LocaleUtils.currencyAmountToLocaleString(root.currencyStore.getCurrentCurrencyAmount(totalCurrencyBalance)) return currencyStore.formatCurrencyAmount(totalCurrencyBalance, token.symbol)
} }
decimals: token && token.decimals ? token.decimals : 4 decimals: token && token.decimals ? token.decimals : 4
balances: token && token.balances ? token.balances: null balances: token && token.balances ? token.balances: null

View File

@ -73,8 +73,9 @@ Item {
readonly property WalletStore.TokensStore tokensStore: WalletStore.RootStore.tokensStore readonly property WalletStore.TokensStore tokensStore: WalletStore.RootStore.tokensStore
readonly property WalletStore.WalletAssetsStore walletAssetsStore: WalletStore.RootStore.walletAssetsStore readonly property WalletStore.WalletAssetsStore walletAssetsStore: WalletStore.RootStore.walletAssetsStore
readonly property CurrenciesStore currencyStore: CurrenciesStore{} readonly property CurrenciesStore currencyStore: CurrenciesStore{}
readonly property TransactionStore transactionStore: TransactionStore{ readonly property TransactionStore transactionStore: TransactionStore {
walletAssetStore: appMain.walletAssetsStore walletAssetStore: appMain.walletAssetsStore
tokensStore: appMain.tokensStore
} }
// set from main.qml // set from main.qml

View File

@ -0,0 +1,42 @@
import QtQuick 2.13
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups.Dialog 0.1
import utils 1.0
ColumnLayout {
signal openInfoPopup()
spacing: 0
StatusDialogDivider {
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
Layout.bottomMargin: Style.current.halfPadding
}
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: Style.current.padding
Layout.rightMargin: Style.current.smallPadding
Layout.bottomMargin: 4
StatusBaseText {
text: qsTr("Community assets")
color: Theme.palette.baseColor1
}
Item { Layout.fillWidth: true }
StatusFlatButton {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
icon.name: "info"
textColor: Theme.palette.baseColor1
horizontalPadding: 0
verticalPadding: 0
onClicked: openInfoPopup()
}
}
}

View File

@ -44,4 +44,5 @@ TransactionDataTile 1.0 TransactionDataTile.qml
TransactionDelegate 1.0 TransactionDelegate.qml TransactionDelegate 1.0 TransactionDelegate.qml
TransactionDetailsHeader.qml 1.0 TransactionDetailsHeader.qml TransactionDetailsHeader.qml 1.0 TransactionDetailsHeader.qml
MockedKeycardReaderStateSelector 1.0 MockedKeycardReaderStateSelector.qml MockedKeycardReaderStateSelector 1.0 MockedKeycardReaderStateSelector.qml
MockedKeycardStateSelector 1.0 MockedKeycardStateSelector.qml MockedKeycardStateSelector 1.0 MockedKeycardStateSelector.qml
AssetsSectionDelegate 1.0 AssetsSectionDelegate.qml

View File

@ -0,0 +1,15 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Popups.Dialog 0.1
StatusDialog {
destroyOnClose: true
title: qsTr("What are community assets?")
standardButtons: Dialog.Ok
width: 520
contentItem: StatusBaseText {
wrapMode: Text.Wrap
text: qsTr("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.")
}
}

View File

@ -26,3 +26,4 @@ DeleteMessageConfirmationPopup 1.0 DeleteMessageConfirmationPopup.qml
UserAgreementPopup 1.0 UserAgreementPopup.qml UserAgreementPopup 1.0 UserAgreementPopup.qml
AlertPopup 1.0 AlertPopup.qml AlertPopup 1.0 AlertPopup.qml
ConfirmExternalLinkPopup 1.0 ConfirmExternalLinkPopup.qml ConfirmExternalLinkPopup 1.0 ConfirmExternalLinkPopup.qml
CommunityAssetsInfoPopup 1.0 CommunityAssetsInfoPopup.qml

View File

@ -77,9 +77,8 @@ StatusDialog {
(popup.bestRoutes && popup.bestRoutes.count === 0 && (popup.bestRoutes && popup.bestRoutes.count === 0 &&
!!amountToSendInput.input.text && recipientLoader.ready && !popup.isLoading) ? !!amountToSendInput.input.text && recipientLoader.ready && !popup.isLoading) ?
Constants.NoRoute : Constants.NoError Constants.NoRoute : Constants.NoError
readonly property double totalSelectedHoldingBalance: isSelectedHoldingValidAsset ? !d.selectedHolding.communityId ? selectedHoldingAggregator.value/(10 ** d.selectedHolding.decimals): selectedHoldingAggregator.value: 0 readonly property double maxFiatBalance: isSelectedHoldingValidAsset ? selectedHolding.currentCurrencyBalance : 0
readonly property double maxFiatBalance: isSelectedHoldingValidAsset && selectedHolding.marketDetails ? totalSelectedHoldingBalance * selectedHolding.marketDetails.currencyPrice.amount : 0 readonly property double maxCryptoBalance: isSelectedHoldingValidAsset ? selectedHolding.currentBalance : 0
readonly property double maxCryptoBalance: isSelectedHoldingValidAsset ? totalSelectedHoldingBalance : 0
readonly property double maxInputBalance: amountToSendInput.inputIsFiat ? maxFiatBalance : maxCryptoBalance readonly property double maxInputBalance: amountToSendInput.inputIsFiat ? maxFiatBalance : maxCryptoBalance
readonly property string inputSymbol: amountToSendInput.inputIsFiat ? currencyStore.currentCurrency : store.selectedAssetSymbol readonly property string inputSymbol: amountToSendInput.inputIsFiat ? currencyStore.currentCurrency : store.selectedAssetSymbol
readonly property bool errorMode: popup.isLoading || !recipientLoader.ready ? false : errorType !== Constants.NoError || networkSelector.errorMode || !amountToSendInput.inputNumberValid readonly property bool errorMode: popup.isLoading || !recipientLoader.ready ? false : errorType !== Constants.NoError || networkSelector.errorMode || !amountToSendInput.inputNumberValid
@ -149,21 +148,6 @@ StatusDialog {
} }
} }
SumAggregator {
id: selectedHoldingAggregator
model: SortFilterProxyModel {
sourceModel: d.isSelectedHoldingValidAsset ? d.selectedHolding.balances: d.isHoveredHoldingValidAsset && !!d.hoveredHolding.symbol ? d.hoveredHolding.balances: null
filters: FastExpressionFilter {
expression: {
store.selectedSenderAccount
return store.selectedSenderAccount.address === model.account
}
expectedRoles: ["account"]
}
}
roleName: "balance"
}
width: 556 width: 556
padding: 0 padding: 0
@ -282,7 +266,7 @@ StatusDialog {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
selectedSenderAccount: store.selectedSenderAccount.address selectedSenderAccount: store.selectedSenderAccount.address
assetsModel: popup.store.walletAssetStore.groupedAccountAssetsModel assetsModel: popup.store.processedAssetsModel
collectiblesModel: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null collectiblesModel: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null
networksModel: popup.store.allNetworksModel networksModel: popup.store.allNetworksModel
currentCurrencySymbol: d.currencyStore.currentCurrencySymbol currentCurrencySymbol: d.currencyStore.currentCurrencySymbol
@ -291,11 +275,12 @@ StatusDialog {
onItemSelected: { onItemSelected: {
d.setSelectedHoldingId(holdingId, holdingType) d.setSelectedHoldingId(holdingId, holdingType)
} }
getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ onSearchTextChanged: popup.store.assetSearchString = searchText
return store.getCurrencyAmountFromBigInt(balance, symbol, decimals) formatCurrentCurrencyAmount: function(balance){
return popup.store.currencyStore.formatCurrencyAmount(balance, popup.store.currencyStore.currentCurrency)
} }
getCurrentCurrencyAmount: function(balance){ formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
return store.getCurrentCurrencyAmount(balance) return popup.store.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
} }
} }
@ -306,8 +291,7 @@ StatusDialog {
visible: d.isSelectedHoldingValidAsset || d.isHoveredHoldingValidAsset && !d.isERC721Transfer visible: d.isSelectedHoldingValidAsset || d.isHoveredHoldingValidAsset && !d.isERC721Transfer
title: { title: {
if(d.isHoveredHoldingValidAsset && !!d.hoveredHolding.symbol) { if(d.isHoveredHoldingValidAsset && !!d.hoveredHolding.symbol) {
let totalAmount = !d.hoveredHolding.communityId ? selectedHoldingAggregator.value/(10 ** d.hoveredHolding.decimals): selectedHoldingAggregator.value const input = amountToSendInput.inputIsFiat ? d.hoveredHolding.currentCurrencyBalance : d.hoveredHolding.currentBalance
const input = amountToSendInput.inputIsFiat ? totalAmount * d.hoveredHolding.marketDetails.currencyPrice.amount : totalAmount
const max = d.prepareForMaxSend(input, d.hoveredHolding.symbol) const max = d.prepareForMaxSend(input, d.hoveredHolding.symbol)
if (max <= 0) if (max <= 0)
return qsTr("No balances active") return qsTr("No balances active")
@ -424,7 +408,7 @@ StatusDialog {
visible: !d.selectedHolding visible: !d.selectedHolding
selectedSenderAccount: store.selectedSenderAccount.address selectedSenderAccount: store.selectedSenderAccount.address
assets: popup.store.walletAssetStore.groupedAccountAssetsModel assets: popup.store.processedAssetsModel
collectibles: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null collectibles: popup.preSelectedAccount ? popup.nestedCollectiblesModel : null
networksModel: popup.store.allNetworksModel networksModel: popup.store.allNetworksModel
onlyAssets: holdingSelector.onlyAssets onlyAssets: holdingSelector.onlyAssets
@ -438,11 +422,12 @@ StatusDialog {
d.setHoveredHoldingId("", Constants.TokenType.Unknown) d.setHoveredHoldingId("", Constants.TokenType.Unknown)
} }
} }
getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ onAssetSearchStringChanged: store.assetSearchString = assetSearchString
return store.getCurrencyAmountFromBigInt(balance, symbol, decimals) formatCurrentCurrencyAmount: function(balance){
return popup.store.currencyStore.formatCurrencyAmount(balance, popup.store.currencyStore.currentCurrency)
} }
getCurrentCurrencyAmount: function(balance){ formatCurrencyAmountFromBigInt: function(balance, symbol, decimals) {
return store.getCurrentCurrencyAmount(balance) return popup.store.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
} }
} }

View File

@ -14,8 +14,8 @@ StatusListItem {
signal tokenSelected(var selectedToken) signal tokenSelected(var selectedToken)
signal tokenHovered(var selectedToken, bool hovered) signal tokenHovered(var selectedToken, bool hovered)
property var getCurrencyAmountFromBigInt: function(balance, symbol, decimals){} property var formatCurrentCurrencyAmount: function(balance){}
property var getCurrentCurrencyAmount: function(balance){} property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
property var balancesModel property var balancesModel
property string selectedSenderAccount property string selectedSenderAccount
@ -29,25 +29,6 @@ StatusListItem {
function selectToken() { function selectToken() {
root.tokenSelected({name, symbol, balances, decimals}) root.tokenSelected({name, symbol, balances, decimals})
} }
readonly property string balanceRoleName: "balance"
property string roleName: balanceRoleName
}
property var filteredBalances : SortFilterProxyModel {
sourceModel: root.balancesModel
filters: FastExpressionFilter {
expression: {
root.selectedSenderAccount
return root.selectedSenderAccount === model.account
}
expectedRoles: ["account"]
}
onCountChanged: {
// Added because the SumAggregator is not evaluated after the filters are applied
d.roleName = ""
d.roleName = d.balanceRoleName
}
} }
Connections { Connections {
@ -64,11 +45,8 @@ StatusListItem {
statusListItemTitleAside.width: statusListItemTitleArea.width - statusListItemTitle.width statusListItemTitleAside.width: statusListItemTitleArea.width - statusListItemTitle.width
statusListItemTitleAside.elide: Text.ElideRight statusListItemTitleAside.elide: Text.ElideRight
label: { label: {
if (!!model && !!model.marketDetails && !!model.marketDetails.currencyPrice) { let balance = !!model && !!model.currentCurrencyBalance ? model.currentCurrencyBalance : 0
let totalCurrencyBalance = aggregator.value/(10 ** decimals) * model.marketDetails.currencyPrice.amount return root.formatCurrentCurrencyAmount(balance)
return LocaleUtils.currencyAmountToLocaleString(root.getCurrentCurrencyAmount(totalCurrencyBalance))
}
return LocaleUtils.currencyAmountToLocaleString(root.getCurrentCurrencyAmount(0))
} }
asset.name: symbol ? Style.png("tokens/" + symbol) : "" asset.name: symbol ? Style.png("tokens/" + symbol) : ""
asset.isImage: true asset.isImage: true
@ -77,13 +55,13 @@ StatusListItem {
statusListItemLabel.anchors.verticalCenterOffset: -12 statusListItemLabel.anchors.verticalCenterOffset: -12
statusListItemLabel.color: Theme.palette.directColor1 statusListItemLabel.color: Theme.palette.directColor1
statusListItemInlineTagsSlot.spacing: 0 statusListItemInlineTagsSlot.spacing: 0
tagsModel: filteredBalances tagsModel: root.balancesModel
tagsDelegate: expandedItem tagsDelegate: expandedItem
statusListItemInlineTagsSlot.children: Row { statusListItemInlineTagsSlot.children: Row {
id: compactRow id: compactRow
spacing: -6 spacing: -6
Repeater { Repeater {
model: filteredBalances model: root.balancesModel
delegate: compactItem delegate: compactItem
} }
} }
@ -93,12 +71,6 @@ StatusListItem {
onClicked: d.selectToken() onClicked: d.selectToken()
SumAggregator {
id: aggregator
model: filteredBalances
roleName: d.roleName
}
Component { Component {
id: compactItem id: compactItem
StatusRoundedImage { StatusRoundedImage {
@ -114,7 +86,7 @@ StatusListItem {
StatusListItemTag { StatusListItemTag {
height: 16 height: 16
leftPadding: 0 leftPadding: 0
title: LocaleUtils.currencyAmountToLocaleString(root.getCurrencyAmountFromBigInt(balance, symbol, decimals)) title: root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
titleText.font.pixelSize: 12 titleText.font.pixelSize: 12
closeButtonVisible: false closeButtonVisible: false
bgColor: "transparent" bgColor: "transparent"

View File

@ -34,6 +34,7 @@ Item {
property alias comboBoxControl: comboBox.control property alias comboBoxControl: comboBox.control
property alias comboBoxDelegate: comboBox.delegate property alias comboBoxDelegate: comboBox.delegate
property alias comboBoxListViewSection: comboBox.comboBoxListViewSection
property var comboBoxPopupHeader property var comboBoxPopupHeader
property int contentIconSize: 21 property int contentIconSize: 21

View File

@ -4,6 +4,7 @@ import QtQuick 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import shared.controls 1.0 import shared.controls 1.0
import shared.popups 1.0
import utils 1.0 import utils 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
@ -12,7 +13,6 @@ import StatusQ 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
import "../controls" import "../controls"
@ -25,12 +25,13 @@ Item {
property var networksModel property var networksModel
property string currentCurrencySymbol property string currentCurrencySymbol
property bool onlyAssets: true property bool onlyAssets: true
property string searchText
implicitWidth: holdingItemSelector.implicitWidth implicitWidth: holdingItemSelector.implicitWidth
implicitHeight: holdingItemSelector.implicitHeight implicitHeight: holdingItemSelector.implicitHeight
property var getCurrencyAmountFromBigInt: function(balance, symbol, decimals){} property var formatCurrentCurrencyAmount: function(balance){}
property var getCurrentCurrencyAmount: function(balance){} property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
signal itemHovered(string holdingId, var holdingType) signal itemHovered(string holdingId, var holdingType)
signal itemSelected(string holdingId, var holdingType) signal itemSelected(string holdingId, var holdingType)
@ -78,7 +79,6 @@ Item {
property var currentHoldingType: Constants.TokenType.Unknown property var currentHoldingType: Constants.TokenType.Unknown
property string searchText
readonly property string uppercaseSearchText: searchText.toUpperCase() readonly property string uppercaseSearchText: searchText.toUpperCase()
property var assetTextFn: function (asset) { property var assetTextFn: function (asset) {
@ -89,25 +89,6 @@ Item {
return !!asset && asset.symbol ? Style.png("tokens/%1".arg(asset.symbol)) : "" return !!asset && asset.symbol ? Style.png("tokens/%1".arg(asset.symbol)) : ""
} }
property var assetComboBoxModel: SortFilterProxyModel {
sourceModel: root.assetsModel
filters: [
FastExpressionFilter {
function search(symbol, name, addressPerChain, searchString) {
return (
searchString === "" ||
symbol.startsWith(searchString) ||
name.toUpperCase().startsWith(searchString) ||
d.searchAddressInList(addressPerChain, searchString)
)
}
expression: search(symbol, name, addressPerChain, d.uppercaseSearchText)
expectedRoles: ["symbol", "name", "addressPerChain"]
}
]
}
property var collectibleTextFn: function (item) { property var collectibleTextFn: function (item) {
if (!!item) { if (!!item) {
return !!item.collectionName ? item.collectionName + ": " + item.name : item.name return !!item.collectionName ? item.collectionName + ": " + item.name : item.name
@ -168,18 +149,6 @@ Item {
readonly property int collectibleContentIconSize: 28 readonly property int collectibleContentIconSize: 28
readonly property int assetContentTextSize: 28 readonly property int assetContentTextSize: 28
readonly property int collectibleContentTextSize: 15 readonly property int collectibleContentTextSize: 15
function searchAddressInList(addressPerChain, searchString) {
let addressFound = false
let tokenAddresses = SQUtils.ModelUtils.modelToFlatArray(addressPerChain, "address")
for (let i =0; i< tokenAddresses.length; i++){
if(tokenAddresses[i].toUpperCase().startsWith(searchString.toUpperCase())) {
addressFound = true
break;
}
}
return addressFound
}
} }
HoldingItemSelector { HoldingItemSelector {
@ -222,15 +191,39 @@ Item {
comboBoxPopupHeader: headerComponent comboBoxPopupHeader: headerComponent
itemTextFn: d.isCurrentBrowsingTypeAsset ? d.assetTextFn : d.collectibleTextFn itemTextFn: d.isCurrentBrowsingTypeAsset ? d.assetTextFn : d.collectibleTextFn
itemIconSourceFn: d.isCurrentBrowsingTypeAsset ? d.assetIconSourceFn : d.collectibleIconSourceFn itemIconSourceFn: d.isCurrentBrowsingTypeAsset ? d.assetIconSourceFn : d.collectibleIconSourceFn
comboBoxModel: d.isCurrentBrowsingTypeAsset ? d.assetComboBoxModel : d.collectibleComboBoxModel comboBoxModel: d.isCurrentBrowsingTypeAsset ? root.assetsModel : d.collectibleComboBoxModel
contentIconSize: d.isAsset(d.currentHoldingType) ? d.assetContentIconSize : d.collectibleContentIconSize contentIconSize: d.isAsset(d.currentHoldingType) ? d.assetContentIconSize : d.collectibleContentIconSize
contentTextSize: d.isAsset(d.currentHoldingType) ? d.assetContentTextSize : d.collectibleContentTextSize contentTextSize: d.isAsset(d.currentHoldingType) ? d.assetContentTextSize : d.collectibleContentTextSize
comboBoxListViewSection.property: "isCommunityAsset"
comboBoxListViewSection.delegate: Loader {
width: ListView.view.width
required property string section
sourceComponent: d.isCurrentBrowsingTypeAsset && section === "true" ? sectionDelegate : null
}
comboBoxControl.popup.onClosed: comboBoxControl.popup.contentItem.headerItem.clear()
}
Component {
id: sectionDelegate
AssetsSectionDelegate {
width: parent.width
onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
}
}
Component {
id: communityInfoPopupCmp
CommunityAssetsInfoPopup {}
} }
Component { Component {
id: headerComponent id: headerComponent
ColumnLayout { ColumnLayout {
function clear() {
searchInput.input.edit.clear()
}
width: holdingItemSelector.comboBoxControl.popup.width width: holdingItemSelector.comboBoxControl.popup.width
Layout.topMargin: d.headerTopMargin Layout.topMargin: d.headerTopMargin
spacing: -1 // Used to overlap rectangles from row components spacing: -1 // Used to overlap rectangles from row components
@ -318,11 +311,11 @@ Item {
root.itemSelected(selectedToken.symbol, Constants.TokenType.ERC20) root.itemSelected(selectedToken.symbol, Constants.TokenType.ERC20)
holdingItemSelector.comboBoxControl.popup.close() holdingItemSelector.comboBoxControl.popup.close()
} }
getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ formatCurrentCurrencyAmount: function(balance){
return root.getCurrencyAmountFromBigInt(balance, symbol, decimals) return root.formatCurrentCurrencyAmount(balance)
} }
getCurrentCurrencyAmount: function(balance){ formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
return root.getCurrentCurrencyAmount(balance) return root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
} }
} }
} }

View File

@ -8,10 +8,11 @@ import StatusQ.Controls 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
import utils 1.0 import utils 1.0
import shared.controls 1.0
import shared.popups 1.0
import "../controls" import "../controls"
Item { Item {
@ -21,25 +22,28 @@ Item {
property var assets: null property var assets: null
property var collectibles: null property var collectibles: null
property var networksModel property var networksModel
property string assetSearchString
signal tokenSelected(string symbol, var holdingType) signal tokenSelected(string symbol, var holdingType)
signal tokenHovered(string symbol, var holdingType, bool hovered) signal tokenHovered(string symbol, var holdingType, bool hovered)
property bool onlyAssets: false property bool onlyAssets: false
property int browsingHoldingType: Constants.TokenType.ERC20 property int browsingHoldingType: Constants.TokenType.ERC20
property var getCurrencyAmountFromBigInt: function(balance, symbol, decimals){} property var formatCurrentCurrencyAmount: function(balance){}
property var getCurrentCurrencyAmount: function(balance){} property var formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){}
onVisibleChanged: { onVisibleChanged: {
if(!visible && root.collectibles) if(!visible) {
root.collectibles.currentCollectionUid = "" if (root.collectibles)
root.collectibles.currentCollectionUid = ""
tokenList.headerItem.input.edit.clear()
}
} }
QtObject { QtObject {
id: d id: d
property string assetSearchString
readonly property var updateAssetSearchText: Backpressure.debounce(root, 1000, function(inputText) { readonly property var updateAssetSearchText: Backpressure.debounce(root, 1000, function(inputText) {
d.assetSearchString = inputText assetSearchString = inputText
}) })
property string collectibleSearchString property string collectibleSearchString
@ -71,18 +75,6 @@ Item {
rightModel: d.renamedAllNetworksModel rightModel: d.renamedAllNetworksModel
joinRole: "chainId" joinRole: "chainId"
} }
function searchAddressInList(addressPerChain, searchString) {
let addressFound = false
let tokenAddresses = SQUtils.ModelUtils.modelToFlatArray(addressPerChain, "address")
for (let i =0; i< tokenAddresses.length; i++){
if(tokenAddresses[i].toUpperCase().startsWith(searchString.toUpperCase())) {
addressFound = true
break;
}
}
return addressFound
}
} }
implicitWidth: contentLayout.implicitWidth implicitWidth: contentLayout.implicitWidth
@ -144,30 +136,34 @@ Item {
height: tokenList.contentHeight height: tokenList.contentHeight
header: root.browsingHoldingType === Constants.TokenType.ERC20 ? tokenHeader : collectibleHeader header: root.browsingHoldingType === Constants.TokenType.ERC20 ? tokenHeader : collectibleHeader
model: root.browsingHoldingType === Constants.TokenType.ERC20 ? tokensModel : collectiblesModel model: root.browsingHoldingType === Constants.TokenType.ERC20 ? root.assets : collectiblesModel
delegate: root.browsingHoldingType === Constants.TokenType.ERC20 ? tokenDelegate : collectiblesDelegate delegate: root.browsingHoldingType === Constants.TokenType.ERC20 ? tokenDelegate : collectiblesDelegate
section {
property: "isCommunityAsset"
delegate: Loader {
width: ListView.view.width
required property string section
sourceComponent: root.browsingHoldingType === Constants.TokenType.ERC20 && section === "true" ? sectionDelegate : null
}
}
}
Component {
id: sectionDelegate
AssetsSectionDelegate {
width: parent.width
onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
}
}
Component {
id: communityInfoPopupCmp
CommunityAssetsInfoPopup {}
} }
} }
} }
} }
property var tokensModel: SortFilterProxyModel {
sourceModel: root.assets
filters: [
FastExpressionFilter {
function search(symbol, name, addressPerChain, searchString) {
tokenList.positionViewAtBeginning()
return (
symbol.startsWith(searchString.toUpperCase()) ||
name.toUpperCase().startsWith(searchString.toUpperCase()) || d.searchAddressInList(addressPerChain, searchString)
)
}
expression: search(symbol, name, addressPerChain, d.assetSearchString)
expectedRoles: ["symbol", "name", "addressPerChain"]
}
]
}
property var collectiblesModel: SortFilterProxyModel { property var collectiblesModel: SortFilterProxyModel {
sourceModel: d.collectiblesNetworksJointModel sourceModel: d.collectiblesNetworksJointModel
filters: [ filters: [
@ -195,11 +191,11 @@ Item {
} }
onTokenSelected: root.tokenSelected(symbol, Constants.TokenType.ERC20) onTokenSelected: root.tokenSelected(symbol, Constants.TokenType.ERC20)
onTokenHovered: root.tokenHovered(symbol, Constants.TokenType.ERC20, hovered) onTokenHovered: root.tokenHovered(symbol, Constants.TokenType.ERC20, hovered)
getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ formatCurrentCurrencyAmount: function(balance){
return root.getCurrencyAmountFromBigInt(balance, symbol, decimals) return root.formatCurrentCurrencyAmount(balance)
} }
getCurrentCurrencyAmount: function(balance){ formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){
return root.getCurrentCurrencyAmount(balance) return root.formatCurrencyAmountFromBigInt(balance, symbol, decimals)
} }
} }
} }

View File

@ -6,6 +6,7 @@ import shared.stores 1.0
import utils 1.0 import utils 1.0
import StatusQ 0.1
import StatusQ.Core.Utils 0.1 import StatusQ.Core.Utils 0.1
import AppLayouts.Wallet.stores 1.0 import AppLayouts.Wallet.stores 1.0
@ -15,6 +16,7 @@ QtObject {
property CurrenciesStore currencyStore: CurrenciesStore {} property CurrenciesStore currencyStore: CurrenciesStore {}
property WalletAssetsStore walletAssetStore property WalletAssetsStore walletAssetStore
property TokensStore tokensStore
property var mainModuleInst: mainModule property var mainModuleInst: mainModule
property var walletSectionSendInst: walletSectionSend property var walletSectionSendInst: walletSectionSend
@ -105,15 +107,9 @@ QtObject {
function getAsset(assetsList, symbol) { function getAsset(assetsList, symbol) {
for(var i=0; i< assetsList.rowCount();i++) { for(var i=0; i< assetsList.rowCount();i++) {
let asset = ModelUtils.get(assetsList, i) let asset = assetsList.get(i)
if(symbol === asset.symbol) { if(symbol === asset.symbol) {
return { return asset
name: asset.name,
symbol: asset.symbol,
totalBalance: asset.totalBalance,
balances: asset.balances,
decimals: asset.decimals
}
} }
} }
return {} return {}
@ -137,7 +133,7 @@ QtObject {
function getHolding(holdingId, holdingType) { function getHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) { if (holdingType === Constants.TokenType.ERC20) {
return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721) { } else if (holdingType === Constants.TokenType.ERC721) {
return getCollectible(holdingId) return getCollectible(holdingId)
} else { } else {
@ -147,7 +143,7 @@ QtObject {
function getSelectorHolding(holdingId, holdingType) { function getSelectorHolding(holdingId, holdingType) {
if (holdingType === Constants.TokenType.ERC20) { if (holdingType === Constants.TokenType.ERC20) {
return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) return getAsset(processedAssetsModel, holdingId)
} else if (holdingType === Constants.TokenType.ERC721) { } else if (holdingType === Constants.TokenType.ERC721) {
return getSelectorCollectible(holdingId) return getSelectorCollectible(holdingId)
} else { } else {
@ -238,6 +234,7 @@ QtObject {
} }
function resetStoredProperties() { function resetStoredProperties() {
assetSearchString = ""
walletSectionSendInst.resetStoredProperties() walletSectionSendInst.resetStoredProperties()
nestedCollectiblesModel.currentCollectionUid = "" nestedCollectiblesModel.currentCollectionUid = ""
} }
@ -253,13 +250,104 @@ QtObject {
return walletSectionSendInst.getShortChainIds(chainShortNames) return walletSectionSendInst.getShortChainIds(chainShortNames)
} }
function getCurrencyAmountFromBigInt(balance, symbol, decimals) { function formatCurrencyAmountFromBigInt(balance, symbol, decimals) {
let bigIntBalance = AmountsArithmetic.fromString(balance) let bigIntBalance = AmountsArithmetic.fromString(balance)
let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals) let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals)
return currencyStore.getCurrencyAmount(decimalBalance, symbol) return currencyStore.formatCurrencyAmount(decimalBalance, symbol)
} }
function getCurrentCurrencyAmount(balance) { // Property set from TokenLIstView and HoldingSelector to search token by name, symbol or contract address
return currencyStore.getCurrencyAmount(balance, currencyStore.currentCurrency) property string assetSearchString
// Internal model filtering balances by the account selected on the SendModalPage
property SubmodelProxyModel __assetsWithFilteredBalances: SubmodelProxyModel {
sourceModel: walletAssetStore.groupedAccountAssetsModel
submodelRoleName: "balances"
delegateModel: SortFilterProxyModel {
sourceModel: submodel
filters: FastExpressionFilter {
expression: root.selectedSenderAccount.address === model.account
expectedRoles: ["account"]
}
}
}
// Model prepared to provide filtered and sorted assets as per the advanced Settings in token management
property var processedAssetsModel: SortFilterProxyModel {
sourceModel: __assetsWithFilteredBalances
proxyRoles: [
FastExpressionRole {
name: "isCommunityAsset"
expression: !!model.communityId
expectedRoles: ["communityId"]
},
FastExpressionRole {
name: "currentBalance"
expression: __getTotalBalance(model.balances, model.decimals, root.selectedSenderAccount)
expectedRoles: ["balances", "decimals"]
},
FastExpressionRole {
name: "currentCurrencyBalance"
expression: {
if (!!model.marketDetails) {
return model.currentBalance * model.marketDetails.currencyPrice.amount
}
return 0
}
expectedRoles: ["marketDetails", "currentBalance", "symbol"]
}
]
filters: [
FastExpressionFilter {
function search(symbol, name, addressPerChain, searchString) {
return (
symbol.toUpperCase().startsWith(searchString.toUpperCase()) ||
name.toUpperCase().startsWith(searchString.toUpperCase()) || __searchAddressInList(addressPerChain, searchString)
)
}
expression: search(symbol, name, addressPerChain, assetSearchString)
expectedRoles: ["symbol", "name", "addressPerChain"]
},
ValueFilter {
roleName: "isCommunityAsset"
value: false
enabled: !tokensStore.showCommunityAssetsInSend
},
FastExpressionFilter {
expression: {
if (model.isCommunityAsset)
return true
return model.currentCurrencyBalance > tokensStore.balanceThresholdAmount
}
expectedRoles: ["isCommunityAsset", "currentCurrencyBalance"]
enabled: tokensStore.balanceThresholdEnabled
}
]
sorters: RoleSorter {
roleName: "isCommunityAsset"
}
}
/* Internal function to search token address */
function __searchAddressInList(addressPerChain, searchString) {
let addressFound = false
let tokenAddresses = ModelUtils.modelToFlatArray(addressPerChain, "address")
for (let i =0; i< tokenAddresses.length; i++){
if(tokenAddresses[i].toUpperCase().startsWith(searchString.toUpperCase())) {
addressFound = true
break;
}
}
return addressFound
}
/* Internal function to calculate total balance */
function __getTotalBalance(balances, decimals) {
let totalBalance = 0
for(let i=0; i<balances.count; i++) {
let balancePerAddressPerChain = ModelUtils.get(balances, i)
totalBalance+=AmountsArithmetic.toNumber(balancePerAddressPerChain.balance, decimals)
}
return totalBalance
} }
} }

View File

@ -89,7 +89,6 @@ ColumnLayout {
sourceModel: root.assets sourceModel: root.assets
proxyRoles: [ proxyRoles: [
FastExpressionRole { FastExpressionRole {
id: filter
name: "currentBalance" name: "currentBalance"
expression: d.getTotalBalance(model.balances, model.decimals, root.addressFilters, root.networkFilters) expression: d.getTotalBalance(model.balances, model.decimals, root.addressFilters, root.networkFilters)
expectedRoles: ["balances", "decimals"] expectedRoles: ["balances", "decimals"]
@ -240,35 +239,9 @@ ColumnLayout {
Component { Component {
id: sectionDelegate id: sectionDelegate
ColumnLayout { AssetsSectionDelegate {
width: parent.width width: parent.width
spacing: 0 onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
StatusDialogDivider {
Layout.fillWidth: true
Layout.topMargin: Style.current.padding
Layout.bottomMargin: Style.current.halfPadding
}
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: Style.current.padding
Layout.rightMargin: Style.current.smallPadding
Layout.bottomMargin: 4
StatusBaseText {
text: qsTr("Community assets")
color: Theme.palette.baseColor1
}
Item { Layout.fillWidth: true }
StatusFlatButton {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
icon.name: "info"
textColor: Theme.palette.baseColor1
horizontalPadding: 0
verticalPadding: 0
onClicked: Global.openPopup(communityInfoPopupCmp)
}
}
} }
} }
@ -307,7 +280,7 @@ ColumnLayout {
} }
currencyBalance.text: { currencyBalance.text: {
let totalCurrencyBalance = modelData && modelData.currentCurrencyBalance ? modelData.currentCurrencyBalance : 0 let totalCurrencyBalance = modelData && modelData.currentCurrencyBalance ? modelData.currentCurrencyBalance : 0
return LocaleUtils.currencyAmountToLocaleString(root.currencyStore.getCurrentCurrencyAmount(totalCurrencyBalance)) return currencyStore.formatCurrencyAmount(totalCurrencyBalance, currencyStore.currentCurrency)
} }
errorMode: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCache && !networkConnectionStore.noMarketConnectionAndNoCache : false errorMode: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCache && !networkConnectionStore.noMarketConnectionAndNoCache : false
errorIcon.tooltip.text: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCacheText : "" errorIcon.tooltip.text: !!networkConnectionStore ? networkConnectionStore.noBlockchainConnectionAndNoCacheText : ""
@ -380,16 +353,7 @@ ColumnLayout {
Component { Component {
id: communityInfoPopupCmp id: communityInfoPopupCmp
StatusDialog { CommunityAssetsInfoPopup {}
destroyOnClose: true
title: qsTr("What are community assets?")
standardButtons: Dialog.Ok
width: 520
contentItem: StatusBaseText {
wrapMode: Text.Wrap
text: qsTr("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.")
}
}
} }
Component { Component {