diff --git a/storybook/pages/SendModalPage.qml b/storybook/pages/SendModalPage.qml index 8ed9713f60..142f0be57f 100644 --- a/storybook/pages/SendModalPage.qml +++ b/storybook/pages/SendModalPage.qml @@ -31,8 +31,9 @@ SplitView { submodelRoleName: "balances" delegateModel: SortFilterProxyModel { sourceModel: submodel - filters: ExpressionFilter { - expression: txStore.selectedSenderAccount.address === account + filters: FastExpressionFilter { + expression: txStore.selectedSenderAccount.address === model.account + expectedRoles: ["account"] } } } @@ -40,6 +41,9 @@ SplitView { TransactionStore { id: txStore walletAssetStore: root.walletAssetStore + showCommunityAssetsInSend: showCommunityAssetsCheckBox.checked + balanceThresholdEnabled: balanceThresholdCheckbox.checked + balanceThresholdAmount: Number(balanceThresholdValue.text) } QtObject { @@ -274,6 +278,32 @@ SplitView { 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 + } + } } } } diff --git a/storybook/pages/TokenListViewPage.qml b/storybook/pages/TokenListViewPage.qml index 9d7dee7b57..39a8b6c7f4 100644 --- a/storybook/pages/TokenListViewPage.qml +++ b/storybook/pages/TokenListViewPage.qml @@ -10,13 +10,25 @@ import AppLayouts.Wallet.stores 1.0 import StatusQ.Core.Utils 0.1 +import shared.stores 1.0 +import shared.stores.send 1.0 + SplitView { + id: root + orientation: Qt.Vertical readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { assetsWithFilteredBalances: groupedAccountsAssetsModel } + TransactionStore { + id: txStore + walletAssetStore: root.walletAssetStore + } + + readonly property CurrenciesStore currencyStore: CurrenciesStore {} + Item { SplitView.fillWidth: true SplitView.fillHeight: true @@ -31,26 +43,16 @@ SplitView { width: 400 - assets: walletAssetStore.groupedAccountAssetsModel + assets: txStore.processedAssetsModel collectibles: WalletNestedCollectiblesModel {} networksModel: NetworksModel.allNetworks - getCurrencyAmountFromBigInt: function(balance, symbol, decimals){ - let bigIntBalance = AmountsArithmetic.fromString(balance) - let balance123 = AmountsArithmetic.toNumber(bigIntBalance, decimals) - return ({ - amount: balance123, - symbol: symbol, - displayDecimals: 2, - stripTrailingZeroes: false - }) + formatCurrentCurrencyAmount: function(balance){ + return currencyStore.formatCurrencyAmount(balance, "USD") } - getCurrentCurrencyAmount: function(balance){ - return ({ - amount: balance, - symbol: "USD", - displayDecimals: 2, - stripTrailingZeroes: false - }) + formatCurrencyAmountFromBigInt: function(balance, symbol, decimals){ + let bigIntBalance = AmountsArithmetic.fromString(balance) + let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals) + return currencyStore.formatCurrencyAmount(decimalBalance, symbol) } } } diff --git a/storybook/src/Models/TokensBySymbolModel.qml b/storybook/src/Models/TokensBySymbolModel.qml index ea7694d262..b5d2bc4725 100644 --- a/storybook/src/Models/TokensBySymbolModel.qml +++ b/storybook/src/Models/TokensBySymbolModel.qml @@ -104,7 +104,7 @@ ListModel { addressPerChain: [ { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271e0f"} ], - decimals: 18, + decimals: 0, type: 1, communityId: "ddls", description: "", @@ -130,7 +130,7 @@ ListModel { addressPerChain: [ { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271p0f"} ], - decimals: 18, + decimals: 0, type: 1, communityId: "sox", description: "", @@ -156,7 +156,7 @@ ListModel { addressPerChain: [ { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271d0f"} ], - decimals: 18, + decimals: 0, type: 1, communityId: "ddls", description: "", @@ -182,7 +182,7 @@ ListModel { addressPerChain: [ { chainId: 420, address: "0x6b175474e89094c44da98b954eedeac495271a0f"} ], - decimals: 18, + decimals: 0, type: 1, communityId: "ast", description: "", diff --git a/storybook/stubs/shared/stores/CurrenciesStore.qml b/storybook/stubs/shared/stores/CurrenciesStore.qml index 7012fb8033..48d36a2b86 100644 --- a/storybook/stubs/shared/stores/CurrenciesStore.qml +++ b/storybook/stubs/shared/stores/CurrenciesStore.qml @@ -1,5 +1,7 @@ import QtQuick 2.15 +import StatusQ.Core 0.1 + QtObject { id: root @@ -7,7 +9,11 @@ QtObject { property string currentCurrencySymbol: "$" 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) { diff --git a/storybook/stubs/shared/stores/send/TransactionStore.qml b/storybook/stubs/shared/stores/send/TransactionStore.qml index 9e4be140ea..51f1130e6a 100644 --- a/storybook/stubs/shared/stores/send/TransactionStore.qml +++ b/storybook/stubs/shared/stores/send/TransactionStore.qml @@ -90,7 +90,7 @@ QtObject { function getHolding(holdingId, holdingType) { if (holdingType === Constants.TokenType.ERC20) { - return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) + return getAsset(processedAssetsModel, holdingId) } else if (holdingType === Constants.TokenType.ERC721) { return getCollectible(holdingId) } else { @@ -100,7 +100,7 @@ QtObject { function getSelectorHolding(holdingId, holdingType) { if (holdingType === Constants.TokenType.ERC20) { - return getAsset(walletAssetStore.groupedAccountAssetsModel, holdingId) + return getAsset(processedAssetsModel, holdingId) } else if (holdingType === Constants.TokenType.ERC721) { return getSelectorCollectible(holdingId) } else { @@ -255,14 +255,96 @@ QtObject { 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 balance123 = SQUtils.AmountsArithmetic.toNumber(bigIntBalance, decimals) - return currencyStore.getCurrencyAmount(balance123, symbol) + let decimalBalance = SQUtils.AmountsArithmetic.toNumber(bigIntBalance, decimals) + return currencyStore.formatCurrencyAmount(decimalBalance, symbol) } - function getCurrentCurrencyAmount(balance) { - return currencyStore.getCurrencyAmount(balance, currencyStore.currentCurrency) + // Property and methods below are used to apply advanced token management settings to the SendModal + 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 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