mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-11 14:16:43 +00:00
feat(@desktop/wallet): Move the Account Selector logic to show selected token balance on a sepcific network to a dedicated WalletAccountsSelectorAdaptor
fixes #16705
This commit is contained in:
parent
37a06fc3be
commit
0d4d1b0ba7
@ -7,48 +7,205 @@ import Models 1.0
|
|||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
|
import shared.stores 1.0
|
||||||
|
|
||||||
Item {
|
import AppLayouts.Wallet.stores 1.0
|
||||||
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
SplitView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
ColumnLayout {
|
orientation: Qt.Vertical
|
||||||
spacing: 16
|
|
||||||
anchors.centerIn: parent
|
|
||||||
implicitWidth: 150
|
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
WalletAccountsModel {
|
readonly property var flatNetworks: NetworksModel.flatNetworks
|
||||||
id: accountsModel
|
readonly property var assetsStore: WalletAssetsStore {
|
||||||
|
id: thisWalletAssetStore
|
||||||
|
walletTokensStore: TokensStore {
|
||||||
|
plainTokensBySymbolModel: TokensBySymbolModel {}
|
||||||
|
}
|
||||||
|
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
||||||
|
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
readonly property var currencyStore: CurrenciesStore{}
|
||||||
text: "Default style"
|
readonly property var nonWatchWalletAcounts: SortFilterProxyModel {
|
||||||
font.bold: true
|
sourceModel: walletAccountsModel
|
||||||
Layout.fillWidth: true
|
filters: ValueFilter { roleName: "canSend"; value: true }
|
||||||
}
|
}
|
||||||
AccountSelector {
|
|
||||||
id: accountSelector
|
readonly property var filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
Layout.fillWidth: true
|
sourceModel: d.flatNetworks
|
||||||
model: WalletAccountsModel {}
|
filters: ValueFilter { roleName: "isTest"; value: true }
|
||||||
onCurrentAccountAddressChanged: {
|
}
|
||||||
accountSelector2.selectedAddress = currentAccountAddress
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: walletAccountsModel
|
||||||
|
readonly property var data: [
|
||||||
|
{
|
||||||
|
name: "helloworld",
|
||||||
|
address: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||||
|
emoji: "😋",
|
||||||
|
colorId: Constants.walletAccountColors.primary,
|
||||||
|
walletType: "",
|
||||||
|
canSend: true,
|
||||||
|
position: 0,
|
||||||
|
currencyBalance: ({amount: 1.25,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Hot wallet (generated)",
|
||||||
|
emoji: "🚗",
|
||||||
|
colorId: Constants.walletAccountColors.army,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||||
|
walletType: Constants.generatedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 3,
|
||||||
|
currencyBalance: ({amount: 10,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Family (seed)",
|
||||||
|
emoji: "🎨",
|
||||||
|
colorId: Constants.walletAccountColors.magenta,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8882",
|
||||||
|
walletType: Constants.seedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 1,
|
||||||
|
currencyBalance: ({amount: 110.05,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Tag Heuer (watch)",
|
||||||
|
emoji: "⌚",
|
||||||
|
colorId: Constants.walletAccountColors.copper,
|
||||||
|
color: "#CB6256",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8883",
|
||||||
|
walletType: Constants.watchWalletType,
|
||||||
|
canSend: false,
|
||||||
|
position: 2,
|
||||||
|
currencyBalance: ({amount: 3,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fab (key)",
|
||||||
|
emoji: "🔑",
|
||||||
|
colorId: Constants.walletAccountColors.camel,
|
||||||
|
color: "#C78F67",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8884",
|
||||||
|
walletType: Constants.keyWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 4,
|
||||||
|
currencyBalance: ({amount: 999,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Component.onCompleted: append(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAccountsSelectorAdaptor {
|
||||||
|
id: walletAccountsSelectorAdaptor
|
||||||
|
|
||||||
|
accounts: walletAccountsModel
|
||||||
|
assetsModel: d.assetsStore.groupedAccountAssetsModel
|
||||||
|
tokensBySymbolModel: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: d.filteredFlatNetworksModel
|
||||||
|
|
||||||
|
selectedTokenKey: selectedTokenComboBox.currentValue
|
||||||
|
selectedNetworkChainId: networksComboBox.currentValue
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: function(balance, symbol, decimals, options = null) {
|
||||||
|
return d.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
SplitView.preferredWidth: 150
|
||||||
|
SplitView.fillHeight: true
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
width: 150
|
||||||
|
|
||||||
|
WalletAccountsModel {
|
||||||
|
id: accountsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Default style"
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
AccountSelector {
|
||||||
|
id: accountSelector
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: WalletAccountsModel {}
|
||||||
|
onCurrentAccountAddressChanged: {
|
||||||
|
accountSelector2.selectedAddress = currentAccountAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Header style"
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
AccountSelectorHeader {
|
||||||
|
id: accountSelector2
|
||||||
|
model: walletAccountsSelectorAdaptor.processedWalletAccounts
|
||||||
|
onCurrentAccountAddressChanged: {
|
||||||
|
accountSelector.selectedAddress = currentAccountAddress
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
}
|
||||||
text: "Header style"
|
|
||||||
font.bold: true
|
Item {
|
||||||
Layout.fillWidth: true
|
SplitView.preferredWidth: 300
|
||||||
}
|
SplitView.preferredHeight: childrenRect.height
|
||||||
AccountSelectorHeader {
|
|
||||||
id: accountSelector2
|
ColumnLayout {
|
||||||
model: accountSelector.model
|
|
||||||
onCurrentAccountAddressChanged: {
|
Label { text: "Selected Token" }
|
||||||
accountSelector.selectedAddress = currentAccountAddress
|
ComboBox {
|
||||||
|
id: selectedTokenComboBox
|
||||||
|
textRole: "name"
|
||||||
|
valueRole: "key"
|
||||||
|
model: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
currentIndex: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
Label { text: "Selected Network" }
|
||||||
|
ComboBox {
|
||||||
|
id: networksComboBox
|
||||||
|
textRole: "chainName"
|
||||||
|
valueRole: "chainId"
|
||||||
|
model: d.filteredFlatNetworksModel
|
||||||
|
currentIndex: -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// category: Components
|
// category: Components
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
import StatusQ.Core.Backpressure 0.1
|
import StatusQ.Core.Backpressure 0.1
|
||||||
|
|
||||||
import Models 1.0
|
import Models 1.0
|
||||||
@ -32,6 +33,10 @@ SplitView {
|
|||||||
|
|
||||||
readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore {
|
readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore {
|
||||||
assetsWithFilteredBalances: groupedAccountsAssetsModel
|
assetsWithFilteredBalances: groupedAccountsAssetsModel
|
||||||
|
walletTokensStore: TokensStore {
|
||||||
|
plainTokensBySymbolModel: TokensBySymbolModel{}
|
||||||
|
getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property var walletAccountsModel: WalletAccountsModel{}
|
readonly property var walletAccountsModel: WalletAccountsModel{}
|
||||||
@ -67,6 +72,14 @@ SplitView {
|
|||||||
simpleSend.estimatedFiatFees = "1.45 EUR"
|
simpleSend.estimatedFiatFees = "1.45 EUR"
|
||||||
simpleSend.estimatedCryptoFees = "0.0007 ETH"
|
simpleSend.estimatedCryptoFees = "0.0007 ETH"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function formatCurrencyAmount(amount, symbol, options = null, locale = null) {
|
||||||
|
if (isNaN(amount)) {
|
||||||
|
return "N/A"
|
||||||
|
}
|
||||||
|
var currencyAmount = d.getCurrencyAmount(amount, symbol)
|
||||||
|
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options, locale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupBackground {
|
PopupBackground {
|
||||||
@ -96,7 +109,7 @@ SplitView {
|
|||||||
|
|
||||||
interactive: interactiveCheckbox.checked
|
interactive: interactiveCheckbox.checked
|
||||||
|
|
||||||
accountsModel: d.walletAccountsModel
|
accountsModel: accountsSelectorAdaptor.processedWalletAccounts
|
||||||
assetsModel: assetsSelectorViewAdaptor.outputAssetsModel
|
assetsModel: assetsSelectorViewAdaptor.outputAssetsModel
|
||||||
collectiblesModel: collectiblesSelectionAdaptor.model
|
collectiblesModel: collectiblesSelectionAdaptor.model
|
||||||
networksModel: d.filteredNetworksModel
|
networksModel: d.filteredNetworksModel
|
||||||
@ -105,13 +118,7 @@ SplitView {
|
|||||||
recentRecipientsModel: WalletTransactionsModel{}
|
recentRecipientsModel: WalletTransactionsModel{}
|
||||||
|
|
||||||
currentCurrency: "USD"
|
currentCurrency: "USD"
|
||||||
fnFormatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
fnFormatCurrencyAmount: d.formatCurrencyAmount
|
||||||
if (isNaN(amount)) {
|
|
||||||
return "N/A"
|
|
||||||
}
|
|
||||||
var currencyAmount = d.getCurrencyAmount(amount, symbol)
|
|
||||||
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options, locale)
|
|
||||||
}
|
|
||||||
|
|
||||||
fnResolveENS: Backpressure.debounce(root, 500, function (ensName, uuid) {
|
fnResolveENS: Backpressure.debounce(root, 500, function (ensName, uuid) {
|
||||||
if (!!ensName && ensName.endsWith(".eth")) {
|
if (!!ensName && ensName.endsWith(".eth")) {
|
||||||
@ -146,6 +153,24 @@ SplitView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WalletAccountsSelectorAdaptor {
|
||||||
|
id: accountsSelectorAdaptor
|
||||||
|
|
||||||
|
accounts: d.walletAccountsModel
|
||||||
|
assetsModel: GroupedAccountsAssetsModel {}
|
||||||
|
tokensBySymbolModel: d.walletAssetStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: d.filteredNetworksModel
|
||||||
|
|
||||||
|
selectedTokenKey: simpleSend.selectedTokenKey
|
||||||
|
selectedNetworkChainId: simpleSend.selectedChainId
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: function(balance, symbol, decimals, options = null) {
|
||||||
|
let bigIntBalance = AmountsArithmetic.fromString(balance)
|
||||||
|
let decimalBalance = AmountsArithmetic.toNumber(bigIntBalance, decimals)
|
||||||
|
return d.formatCurrencyAmount(decimalBalance, symbol, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TokenSelectorViewAdaptor {
|
TokenSelectorViewAdaptor {
|
||||||
id: assetsSelectorViewAdaptor
|
id: assetsSelectorViewAdaptor
|
||||||
|
|
||||||
|
187
storybook/pages/WalletAccountsSelectorAdaptorPage.qml
Normal file
187
storybook/pages/WalletAccountsSelectorAdaptorPage.qml
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import AppLayouts.Wallet.stores 1.0
|
||||||
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
|
|
||||||
|
import Storybook 1.0
|
||||||
|
import Models 1.0
|
||||||
|
|
||||||
|
import shared.stores 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: walletAccountsModel
|
||||||
|
readonly property var data: [
|
||||||
|
{
|
||||||
|
name: "helloworld",
|
||||||
|
address: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||||
|
emoji: "😋",
|
||||||
|
colorId: Constants.walletAccountColors.primary,
|
||||||
|
walletType: "",
|
||||||
|
canSend: true,
|
||||||
|
position: 0,
|
||||||
|
currencyBalance: ({amount: 1.25,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Hot wallet (generated)",
|
||||||
|
emoji: "🚗",
|
||||||
|
colorId: Constants.walletAccountColors.army,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||||
|
walletType: Constants.generatedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 3,
|
||||||
|
currencyBalance: ({amount: 10,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Family (seed)",
|
||||||
|
emoji: "🎨",
|
||||||
|
colorId: Constants.walletAccountColors.magenta,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8882",
|
||||||
|
walletType: Constants.seedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 1,
|
||||||
|
currencyBalance: ({amount: 110.05,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Tag Heuer (watch)",
|
||||||
|
emoji: "⌚",
|
||||||
|
colorId: Constants.walletAccountColors.copper,
|
||||||
|
color: "#CB6256",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8883",
|
||||||
|
walletType: Constants.watchWalletType,
|
||||||
|
canSend: false,
|
||||||
|
position: 2,
|
||||||
|
currencyBalance: ({amount: 3,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fab (key)",
|
||||||
|
emoji: "🔑",
|
||||||
|
colorId: Constants.walletAccountColors.camel,
|
||||||
|
color: "#C78F67",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8884",
|
||||||
|
walletType: Constants.keyWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 4,
|
||||||
|
currencyBalance: ({amount: 999,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Component.onCompleted: append(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
readonly property var assetsStore: WalletAssetsStore {
|
||||||
|
id: thisWalletAssetStore
|
||||||
|
walletTokensStore: TokensStore {
|
||||||
|
plainTokensBySymbolModel: TokensBySymbolModel {}
|
||||||
|
}
|
||||||
|
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
||||||
|
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
||||||
|
}
|
||||||
|
readonly property var currencyStore: CurrenciesStore{}
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletAccountsSelectorAdaptor {
|
||||||
|
id: adaptor
|
||||||
|
accounts: walletAccountsModel
|
||||||
|
assetsModel: d.assetsStore.groupedAccountAssetsModel
|
||||||
|
tokensBySymbolModel: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
|
sourceModel: NetworksModel.flatNetworks
|
||||||
|
filters: ValueFilter { roleName: "isTest"; value: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: function(balance, symbol, decimals, options = null) {
|
||||||
|
return d.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTokenKey: selectedTokenComboBox.currentValue
|
||||||
|
selectedNetworkChainId: networksComboBox.currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Label { text: "Selected Token" }
|
||||||
|
ComboBox {
|
||||||
|
id: selectedTokenComboBox
|
||||||
|
textRole: "name"
|
||||||
|
valueRole: "key"
|
||||||
|
model: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
currentIndex: 0
|
||||||
|
onCountChanged: currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Label { text: "Selected Network" }
|
||||||
|
ComboBox {
|
||||||
|
id: networksComboBox
|
||||||
|
textRole: "chainName"
|
||||||
|
valueRole: "chainId"
|
||||||
|
model: adaptor.filteredFlatNetworksModel
|
||||||
|
currentIndex: 0
|
||||||
|
onCountChanged: currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
GenericListView {
|
||||||
|
label: "Input Accounts model"
|
||||||
|
|
||||||
|
model: walletAccountsModel
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
roles: ["name", "address", "currencyBalance", "position", "canSend"]
|
||||||
|
|
||||||
|
skipEmptyRoles: true
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericListView {
|
||||||
|
label: "Adapter's output model"
|
||||||
|
|
||||||
|
model: adaptor.processedWalletAccounts
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
roles: ["name", "address", "currencyBalance", "position", "canSend", "accountBalance", "currencyBalanceDouble"]
|
||||||
|
|
||||||
|
skipEmptyRoles: true
|
||||||
|
|
||||||
|
insetComponent: Label {
|
||||||
|
text: "balance " + (model ? model.accountBalance.formattedBalance: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// category: Adaptors
|
@ -171,26 +171,28 @@ Item {
|
|||||||
|
|
||||||
function test_floating_header_default_account() {
|
function test_floating_header_default_account() {
|
||||||
verify(!!controlUnderTest)
|
verify(!!controlUnderTest)
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
/* using a for loop set different accounts as default index and
|
/* using a for loop set different accounts as default index and
|
||||||
check if the correct values are displayed in the floating header*/
|
check if the correct values are displayed in the floating header*/
|
||||||
for (let i = 0; i< swapAdaptor.nonWatchAccounts.count; i++) {
|
for (let i = 0; i< walletAccounts.count; i++) {
|
||||||
const nonWatchAccount = swapAdaptor.nonWatchAccounts.get(i)
|
const accountToTest = walletAccounts.get(i)
|
||||||
root.swapFormData.selectedAccountAddress = nonWatchAccount.address
|
root.swapFormData.selectedAccountAddress = accountToTest.address
|
||||||
|
|
||||||
// Launch popup
|
// Launch popup
|
||||||
launchAndVerfyModal()
|
launchAndVerfyModal()
|
||||||
|
|
||||||
const floatingHeaderBackground = findChild(controlUnderTest, "headerBackground")
|
const floatingHeaderBackground = findChild(controlUnderTest, "headerBackground")
|
||||||
verify(!!floatingHeaderBackground)
|
verify(!!floatingHeaderBackground)
|
||||||
compare(floatingHeaderBackground.color.toString().toUpperCase(), Utils.getColorForId(nonWatchAccount.colorId).toString().toUpperCase())
|
compare(floatingHeaderBackground.color.toString().toUpperCase(), Utils.getColorForId(accountToTest.colorId).toString().toUpperCase())
|
||||||
|
|
||||||
const headerContentItemText = findChild(controlUnderTest, "textContent")
|
const headerContentItemText = findChild(controlUnderTest, "textContent")
|
||||||
verify(!!headerContentItemText)
|
verify(!!headerContentItemText)
|
||||||
compare(headerContentItemText.text, nonWatchAccount.name)
|
compare(headerContentItemText.text, accountToTest.name)
|
||||||
|
|
||||||
const headerContentItemEmoji = findChild(controlUnderTest, "assetContent")
|
const headerContentItemEmoji = findChild(controlUnderTest, "assetContent")
|
||||||
verify(!!headerContentItemEmoji)
|
verify(!!headerContentItemEmoji)
|
||||||
compare(headerContentItemEmoji.asset.emoji, nonWatchAccount.emoji)
|
compare(headerContentItemEmoji.asset.emoji, accountToTest.emoji)
|
||||||
}
|
}
|
||||||
closeAndVerfyModal()
|
closeAndVerfyModal()
|
||||||
}
|
}
|
||||||
@ -228,6 +230,7 @@ Item {
|
|||||||
launchAndVerfyModal()
|
launchAndVerfyModal()
|
||||||
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
launchAccountSelectionPopup(accountsModalHeader)
|
launchAccountSelectionPopup(accountsModalHeader)
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
const comboBoxList = findChild(controlUnderTest, "accountSelectorList")
|
const comboBoxList = findChild(controlUnderTest, "accountSelectorList")
|
||||||
verify(!!comboBoxList)
|
verify(!!comboBoxList)
|
||||||
@ -235,7 +238,7 @@ Item {
|
|||||||
|
|
||||||
for(let i =0; i< comboBoxList.model.count; i++) {
|
for(let i =0; i< comboBoxList.model.count; i++) {
|
||||||
let delegateUnderTest = comboBoxList.itemAtIndex(i)
|
let delegateUnderTest = comboBoxList.itemAtIndex(i)
|
||||||
let accountToBeTested = swapAdaptor.nonWatchAccounts.get(i)
|
let accountToBeTested = walletAccounts.get(i)
|
||||||
let elidedAddress = SQUtils.Utils.elideAndFormatWalletAddress(accountToBeTested.address)
|
let elidedAddress = SQUtils.Utils.elideAndFormatWalletAddress(accountToBeTested.address)
|
||||||
compare(delegateUnderTest.title, accountToBeTested.name)
|
compare(delegateUnderTest.title, accountToBeTested.name)
|
||||||
compare(delegateUnderTest.subTitle, elidedAddress)
|
compare(delegateUnderTest.subTitle, elidedAddress)
|
||||||
@ -302,7 +305,6 @@ Item {
|
|||||||
|
|
||||||
for(let i =0; i< comboBoxList.model.count; i++) {
|
for(let i =0; i< comboBoxList.model.count; i++) {
|
||||||
let delegateUnderTest = comboBoxList.itemAtIndex(i)
|
let delegateUnderTest = comboBoxList.itemAtIndex(i)
|
||||||
verify(!!delegateUnderTest.model.fromToken)
|
|
||||||
verify(!!delegateUnderTest.model.accountBalance)
|
verify(!!delegateUnderTest.model.accountBalance)
|
||||||
compare(delegateUnderTest.inlineTagModel, 1)
|
compare(delegateUnderTest.inlineTagModel, 1)
|
||||||
|
|
||||||
@ -315,9 +317,9 @@ Item {
|
|||||||
compare(inlineTagDelegate_0.asset.color.toString().toUpperCase(), delegateUnderTest.model.accountBalance.chainColor.toString().toUpperCase())
|
compare(inlineTagDelegate_0.asset.color.toString().toUpperCase(), delegateUnderTest.model.accountBalance.chainColor.toString().toUpperCase())
|
||||||
compare(inlineTagDelegate_0.titleText.color, balance === "0" ? Theme.palette.baseColor1 : Theme.palette.directColor1)
|
compare(inlineTagDelegate_0.titleText.color, balance === "0" ? Theme.palette.baseColor1 : Theme.palette.directColor1)
|
||||||
|
|
||||||
let bigIntBalance = SQUtils.AmountsArithmetic.toNumber(balance, delegateUnderTest.model.fromToken.decimals)
|
let bigIntBalance = SQUtils.AmountsArithmetic.toNumber(balance, controlUnderTest.swapAdaptor.fromToken.decimals)
|
||||||
compare(inlineTagDelegate_0.title, balance === "0" ? "0 %1".arg(delegateUnderTest.model.fromToken.symbol)
|
compare(inlineTagDelegate_0.title, balance === "0" ? "0 %1".arg(controlUnderTest.swapAdaptor.fromToken.symbol)
|
||||||
: root.swapAdaptor.formatCurrencyAmount(bigIntBalance, delegateUnderTest.model.fromToken.symbol))
|
: root.swapAdaptor.currencyStore.formatCurrencyAmount(bigIntBalance, controlUnderTest.swapAdaptor.fromToken.symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
closeAndVerfyModal()
|
closeAndVerfyModal()
|
||||||
@ -327,13 +329,16 @@ Item {
|
|||||||
// Launch popup
|
// Launch popup
|
||||||
launchAndVerfyModal()
|
launchAndVerfyModal()
|
||||||
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
const payPanel = findChild(controlUnderTest, "payPanel")
|
const payPanel = findChild(controlUnderTest, "payPanel")
|
||||||
verify(!!payPanel)
|
verify(!!payPanel)
|
||||||
const amountToSendInput = findChild(payPanel, "amountToSendInput")
|
const amountToSendInput = findChild(payPanel, "amountToSendInput")
|
||||||
verify(!!amountToSendInput)
|
verify(!!amountToSendInput)
|
||||||
verify(amountToSendInput.cursorVisible)
|
verify(amountToSendInput.cursorVisible)
|
||||||
|
|
||||||
for(let i =0; i< swapAdaptor.nonWatchAccounts.count; i++) {
|
for(let i =0; i< walletAccounts.count; i++) {
|
||||||
// launch account selection dropdown
|
// launch account selection dropdown
|
||||||
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
launchAccountSelectionPopup(accountsModalHeader)
|
launchAccountSelectionPopup(accountsModalHeader)
|
||||||
@ -348,20 +353,20 @@ Item {
|
|||||||
verify(accountsModalHeader.control.popup.closed)
|
verify(accountsModalHeader.control.popup.closed)
|
||||||
|
|
||||||
// The input params form's slected Index should be updated as per this selection
|
// The input params form's slected Index should be updated as per this selection
|
||||||
compare(root.swapFormData.selectedAccountAddress, swapAdaptor.nonWatchAccounts.get(i).address)
|
compare(root.swapFormData.selectedAccountAddress, walletAccounts.get(i).address)
|
||||||
|
|
||||||
// The comboBox item should reflect chosen account
|
// The comboBox item should reflect chosen account
|
||||||
const floatingHeaderBackground = findChild(accountsModalHeader, "headerBackground")
|
const floatingHeaderBackground = findChild(accountsModalHeader, "headerBackground")
|
||||||
verify(!!floatingHeaderBackground)
|
verify(!!floatingHeaderBackground)
|
||||||
compare(floatingHeaderBackground.color.toString().toUpperCase(), swapAdaptor.nonWatchAccounts.get(i).color.toString().toUpperCase())
|
compare(floatingHeaderBackground.color.toString().toUpperCase(), walletAccounts.get(i).color.toString().toUpperCase())
|
||||||
|
|
||||||
const headerContentItemText = findChild(accountsModalHeader, "textContent")
|
const headerContentItemText = findChild(accountsModalHeader, "textContent")
|
||||||
verify(!!headerContentItemText)
|
verify(!!headerContentItemText)
|
||||||
compare(headerContentItemText.text, swapAdaptor.nonWatchAccounts.get(i).name)
|
compare(headerContentItemText.text, walletAccounts.get(i).name)
|
||||||
|
|
||||||
const headerContentItemEmoji = findChild(accountsModalHeader, "assetContent")
|
const headerContentItemEmoji = findChild(accountsModalHeader, "assetContent")
|
||||||
verify(!!headerContentItemEmoji)
|
verify(!!headerContentItemEmoji)
|
||||||
compare(headerContentItemEmoji.asset.emoji, swapAdaptor.nonWatchAccounts.get(i).emoji)
|
compare(headerContentItemEmoji.asset.emoji, walletAccounts.get(i).emoji)
|
||||||
|
|
||||||
waitForRendering(amountToSendInput)
|
waitForRendering(amountToSendInput)
|
||||||
|
|
||||||
@ -477,7 +482,7 @@ Item {
|
|||||||
verify(!!fromToken)
|
verify(!!fromToken)
|
||||||
let bigIntBalance = SQUtils.AmountsArithmetic.toNumber(accountBalance.balance, fromToken.decimals)
|
let bigIntBalance = SQUtils.AmountsArithmetic.toNumber(accountBalance.balance, fromToken.decimals)
|
||||||
compare(inlineTagDelegate_0.title, bigIntBalance === 0 ? "0 %1".arg(fromToken.symbol)
|
compare(inlineTagDelegate_0.title, bigIntBalance === 0 ? "0 %1".arg(fromToken.symbol)
|
||||||
: root.swapAdaptor.formatCurrencyAmount(bigIntBalance, fromToken.symbol))
|
: root.swapAdaptor.currencyStore.formatCurrencyAmount(bigIntBalance, fromToken.symbol))
|
||||||
}
|
}
|
||||||
// close account selection dropdown
|
// close account selection dropdown
|
||||||
accountsModalHeader.control.popup.close()
|
accountsModalHeader.control.popup.close()
|
||||||
@ -918,7 +923,11 @@ Item {
|
|||||||
// try setting value before popup is launched and check values
|
// try setting value before popup is launched and check values
|
||||||
let valueToExchange = 0.001
|
let valueToExchange = 0.001
|
||||||
let valueToExchangeString = valueToExchange.toString()
|
let valueToExchangeString = valueToExchange.toString()
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.fromTokensKey = "ETH"
|
root.swapFormData.fromTokensKey = "ETH"
|
||||||
root.swapFormData.fromTokenAmount = valueToExchangeString
|
root.swapFormData.fromTokenAmount = valueToExchangeString
|
||||||
@ -968,11 +977,14 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_modal_pay_input_wrong_value_1() {
|
function test_modal_pay_input_wrong_value_1() {
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
let invalidValues = ["ABC", "0.0.010201", "12PASA", "100,9.01"]
|
let invalidValues = ["ABC", "0.0.010201", "12PASA", "100,9.01"]
|
||||||
for (let i =0; i<invalidValues.length; i++) {
|
for (let i =0; i<invalidValues.length; i++) {
|
||||||
let invalidValue = invalidValues[i]
|
let invalidValue = invalidValues[i]
|
||||||
// try setting value before popup is launched and check values
|
// try setting value before popup is launched and check values
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.fromTokensKey =
|
root.swapFormData.fromTokensKey =
|
||||||
root.swapFormData.fromTokenAmount = invalidValue
|
root.swapFormData.fromTokenAmount = invalidValue
|
||||||
@ -1013,10 +1025,13 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_modal_pay_input_wrong_value_2() {
|
function test_modal_pay_input_wrong_value_2() {
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
// try setting value before popup is launched and check values
|
// try setting value before popup is launched and check values
|
||||||
let valueToExchange = 100
|
let valueToExchange = 100
|
||||||
let valueToExchangeString = valueToExchange.toString()
|
let valueToExchangeString = valueToExchange.toString()
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.fromTokensKey = "ETH"
|
root.swapFormData.fromTokensKey = "ETH"
|
||||||
root.swapFormData.fromTokenAmount = valueToExchangeString
|
root.swapFormData.fromTokenAmount = valueToExchangeString
|
||||||
@ -1103,10 +1118,13 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_modal_receive_input_presetValues() {
|
function test_modal_receive_input_presetValues() {
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
let valueToReceive = 0.001
|
let valueToReceive = 0.001
|
||||||
let valueToReceiveString = valueToReceive.toString()
|
let valueToReceiveString = valueToReceive.toString()
|
||||||
// try setting value before popup is launched and check values
|
// try setting value before popup is launched and check values
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.toTokenKey = "STT"
|
root.swapFormData.toTokenKey = "STT"
|
||||||
root.swapFormData.toTokenAmount = valueToReceiveString
|
root.swapFormData.toTokenAmount = valueToReceiveString
|
||||||
@ -1164,12 +1182,15 @@ Item {
|
|||||||
root.swapFormData.fromTokenAmount = valueToExchangeString
|
root.swapFormData.fromTokenAmount = valueToExchangeString
|
||||||
root.swapFormData.toTokenKey = "STT"
|
root.swapFormData.toTokenKey = "STT"
|
||||||
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
formValuesChanged.wait()
|
formValuesChanged.wait()
|
||||||
|
|
||||||
// Launch popup
|
// Launch popup
|
||||||
launchAndVerfyModal()
|
launchAndVerfyModal()
|
||||||
// The default is the first account. Setting the second account to test switching accounts
|
// The default is the first account. Setting the second account to test switching accounts
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(1).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(1).address
|
||||||
|
|
||||||
waitForItemPolished(controlUnderTest.contentItem)
|
waitForItemPolished(controlUnderTest.contentItem)
|
||||||
|
|
||||||
@ -1215,13 +1236,17 @@ Item {
|
|||||||
function test_modal_max_button_click_with_no_preset_pay_value() {
|
function test_modal_max_button_click_with_no_preset_pay_value() {
|
||||||
// Launch popup
|
// Launch popup
|
||||||
launchAndVerfyModal()
|
launchAndVerfyModal()
|
||||||
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
// The default is the first account. Setting the second account to test switching accounts
|
// The default is the first account. Setting the second account to test switching accounts
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(1).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(1).address
|
||||||
formValuesChanged.clear()
|
formValuesChanged.clear()
|
||||||
|
|
||||||
// try setting value before popup is launched and check values
|
// try setting value before popup is launched and check values
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.fromTokensKey = "ETH"
|
root.swapFormData.fromTokensKey = "ETH"
|
||||||
root.swapFormData.toTokenKey = "STT"
|
root.swapFormData.toTokenKey = "STT"
|
||||||
|
|
||||||
@ -1266,6 +1291,10 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_modal_pay_input_switching_accounts() {
|
function test_modal_pay_input_switching_accounts() {
|
||||||
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
// test with pay value being set and not set
|
// test with pay value being set and not set
|
||||||
let payValuesToTestWith = ["", "0.2"]
|
let payValuesToTestWith = ["", "0.2"]
|
||||||
|
|
||||||
@ -1275,7 +1304,7 @@ Item {
|
|||||||
|
|
||||||
// Asset chosen but no pay value set state -------------------------------------------------------------------------------
|
// Asset chosen but no pay value set state -------------------------------------------------------------------------------
|
||||||
root.swapFormData.fromTokenAmount = valueToExchangeString
|
root.swapFormData.fromTokenAmount = valueToExchangeString
|
||||||
root.swapFormData.selectedAccountAddress = swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.fromTokensKey = "ETH"
|
root.swapFormData.fromTokensKey = "ETH"
|
||||||
|
|
||||||
@ -1292,8 +1321,8 @@ Item {
|
|||||||
const errorTag = findChild(controlUnderTest, "errorTag")
|
const errorTag = findChild(controlUnderTest, "errorTag")
|
||||||
verify(!!errorTag)
|
verify(!!errorTag)
|
||||||
|
|
||||||
for (let i=0; i< root.swapAdaptor.nonWatchAccounts.count; i++) {
|
for (let i=0; i< walletAccounts.count; i++) {
|
||||||
root.swapFormData.selectedAccountAddress = root.swapAdaptor.nonWatchAccounts.get(i).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(i).address
|
||||||
|
|
||||||
waitForItemPolished(controlUnderTest.contentItem)
|
waitForItemPolished(controlUnderTest.contentItem)
|
||||||
|
|
||||||
@ -1382,11 +1411,14 @@ Item {
|
|||||||
const receiveBottomItemText = findChild(receivePanel, "bottomItemText")
|
const receiveBottomItemText = findChild(receivePanel, "bottomItemText")
|
||||||
verify(!!receiveBottomItemText)
|
verify(!!receiveBottomItemText)
|
||||||
|
|
||||||
|
const accountsModalHeader = getAndVerifyAccountsModalHeader()
|
||||||
|
let walletAccounts = accountsModalHeader.model
|
||||||
|
|
||||||
root.swapAdaptor.reset()
|
root.swapAdaptor.reset()
|
||||||
|
|
||||||
// set network and address by default same
|
// set network and address by default same
|
||||||
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
root.swapFormData.selectedNetworkChainId = root.swapAdaptor.filteredFlatNetworksModel.get(0).chainId
|
||||||
root.swapFormData.selectedAccountAddress = root.swapAdaptor.nonWatchAccounts.get(0).address
|
root.swapFormData.selectedAccountAddress = walletAccounts.get(0).address
|
||||||
root.swapFormData.fromTokensKey = data.fromToken
|
root.swapFormData.fromTokensKey = data.fromToken
|
||||||
root.swapFormData.fromTokenAmount = data.fromTokenAmount
|
root.swapFormData.fromTokenAmount = data.fromTokenAmount
|
||||||
root.swapFormData.toTokenKey = data.toToken
|
root.swapFormData.toTokenKey = data.toToken
|
||||||
|
208
storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml
Normal file
208
storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtTest 1.15
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
import AppLayouts.Wallet.stores 1.0
|
||||||
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
|
|
||||||
|
import Models 1.0
|
||||||
|
|
||||||
|
import shared.stores 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
width: 600
|
||||||
|
height: 400
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: walletAccountsModel
|
||||||
|
readonly property var data: [
|
||||||
|
{
|
||||||
|
name: "helloworld",
|
||||||
|
address: "0x7F47C2e18a4BBf5487E6fb082eC2D9Ab0E6d7240",
|
||||||
|
emoji: "😋",
|
||||||
|
colorId: Constants.walletAccountColors.primary,
|
||||||
|
walletType: "",
|
||||||
|
canSend: true,
|
||||||
|
position: 0,
|
||||||
|
currencyBalance: ({amount: 1.25,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Hot wallet (generated)",
|
||||||
|
emoji: "🚗",
|
||||||
|
colorId: Constants.walletAccountColors.army,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8881",
|
||||||
|
walletType: Constants.generatedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 3,
|
||||||
|
currencyBalance: ({amount: 10,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Family (seed)",
|
||||||
|
emoji: "🎨",
|
||||||
|
colorId: Constants.walletAccountColors.magenta,
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8882",
|
||||||
|
walletType: Constants.seedWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 1,
|
||||||
|
currencyBalance: ({amount: 110.05,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Tag Heuer (watch)",
|
||||||
|
emoji: "⌚",
|
||||||
|
colorId: Constants.walletAccountColors.copper,
|
||||||
|
color: "#CB6256",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8883",
|
||||||
|
walletType: Constants.watchWalletType,
|
||||||
|
canSend: false,
|
||||||
|
position: 2,
|
||||||
|
currencyBalance: ({amount: 3,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fab (key)",
|
||||||
|
emoji: "🔑",
|
||||||
|
colorId: Constants.walletAccountColors.camel,
|
||||||
|
color: "#C78F67",
|
||||||
|
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8884",
|
||||||
|
walletType: Constants.keyWalletType,
|
||||||
|
canSend: true,
|
||||||
|
position: 4,
|
||||||
|
currencyBalance: ({amount: 999,
|
||||||
|
symbol: "USD",
|
||||||
|
displayDecimals: 2,
|
||||||
|
stripTrailingZeroes: false}),
|
||||||
|
migratedToKeycard: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Component.onCompleted: append(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
readonly property var flatNetworks: NetworksModel.flatNetworks
|
||||||
|
readonly property var assetsStore: WalletAssetsStore {
|
||||||
|
id: thisWalletAssetStore
|
||||||
|
walletTokensStore: TokensStore {
|
||||||
|
plainTokensBySymbolModel: TokensBySymbolModel {}
|
||||||
|
}
|
||||||
|
readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {}
|
||||||
|
assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var currencyStore: CurrenciesStore{}
|
||||||
|
readonly property var nonWatchWalletAcounts: SortFilterProxyModel {
|
||||||
|
sourceModel: walletAccountsModel
|
||||||
|
filters: ValueFilter { roleName: "canSend"; value: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
|
sourceModel: d.flatNetworks
|
||||||
|
filters: ValueFilter { roleName: "isTest"; value: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property ObjectProxyModel filteredBalancesModel: ObjectProxyModel {
|
||||||
|
sourceModel: d.assetsStore.groupedAccountAssetsModel
|
||||||
|
|
||||||
|
delegate: SortFilterProxyModel {
|
||||||
|
readonly property var balances: this
|
||||||
|
|
||||||
|
sourceModel: LeftJoinModel {
|
||||||
|
leftModel: model.balances
|
||||||
|
rightModel: d.filteredFlatNetworksModel
|
||||||
|
|
||||||
|
joinRole: "chainId"
|
||||||
|
}
|
||||||
|
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "chainId"
|
||||||
|
value: d.selectedNetworkChainId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedRoles: "balances"
|
||||||
|
exposedRoles: "balances"
|
||||||
|
}
|
||||||
|
|
||||||
|
property string selectedTokenKey: "ETH"
|
||||||
|
property int selectedNetworkChainId: 11155111
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: componentUnderTest
|
||||||
|
WalletAccountsSelectorAdaptor {
|
||||||
|
accounts: walletAccountsModel
|
||||||
|
assetsModel: d.assetsStore.groupedAccountAssetsModel
|
||||||
|
tokensBySymbolModel: d.assetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: d.filteredFlatNetworksModel
|
||||||
|
|
||||||
|
selectedTokenKey: d.selectedTokenKey
|
||||||
|
selectedNetworkChainId: d.selectedNetworkChainId
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: function(balance, symbol, decimals, options = null) {
|
||||||
|
return d.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property WalletAccountsSelectorAdaptor controlUnderTest: null
|
||||||
|
|
||||||
|
TestCase {
|
||||||
|
name: "WalletAccountsSelectorAdaptor"
|
||||||
|
when: windowShown
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_no_watchOnly_account() {
|
||||||
|
verify(!!controlUnderTest)
|
||||||
|
compare(controlUnderTest.processedWalletAccounts.count, d.nonWatchWalletAcounts.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_accountBalance_data() {
|
||||||
|
return [
|
||||||
|
{selectedTokenKey: "ETH", chainId: 11155111},
|
||||||
|
{selectedTokenKey: "STT", chainId: 11155111},
|
||||||
|
{selectedTokenKey: "ETH", chainId: 11155420},
|
||||||
|
{selectedTokenKey: "STT", chainId: 11155420}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_accountBalance(data) {
|
||||||
|
verify(!!controlUnderTest)
|
||||||
|
d.selectedTokenKey = data.selectedTokenKey
|
||||||
|
d.selectedNetworkChainId = data.chainId
|
||||||
|
let processedAccounts = controlUnderTest.processedWalletAccounts
|
||||||
|
for (let i = 0; i < processedAccounts.count; i++) {
|
||||||
|
let accountAddress = processedAccounts.get(i).address
|
||||||
|
let selectedTokenBalancesModel = ModelUtils.getByKey(d.filteredBalancesModel, "tokensKey", d.selectedTokenKey).balances
|
||||||
|
let tokenBalanceForSelectedAccount = ModelUtils.getByKey(selectedTokenBalancesModel, "account", accountAddress) ?? 0
|
||||||
|
let tokenBalanceForAccount = !!tokenBalanceForSelectedAccount ? tokenBalanceForSelectedAccount.balance: "0"
|
||||||
|
|
||||||
|
compare(tokenBalanceForAccount, processedAccounts.get(i).accountBalance.balance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
/**
|
||||||
|
Transforms and prepares the wallet accounts model to display
|
||||||
|
selected token on selected network
|
||||||
|
|
||||||
|
When no token or network is selected, only currency balance for account is shown.
|
||||||
|
*/
|
||||||
|
QObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// input api
|
||||||
|
|
||||||
|
/** Expected accounts model structure:
|
||||||
|
- name: name of the account
|
||||||
|
- address: address of the account,
|
||||||
|
- colorId: color id for the account,
|
||||||
|
- canSend: can send from acount ,
|
||||||
|
- position: position set by user in settings,
|
||||||
|
- currencyBalance: total currency balance in CurrencyAmount type,
|
||||||
|
- migratedToKeycard: if account is migrated to keycard.
|
||||||
|
*/
|
||||||
|
required property var accounts
|
||||||
|
/** Expected assets model structure:
|
||||||
|
- tokensKey: string -> unique string ID of the token (asset); e.g. "ETH" or contract address
|
||||||
|
- name: string -> user visible token name (e.g. "Ethereum")
|
||||||
|
- symbol: string -> user visible token symbol (e.g. "ETH")
|
||||||
|
- decimals: int -> number of decimal places
|
||||||
|
- communityId: string -> optional; ID of the community this token belongs to, if any
|
||||||
|
- marketDetails: var -> object containing props like `currencyPrice` for the computed values below
|
||||||
|
- balances: submodel -> [ chainId:int, account:string, balance:BigIntString, iconUrl:string ]
|
||||||
|
*/
|
||||||
|
required property var assetsModel
|
||||||
|
/** Expected token by symbol model structure:
|
||||||
|
- key: id for the token,
|
||||||
|
- name: name of the token,
|
||||||
|
- symbol: symbol of the token,
|
||||||
|
- decimals: decimals for the token
|
||||||
|
*/
|
||||||
|
required property var tokensBySymbolModel
|
||||||
|
/** Expected networks model structure:
|
||||||
|
- chainId: chain Id for network,
|
||||||
|
- chainName: name of network,
|
||||||
|
- iconUrl: icon representing the network,
|
||||||
|
*/
|
||||||
|
required property var filteredFlatNetworksModel
|
||||||
|
/** selectedTokenKey:
|
||||||
|
the selected token key
|
||||||
|
*/
|
||||||
|
required property string selectedTokenKey
|
||||||
|
/** selectedNetworkChainId:
|
||||||
|
the selected network chainId
|
||||||
|
*/
|
||||||
|
required property int selectedNetworkChainId
|
||||||
|
|
||||||
|
/** function to calculate token balance from BigInt:
|
||||||
|
the selected network chainId
|
||||||
|
*/
|
||||||
|
required property var fnFormatCurrencyAmountFromBigInt
|
||||||
|
|
||||||
|
/** output model
|
||||||
|
Computed processedWalletAccounts model addon values:
|
||||||
|
- accountBalance: balance of selected token on selected network along with network information
|
||||||
|
- filters out account that cant be used to send
|
||||||
|
*/
|
||||||
|
readonly property var processedWalletAccounts: SortFilterProxyModel {
|
||||||
|
sourceModel: root.accounts
|
||||||
|
delayed: true // Delayed to allow `processAccountBalance` dependencies to be resolved
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "canSend"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
sorters: [
|
||||||
|
RoleSorter { roleName: "currencyBalanceDouble"; sortOrder: Qt.DescendingOrder },
|
||||||
|
RoleSorter { roleName: "position"; sortOrder: Qt.AscendingOrder }
|
||||||
|
]
|
||||||
|
proxyRoles: [
|
||||||
|
FastExpressionRole {
|
||||||
|
name: "accountBalance"
|
||||||
|
expression: {
|
||||||
|
// dependencies
|
||||||
|
root.selectedTokenKey
|
||||||
|
root.selectedNetworkChainId
|
||||||
|
return d.processAccountBalance(model.address)
|
||||||
|
}
|
||||||
|
expectedRoles: ["address"]
|
||||||
|
},
|
||||||
|
FastExpressionRole {
|
||||||
|
name: "currencyBalanceDouble"
|
||||||
|
expression: model.currencyBalance.amount
|
||||||
|
expectedRoles: ["currencyBalance"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
readonly property ObjectProxyModel filteredBalancesModel: ObjectProxyModel {
|
||||||
|
sourceModel: root.assetsModel
|
||||||
|
|
||||||
|
delegate: SortFilterProxyModel {
|
||||||
|
readonly property var balances: this
|
||||||
|
|
||||||
|
sourceModel: LeftJoinModel {
|
||||||
|
leftModel: model.balances
|
||||||
|
rightModel: root.filteredFlatNetworksModel
|
||||||
|
|
||||||
|
joinRole: "chainId"
|
||||||
|
}
|
||||||
|
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "chainId"
|
||||||
|
value: root.selectedNetworkChainId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedRoles: "balances"
|
||||||
|
exposedRoles: "balances"
|
||||||
|
}
|
||||||
|
|
||||||
|
function processAccountBalance(address) {
|
||||||
|
let selectedToken = ModelUtils.getByKey(root.tokensBySymbolModel, "key", root.selectedTokenKey)
|
||||||
|
if (!selectedToken) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let network = ModelUtils.getByKey(root.filteredFlatNetworksModel, "chainId", root.selectedNetworkChainId)
|
||||||
|
if (!network) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let balancesModel = ModelUtils.getByKey(filteredBalancesModel, "tokensKey", root.selectedTokenKey, "balances")
|
||||||
|
let accountBalance = ModelUtils.getByKey(balancesModel, "account", address)
|
||||||
|
if(accountBalance && accountBalance.balance !== "0") {
|
||||||
|
accountBalance.formattedBalance = root.fnFormatCurrencyAmountFromBigInt(accountBalance.balance, selectedToken.symbol, selectedToken.decimals)
|
||||||
|
return accountBalance
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
balance: "0",
|
||||||
|
iconUrl: network.iconUrl,
|
||||||
|
chainColor: network.chainColor,
|
||||||
|
formattedBalance: "0 %1".arg(selectedToken.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
CollectiblesSelectionAdaptor 1.0 CollectiblesSelectionAdaptor.qml
|
CollectiblesSelectionAdaptor 1.0 CollectiblesSelectionAdaptor.qml
|
||||||
TokenSelectorViewAdaptor 1.0 TokenSelectorViewAdaptor.qml
|
TokenSelectorViewAdaptor 1.0 TokenSelectorViewAdaptor.qml
|
||||||
|
WalletAccountsSelectorAdaptor 1.0 WalletAccountsSelectorAdaptor.qml
|
||||||
|
@ -23,9 +23,6 @@ StatusDialog {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
/**
|
/**
|
||||||
TODO: use the newly defined WalletAccountsSelectorAdaptor
|
|
||||||
in https://github.com/status-im/status-desktop/pull/16834
|
|
||||||
This will also remove watch only accounts from the list
|
|
||||||
Expected model structure:
|
Expected model structure:
|
||||||
- name: name of account
|
- name: name of account
|
||||||
- address: wallet address
|
- address: wallet address
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import QtQml.Models 2.15
|
import QtQml.Models 2.15
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
|
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.Backpressure 0.1
|
import StatusQ.Core.Backpressure 0.1
|
||||||
@ -18,6 +20,7 @@ import shared.panels 1.0
|
|||||||
import AppLayouts.Wallet.controls 1.0
|
import AppLayouts.Wallet.controls 1.0
|
||||||
import AppLayouts.Wallet.panels 1.0
|
import AppLayouts.Wallet.panels 1.0
|
||||||
import AppLayouts.Wallet.popups.buy 1.0
|
import AppLayouts.Wallet.popups.buy 1.0
|
||||||
|
import AppLayouts.Wallet.adaptors 1.0
|
||||||
|
|
||||||
StatusDialog {
|
StatusDialog {
|
||||||
id: root
|
id: root
|
||||||
@ -58,11 +61,37 @@ StatusDialog {
|
|||||||
selectedTokenKey: root.swapInputParamsForm.fromTokensKey
|
selectedTokenKey: root.swapInputParamsForm.fromTokensKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property WalletAccountsSelectorAdaptor accountsSelectorAdaptor : WalletAccountsSelectorAdaptor {
|
||||||
|
accounts: root.swapAdaptor.swapStore.accounts
|
||||||
|
assetsModel: root.swapAdaptor.walletAssetsStore.baseGroupedAccountAssetModel
|
||||||
|
tokensBySymbolModel: root.swapAdaptor.walletAssetsStore.walletTokensStore.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
|
sourceModel: root.swapAdaptor.swapStore.flatNetworks
|
||||||
|
filters: ValueFilter { roleName: "isTest"; value: root.swapAdaptor.swapStore.areTestNetworksEnabled }
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTokenKey: root.swapInputParamsForm.fromTokensKey
|
||||||
|
selectedNetworkChainId: root.swapInputParamsForm.selectedNetworkChainId
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: function(balance, symbol, decimals, options = null) {
|
||||||
|
return root.swapAdaptor.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var selectedAccount: selectedAccountEntry.item
|
||||||
|
|
||||||
function addMetricsEvent(subEventName) {
|
function addMetricsEvent(subEventName) {
|
||||||
Global.addCentralizedMetricIfEnabled("swap", {subEvent: subEventName})
|
Global.addCentralizedMetricIfEnabled("swap", {subEvent: subEventName})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelEntry {
|
||||||
|
id: selectedAccountEntry
|
||||||
|
sourceModel: d.accountsSelectorAdaptor.processedWalletAccounts
|
||||||
|
key: "address"
|
||||||
|
value: root.swapInputParamsForm.selectedAccountAddress
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.swapInputParamsForm
|
target: root.swapInputParamsForm
|
||||||
function onFormValuesChanged() {
|
function onFormValuesChanged() {
|
||||||
@ -109,7 +138,7 @@ StatusDialog {
|
|||||||
AccountSelectorHeader {
|
AccountSelectorHeader {
|
||||||
id: selector
|
id: selector
|
||||||
control.popup.width: 512
|
control.popup.width: 512
|
||||||
model: root.swapAdaptor.nonWatchAccounts
|
model: d.accountsSelectorAdaptor.processedWalletAccounts
|
||||||
selectedAddress: root.swapInputParamsForm.selectedAccountAddress
|
selectedAddress: root.swapInputParamsForm.selectedAccountAddress
|
||||||
onCurrentAccountAddressChanged: {
|
onCurrentAccountAddressChanged: {
|
||||||
if (currentAccountAddress !== "" && currentAccountAddress !== root.swapInputParamsForm.selectedAccountAddress) {
|
if (currentAccountAddress !== "" && currentAccountAddress !== root.swapInputParamsForm.selectedAccountAddress) {
|
||||||
@ -409,7 +438,7 @@ StatusDialog {
|
|||||||
objectName: "signButton"
|
objectName: "signButton"
|
||||||
readonly property string fromTokenSymbol: !!root.swapAdaptor.fromToken ? root.swapAdaptor.fromToken.symbol ?? "" : ""
|
readonly property string fromTokenSymbol: !!root.swapAdaptor.fromToken ? root.swapAdaptor.fromToken.symbol ?? "" : ""
|
||||||
loadingWithText: root.swapAdaptor.approvalPending
|
loadingWithText: root.swapAdaptor.approvalPending
|
||||||
icon.name: root.swapAdaptor.selectedAccount.migratedToKeycard ? Constants.authenticationIconByType[Constants.LoginType.Keycard]
|
icon.name: d.selectedAccount.migratedToKeycard ? Constants.authenticationIconByType[Constants.LoginType.Keycard]
|
||||||
: Constants.authenticationIconByType[root.loginType]
|
: Constants.authenticationIconByType[root.loginType]
|
||||||
text: {
|
text: {
|
||||||
if(root.swapAdaptor.validSwapProposalReceived) {
|
if(root.swapAdaptor.validSwapProposalReceived) {
|
||||||
@ -461,7 +490,7 @@ StatusDialog {
|
|||||||
|
|
||||||
formatBigNumber: (number, symbol, noSymbolOption) => root.swapAdaptor.currencyStore.formatBigNumber(number, symbol, noSymbolOption)
|
formatBigNumber: (number, symbol, noSymbolOption) => root.swapAdaptor.currencyStore.formatBigNumber(number, symbol, noSymbolOption)
|
||||||
|
|
||||||
loginType: root.swapAdaptor.selectedAccount.migratedToKeycard ? Constants.LoginType.Keycard : root.loginType
|
loginType: d.selectedAccount.migratedToKeycard ? Constants.LoginType.Keycard : root.loginType
|
||||||
feesLoading: root.swapAdaptor.swapProposalLoading
|
feesLoading: root.swapAdaptor.swapProposalLoading
|
||||||
|
|
||||||
fromTokenSymbol: root.swapAdaptor.fromToken.symbol
|
fromTokenSymbol: root.swapAdaptor.fromToken.symbol
|
||||||
@ -470,11 +499,11 @@ StatusDialog {
|
|||||||
"chainId", root.swapInputParamsForm.selectedNetworkChainId,
|
"chainId", root.swapInputParamsForm.selectedNetworkChainId,
|
||||||
"address")
|
"address")
|
||||||
|
|
||||||
accountName: root.swapAdaptor.selectedAccount.name
|
accountName: d.selectedAccount.name
|
||||||
accountAddress: root.swapAdaptor.selectedAccount.address
|
accountAddress: d.selectedAccount.address
|
||||||
accountEmoji: root.swapAdaptor.selectedAccount.emoji
|
accountEmoji: d.selectedAccount.emoji
|
||||||
accountColor: Utils.getColorForId(root.swapAdaptor.selectedAccount.colorId)
|
accountColor: Utils.getColorForId(d.selectedAccount.colorId)
|
||||||
accountBalanceFormatted: root.swapAdaptor.selectedAccount.accountBalance.formattedBalance
|
accountBalanceFormatted: d.selectedAccount.accountBalance.formattedBalance
|
||||||
|
|
||||||
networkShortName: networkFilter.singleSelectionItemData.shortName
|
networkShortName: networkFilter.singleSelectionItemData.shortName
|
||||||
networkName: networkFilter.singleSelectionItemData.chainName
|
networkName: networkFilter.singleSelectionItemData.chainName
|
||||||
@ -513,7 +542,7 @@ StatusDialog {
|
|||||||
|
|
||||||
formatBigNumber: (number, symbol, noSymbolOption) => root.swapAdaptor.currencyStore.formatBigNumber(number, symbol, noSymbolOption)
|
formatBigNumber: (number, symbol, noSymbolOption) => root.swapAdaptor.currencyStore.formatBigNumber(number, symbol, noSymbolOption)
|
||||||
|
|
||||||
loginType: root.swapAdaptor.selectedAccount.migratedToKeycard ? Constants.LoginType.Keycard : root.loginType
|
loginType: d.selectedAccount.migratedToKeycard ? Constants.LoginType.Keycard : root.loginType
|
||||||
feesLoading: root.swapAdaptor.swapProposalLoading
|
feesLoading: root.swapAdaptor.swapProposalLoading
|
||||||
|
|
||||||
fromTokenSymbol: root.swapAdaptor.fromToken.symbol
|
fromTokenSymbol: root.swapAdaptor.fromToken.symbol
|
||||||
@ -528,10 +557,10 @@ StatusDialog {
|
|||||||
"chainId", root.swapInputParamsForm.selectedNetworkChainId,
|
"chainId", root.swapInputParamsForm.selectedNetworkChainId,
|
||||||
"address")
|
"address")
|
||||||
|
|
||||||
accountName: root.swapAdaptor.selectedAccount.name
|
accountName: d.selectedAccount.name
|
||||||
accountAddress: root.swapAdaptor.selectedAccount.address
|
accountAddress: d.selectedAccount.address
|
||||||
accountEmoji: root.swapAdaptor.selectedAccount.emoji
|
accountEmoji: d.selectedAccount.emoji
|
||||||
accountColor: Utils.getColorForId(root.swapAdaptor.selectedAccount.colorId)
|
accountColor: Utils.getColorForId(d.selectedAccount.colorId)
|
||||||
|
|
||||||
networkShortName: networkFilter.singleSelectionItemData.shortName
|
networkShortName: networkFilter.singleSelectionItemData.shortName
|
||||||
networkName: networkFilter.singleSelectionItemData.chainName
|
networkName: networkFilter.singleSelectionItemData.chainName
|
||||||
|
@ -33,51 +33,9 @@ QObject {
|
|||||||
// To expose the selected from and to Token from the SwapModal
|
// To expose the selected from and to Token from the SwapModal
|
||||||
readonly property var fromToken: fromTokenEntry.item
|
readonly property var fromToken: fromTokenEntry.item
|
||||||
readonly property var toToken: toTokenEntry.item
|
readonly property var toToken: toTokenEntry.item
|
||||||
readonly property var selectedAccount: selectedAccountEntry.item
|
|
||||||
|
|
||||||
readonly property string uuid: d.uuid
|
readonly property string uuid: d.uuid
|
||||||
|
|
||||||
// TO REVIEW: Handle this in a separate `WalletAccountsAdaptor.qml` file.
|
|
||||||
// Probably this data transformation should live there since they have common base.
|
|
||||||
readonly property var nonWatchAccounts: SortFilterProxyModel {
|
|
||||||
sourceModel: root.swapStore.accounts
|
|
||||||
delayed: true // Delayed to allow `processAccountBalance` dependencies to be resolved
|
|
||||||
filters: ValueFilter {
|
|
||||||
roleName: "canSend"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
sorters: [
|
|
||||||
RoleSorter { roleName: "currencyBalanceDouble"; sortOrder: Qt.DescendingOrder },
|
|
||||||
RoleSorter { roleName: "position"; sortOrder: Qt.AscendingOrder }
|
|
||||||
]
|
|
||||||
proxyRoles: [
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "accountBalance"
|
|
||||||
expression: {
|
|
||||||
// dependencies
|
|
||||||
root.swapFormData.fromTokensKey
|
|
||||||
root.fromToken
|
|
||||||
root.fromToken.symbol
|
|
||||||
root.fromToken.decimals
|
|
||||||
root.swapFormData.selectedNetworkChainId
|
|
||||||
root.swapFormData.fromTokensKey
|
|
||||||
|
|
||||||
return d.processAccountBalance(model.address)
|
|
||||||
}
|
|
||||||
expectedRoles: ["address"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "currencyBalanceDouble"
|
|
||||||
expression: model.currencyBalance.amount
|
|
||||||
expectedRoles: ["currencyBalance"]
|
|
||||||
},
|
|
||||||
FastExpressionRole {
|
|
||||||
name: "fromToken"
|
|
||||||
expression: root.fromToken
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property SortFilterProxyModel filteredFlatNetworksModel: SortFilterProxyModel {
|
readonly property SortFilterProxyModel filteredFlatNetworksModel: SortFilterProxyModel {
|
||||||
sourceModel: root.swapStore.flatNetworks
|
sourceModel: root.swapStore.flatNetworks
|
||||||
filters: ValueFilter { roleName: "isTest"; value: root.swapStore.areTestNetworksEnabled }
|
filters: ValueFilter { roleName: "isTest"; value: root.swapStore.areTestNetworksEnabled }
|
||||||
@ -94,55 +52,6 @@ QObject {
|
|||||||
// storing txHash to verify against tx completed event
|
// storing txHash to verify against tx completed event
|
||||||
property string txHash
|
property string txHash
|
||||||
|
|
||||||
readonly property ObjectProxyModel filteredBalancesModel: ObjectProxyModel {
|
|
||||||
sourceModel: root.walletAssetsStore.baseGroupedAccountAssetModel
|
|
||||||
|
|
||||||
delegate: SortFilterProxyModel {
|
|
||||||
readonly property var balances: this
|
|
||||||
|
|
||||||
sourceModel: LeftJoinModel {
|
|
||||||
leftModel: model.balances
|
|
||||||
rightModel: root.swapStore.flatNetworks
|
|
||||||
|
|
||||||
joinRole: "chainId"
|
|
||||||
}
|
|
||||||
|
|
||||||
filters: ValueFilter {
|
|
||||||
roleName: "chainId"
|
|
||||||
value: root.swapFormData.selectedNetworkChainId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedRoles: "balances"
|
|
||||||
exposedRoles: "balances"
|
|
||||||
}
|
|
||||||
|
|
||||||
function processAccountBalance(address) {
|
|
||||||
if (!root.swapFormData.fromTokensKey || !root.fromToken) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
let network = ModelUtils.getByKey(root.filteredFlatNetworksModel, "chainId", root.swapFormData.selectedNetworkChainId)
|
|
||||||
|
|
||||||
if (!network) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
let balancesModel = ModelUtils.getByKey(filteredBalancesModel, "tokensKey", root.swapFormData.fromTokensKey, "balances")
|
|
||||||
let accountBalance = ModelUtils.getByKey(balancesModel, "account", address)
|
|
||||||
if(accountBalance && accountBalance.balance !== "0") {
|
|
||||||
accountBalance.formattedBalance = root.formatCurrencyAmountFromBigInt(accountBalance.balance, root.fromToken.symbol, root.fromToken.decimals)
|
|
||||||
return accountBalance
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
balance: "0",
|
|
||||||
iconUrl: network.iconUrl,
|
|
||||||
chainColor: network.chainColor,
|
|
||||||
formattedBalance: "0 %1".arg(root.fromToken.symbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties to handle error states
|
// Properties to handle error states
|
||||||
readonly property bool isRouteEthBalanceInsufficient: root.validSwapProposalReceived && root.swapOutputData.errCode === Constants.routerErrorCodes.router.errNotEnoughNativeBalance
|
readonly property bool isRouteEthBalanceInsufficient: root.validSwapProposalReceived && root.swapOutputData.errCode === Constants.routerErrorCodes.router.errNotEnoughNativeBalance
|
||||||
|
|
||||||
@ -209,13 +118,6 @@ QObject {
|
|||||||
value: root.swapFormData.toTokenKey
|
value: root.swapFormData.toTokenKey
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelEntry {
|
|
||||||
id: selectedAccountEntry
|
|
||||||
sourceModel: root.nonWatchAccounts
|
|
||||||
key: "address"
|
|
||||||
value: root.swapFormData.selectedAccountAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.swapStore
|
target: root.swapStore
|
||||||
function onSuggestedRoutesReady(txRoutes, errCode, errDescription) {
|
function onSuggestedRoutesReady(txRoutes, errCode, errDescription) {
|
||||||
@ -284,14 +186,6 @@ QObject {
|
|||||||
d.txHash = ""
|
d.txHash = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatCurrencyAmount(balance, symbol, options = null, locale = null) {
|
|
||||||
return root.currencyStore.formatCurrencyAmount(balance, symbol, options, locale)
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatCurrencyAmountFromBigInt(balance, symbol, decimals, options = null) {
|
|
||||||
return root.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDisabledChainIds(enabledChainId) {
|
function getDisabledChainIds(enabledChainId) {
|
||||||
let disabledChainIds = []
|
let disabledChainIds = []
|
||||||
let chainIds = ModelUtils.modelToFlatArray(root.filteredFlatNetworksModel, "chainId")
|
let chainIds = ModelUtils.modelToFlatArray(root.filteredFlatNetworksModel, "chainId")
|
||||||
|
@ -668,21 +668,22 @@ Item {
|
|||||||
flatNetworksModel: WalletStores.RootStore.flatNetworks
|
flatNetworksModel: WalletStores.RootStore.flatNetworks
|
||||||
areTestNetworksEnabled: WalletStores.RootStore.areTestNetworksEnabled
|
areTestNetworksEnabled: WalletStores.RootStore.areTestNetworksEnabled
|
||||||
groupedAccountAssetsModel: appMain.walletAssetsStore.groupedAccountAssetsModel
|
groupedAccountAssetsModel: appMain.walletAssetsStore.groupedAccountAssetsModel
|
||||||
currentCurrency: appMain.currencyStore.currentCurrency
|
plainTokensBySymbolModel: appMain.tokensStore.plainTokensBySymbolModel
|
||||||
showCommunityAssetsInSend: appMain.tokensStore.showCommunityAssetsInSend
|
showCommunityAssetsInSend: appMain.tokensStore.showCommunityAssetsInSend
|
||||||
collectiblesBySymbolModel: WalletStores.RootStore.collectiblesStore.jointCollectiblesBySymbolModel
|
collectiblesBySymbolModel: WalletStores.RootStore.collectiblesStore.jointCollectiblesBySymbolModel
|
||||||
tokenBySymbolModel: appMain.tokensStore.plainTokensBySymbolModel
|
tokenBySymbolModel: appMain.tokensStore.plainTokensBySymbolModel
|
||||||
fnFormatCurrencyAmount: function(amount, symbol, options = null, locale = null) {
|
savedAddressesModel: WalletStores.RootStore.savedAddresses
|
||||||
return appMain.currencyStore.formatCurrencyAmount(amount, symbol)
|
recentRecipientsModel: appMain.transactionStore.tempActivityController1Model
|
||||||
}
|
|
||||||
|
currentCurrency: appMain.currencyStore.currentCurrency
|
||||||
|
fnFormatCurrencyAmount: appMain.currencyStore.formatCurrencyAmount
|
||||||
|
fnFormatCurrencyAmountFromBigInt: appMain.currencyStore.formatCurrencyAmountFromBigInt
|
||||||
|
|
||||||
// TODO remove this call to mainModule under #16919
|
// TODO remove this call to mainModule under #16919
|
||||||
fnResolveENS: function(ensName, uuid) {
|
fnResolveENS: function(ensName, uuid) {
|
||||||
mainModule.resolveENS(name, uuid)
|
mainModule.resolveENS(name, uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
savedAddressesModel: WalletStores.RootStore.savedAddresses
|
|
||||||
recentRecipientsModel: appMain.transactionStore.tempActivityController1Model
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
// It's requested from many nested places, so as a workaround we use
|
// It's requested from many nested places, so as a workaround we use
|
||||||
// Global to shorten the path via global signal.
|
// Global to shorten the path via global signal.
|
||||||
|
@ -41,8 +41,6 @@ QtObject {
|
|||||||
|
|
||||||
/** For simple send modal flows, decoupling from transaction store **/
|
/** For simple send modal flows, decoupling from transaction store **/
|
||||||
|
|
||||||
/** curently selected fiat currency symbol **/
|
|
||||||
required property string currentCurrency
|
|
||||||
/** Expected model structure:
|
/** Expected model structure:
|
||||||
- name: name of account
|
- name: name of account
|
||||||
- address: wallet address
|
- address: wallet address
|
||||||
@ -62,6 +60,13 @@ QtObject {
|
|||||||
- balances: submodel[ chainId:int, account:string, balance:BigIntString, iconUrl:string ]
|
- balances: submodel[ chainId:int, account:string, balance:BigIntString, iconUrl:string ]
|
||||||
**/
|
**/
|
||||||
required property var groupedAccountAssetsModel
|
required property var groupedAccountAssetsModel
|
||||||
|
/** Expected token by symbol model structure:
|
||||||
|
- key: id for the token,
|
||||||
|
- name: name of the token,
|
||||||
|
- symbol: symbol of the token,
|
||||||
|
- decimals: decimals for the token
|
||||||
|
*/
|
||||||
|
required property var plainTokensBySymbolModel
|
||||||
/** Expected model structure:
|
/** Expected model structure:
|
||||||
- symbol [string] - unique identifier of a collectible
|
- symbol [string] - unique identifier of a collectible
|
||||||
- collectionUid [string] - unique identifier of a collection
|
- collectionUid [string] - unique identifier of a collection
|
||||||
@ -96,8 +101,6 @@ QtObject {
|
|||||||
/** whether community tokens are shown in send modal
|
/** whether community tokens are shown in send modal
|
||||||
based on a global setting **/
|
based on a global setting **/
|
||||||
required property bool showCommunityAssetsInSend
|
required property bool showCommunityAssetsInSend
|
||||||
/** required function to format currency amount to locale string **/
|
|
||||||
required property var fnFormatCurrencyAmount
|
|
||||||
|
|
||||||
required property var savedAddressesModel
|
required property var savedAddressesModel
|
||||||
required property var recentRecipientsModel
|
required property var recentRecipientsModel
|
||||||
@ -107,6 +110,13 @@ QtObject {
|
|||||||
/** required signal to receive resolved ens name address **/
|
/** required signal to receive resolved ens name address **/
|
||||||
signal ensNameResolved(string resolvedPubKey, string resolvedAddress, string uuid)
|
signal ensNameResolved(string resolvedPubKey, string resolvedAddress, string uuid)
|
||||||
|
|
||||||
|
/** curently selected fiat currency symbol **/
|
||||||
|
required property string currentCurrency
|
||||||
|
/** required function to format currency amount to locale string **/
|
||||||
|
required property var fnFormatCurrencyAmount
|
||||||
|
/** required function to format to currency amount from big int **/
|
||||||
|
required property var fnFormatCurrencyAmountFromBigInt
|
||||||
|
|
||||||
function openSend(params = {}) {
|
function openSend(params = {}) {
|
||||||
// TODO remove once simple send is feature complete
|
// TODO remove once simple send is feature complete
|
||||||
let sendModalCmp = root.simpleSendEnabled ? simpleSendModalComponent: sendModalComponent
|
let sendModalCmp = root.simpleSendEnabled ? simpleSendModalComponent: sendModalComponent
|
||||||
@ -243,14 +253,13 @@ QtObject {
|
|||||||
SimpleSendModal {
|
SimpleSendModal {
|
||||||
id: simpleSendModal
|
id: simpleSendModal
|
||||||
|
|
||||||
/** TODO: use the newly defined WalletAccountsSelectorAdaptor
|
accountsModel: backendHandler.accountsSelectorAdaptor.processedWalletAccounts
|
||||||
in https://github.com/status-im/status-desktop/pull/16834 **/
|
|
||||||
accountsModel: root.walletAccountsModel
|
|
||||||
assetsModel: backendHandler.assetsSelectorViewAdaptor.outputAssetsModel
|
assetsModel: backendHandler.assetsSelectorViewAdaptor.outputAssetsModel
|
||||||
collectiblesModel: backendHandler.collectiblesSelectionAdaptor.model
|
collectiblesModel: backendHandler.collectiblesSelectionAdaptor.model
|
||||||
networksModel: backendHandler.filteredFlatNetworksModel
|
networksModel: backendHandler.filteredFlatNetworksModel
|
||||||
savedAddressesModel: root.savedAddressesModel
|
savedAddressesModel: root.savedAddressesModel
|
||||||
recentRecipientsModel: root.recentRecipientsModel
|
recentRecipientsModel: root.recentRecipientsModel
|
||||||
|
|
||||||
currentCurrency: root.currentCurrency
|
currentCurrency: root.currentCurrency
|
||||||
fnFormatCurrencyAmount: root.fnFormatCurrencyAmount
|
fnFormatCurrencyAmount: root.fnFormatCurrencyAmount
|
||||||
fnResolveENS: root.fnResolveENS
|
fnResolveENS: root.fnResolveENS
|
||||||
@ -315,6 +324,18 @@ QtObject {
|
|||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property var accountsSelectorAdaptor: WalletAccountsSelectorAdaptor {
|
||||||
|
accounts: root.walletAccountsModel
|
||||||
|
assetsModel: root.groupedAccountAssetsModel
|
||||||
|
tokensBySymbolModel: root.plainTokensBySymbolModel
|
||||||
|
filteredFlatNetworksModel: backendHandler.filteredFlatNetworksModel
|
||||||
|
|
||||||
|
selectedTokenKey: simpleSendModal.selectedTokenKey
|
||||||
|
selectedNetworkChainId: simpleSendModal.selectedChainId
|
||||||
|
|
||||||
|
fnFormatCurrencyAmountFromBigInt: root.fnFormatCurrencyAmountFromBigInt
|
||||||
|
}
|
||||||
|
|
||||||
readonly property var assetsSelectorViewAdaptor: TokenSelectorViewAdaptor {
|
readonly property var assetsSelectorViewAdaptor: TokenSelectorViewAdaptor {
|
||||||
// TODO: remove all store dependecies and add specific properties to the handler instead
|
// TODO: remove all store dependecies and add specific properties to the handler instead
|
||||||
assetsModel: root.groupedAccountAssetsModel
|
assetsModel: root.groupedAccountAssetsModel
|
||||||
|
Loading…
x
Reference in New Issue
Block a user