refactor(Wallet/SendModal): Created `WalletAccountsAdaptor` to be used in `SendModal`

- Created data transformation file called `WalletAccountsAdaptor` for `SendModal`. Now it contains the owned wallet accounts model data transformations.
- Added common formatting method for short chain ids to some utils and partially removed backend dependency.
This commit is contained in:
Noelia 2024-07-03 22:46:00 +02:00 committed by Noelia
parent 18e230bf91
commit bc74724672
12 changed files with 150 additions and 37 deletions

View File

@ -170,6 +170,7 @@ QtObject:
return (chainIds, enable)
# TODO: To be removed once all qml calls to this method are removed. Normally the formatting methods should live in the qml project.
proc getNetworkShortNames*(self: Model, preferredNetworks: string, areTestNetworksEnabled: bool): string =
var networkString = ""
let networks = preferredNetworks.split(":")

View File

@ -18,7 +18,6 @@ import Models 1.0
import Storybook 1.0
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.stores 1.0 as WalletStores
import AppLayouts.Wallet.services.dapps 1.0
import SortFilterProxyModel 0.2
@ -373,7 +372,7 @@ Item {
}
}
walletRootStore: WalletStores.RootStore {
walletRootStore: QObject {
property string selectedAddress: ""
property var filteredFlatModel: SortFilterProxyModel {
sourceModel: NetworksModel.flatNetworks

View File

@ -14,7 +14,6 @@ import AppLayouts.Wallet.services.dapps 1.0
import AppLayouts.Wallet.services.dapps.types 1.0
import AppLayouts.Profile.stores 1.0
import AppLayouts.Wallet.panels 1.0
import AppLayouts.Wallet.stores 1.0 as WalletStores
import shared.stores 1.0
@ -121,7 +120,7 @@ Item {
Component {
id: walletStoreComponent
WalletStores.RootStore {
QtObject {
property string selectedAddress: ""
readonly property ListModel filteredFlatModel: ListModel {
ListElement { chainId: 1 }

View File

@ -261,7 +261,7 @@ Item {
mouseMove(delegateUnderTest, delegateUnderTest.width/2, delegateUnderTest.height/2)
verify(delegateUnderTest.sensor.containsMouse)
compare(delegateUnderTest.title, swapAdaptor.nonWatchAccounts.get(i).name)
compare(delegateUnderTest.subTitle, WalletUtils.colorizedChainPrefix(root.swapAdaptor.getNetworkShortNames(swapAdaptor.nonWatchAccounts.get(i).preferredSharingChainIds)), "Randomly failing locally. Add a bug if you see this failing in CI")
compare(delegateUnderTest.subTitle, WalletUtils.colorizedChainPrefix(WalletUtils.getNetworkShortNames(swapAdaptor.nonWatchAccounts.get(i).preferredSharingChainIds, root.swapStore.flatNetworks)), "Randomly failing locally. Add a bug if you see this failing in CI")
verify(delegateUnderTest.color, Theme.palette.baseColor2)
}

View File

@ -1,5 +1,13 @@
// This should not be a singleton. TODO: Remove it once the "real" Wallet root store is not a singleton anymore.
pragma Singleton
import QtQml 2.15
QtObject {
id: root
// TODO: Remove this. This stub should be empty. The color transformation should be done in adaptors or in the first model transformation steps.
function colorForChainShortName(chainShortName) {
return "#FF0000" // Just some random testing color
}
}

View File

@ -1,6 +1,6 @@
ActivityFiltersStore 1.0 ActivityFiltersStore.qml
CollectiblesStore 1.0 CollectiblesStore.qml
RootStore 1.0 RootStore.qml
singleton RootStore 1.0 RootStore.qml
SwapStore 1.0 SwapStore.qml
TokensStore 1.0 TokensStore.qml
WalletAssetsStore 1.0 WalletAssetsStore.qml

View File

@ -7,9 +7,39 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import "stores" as WalletStores
import AppLayouts.Wallet.stores 1.0 as WalletStores
QtObject {
function colorizedChainPrefixNew(chainColors, prefix) {
if (!prefix)
return ""
const prefixes = prefix.split(":").filter(Boolean)
let prefixStr = ""
const lastPrefixEndsWithColumn = prefix.endsWith(":")
const defaultColor = Theme.palette.baseColor1
for (let i in prefixes) {
const pref = prefixes[i]
let col = chainColors[pref]
if (!col)
col = defaultColor
prefixStr += Utils.richColorText(pref, col)
// Avoid adding ":" if it was not there for the last prefix,
// because when user manually edits the address, it breaks editing
if (!(i === (prefixes.length - 1) && !lastPrefixEndsWithColumn)) {
prefixStr += Utils.richColorText(":", Theme.palette.baseColor1)
}
}
return prefixStr
}
// TODO: Remove dependency to RootStore by requesting model or chainColors as a parameter. Indeed, this
// method should be just replaced by `colorizedChainPrefixNew`
// Issue #15494
function colorizedChainPrefix(prefix) {
if (!prefix)
return ""
@ -28,7 +58,7 @@ QtObject {
prefixStr += Utils.richColorText(pref, col)
// Avoid adding ":" if it was not there for the last prefix,
// because when user manually edits the address, it breaks editing
if (!(i == (prefixes.length - 1) && !lastPrefixEndsWithColumn)) {
if (!(i === (prefixes.length - 1) && !lastPrefixEndsWithColumn)) {
prefixStr += Utils.richColorText(":", Theme.palette.baseColor1)
}
}
@ -88,4 +118,16 @@ QtObject {
return qsTr("> 5 minutes")
}
}
// Where: chainIds [string] - separated by `:`, e.g "42161:10:1"
function getNetworkShortNames(chainIds: string, flatNetworksModel) {
let networkString = ""
const chainIdsArray = chainIds.split(":")
for (let i = 0; i < chainIdsArray.length; i++) {
const nwShortName = StatusQUtils.ModelUtils.getByKey(flatNetworksModel, "chainId", Number(chainIdsArray[i]), "shortName")
if (!!nwShortName)
networkString = networkString + nwShortName + ':'
}
return networkString
}
}

View File

@ -0,0 +1,80 @@
import QtQml 2.15
import AppLayouts.Wallet 1.0
import StatusQ 0.1
import StatusQ.Core.Utils 0.1
import SortFilterProxyModel 0.2
QObject {
id: root
// Input parameters:
/**
Expected model structure:
address [string] - wallet account address, e.g "0x10b...eaf"
name [string] - wallet account name, e.g "Status account"
keyUid [string] - unique identifier, e.g "0x79e07.....006"
currencyBalance [var] - CurrencyAmount type
amount [string]
symbol [string]
displayDecimals [int]
stripTrailingZeroes [bool]
emoji [string] - custom emoji
walletType [string] - e.g "generated"
colorId [string] - e.g "YELLOW"
preferredSharingChainIds [string] - separated by `:`, e.g "42161:10:1"
position [int] - visual order, e.g: "1"
**/
property var accountsModel
property var flatNetworksModel
property bool areTestNetworksEnabled
// Output parameters:
/**
Model structure:
All roles from the source model are passed directly to the output model,
additionally:
colorizedChainShortNames [string] - build from `preferredSharingChainIds` adding different colors to different network short names
**/
readonly property alias model: sfpm
readonly property SortFilterProxyModel filteredFlatNetworksModel: SortFilterProxyModel {
sourceModel: root.flatNetworksModel
filters: ValueFilter { roleName: "isTest"; value: root.areTestNetworksEnabled }
}
QtObject {
id: d
property var chainColors: ({})
function initChainColors() {
for (let i = 0; i < root.flatNetworksModel.count; i++) {
const item = ModelUtils.get(root.flatNetworksModel, i)
chainColors[item.shortName] = item.chainColor
}
}
}
SortFilterProxyModel {
id: sfpm
sourceModel: root.accountsModel ?? null
proxyRoles: FastExpressionRole {
function getChainShortNames(preferredSharingChainIds){
const chainShortNames = WalletUtils.getNetworkShortNames(preferredSharingChainIds, root.flatNetworksModel)
return WalletUtils.colorizedChainPrefixNew(d.chainColors, chainShortNames)
}
name: "colorizedChainShortNames"
expectedRoles: ["preferredSharingChainIds"]
expression: getChainShortNames(model.preferredSharingChainIds)
}
}
onFlatNetworksModelChanged: d.initChainColors()
}

View File

@ -1,2 +1,3 @@
CollectiblesSelectionAdaptor 1.0 CollectiblesSelectionAdaptor.qml
TokenSelectorViewAdaptor 1.0 TokenSelectorViewAdaptor.qml
WalletAccountsAdaptor 1.0 WalletAccountsAdaptor.qml

View File

@ -33,6 +33,8 @@ QObject {
readonly property string uuid: d.uuid
// TO REVIEW: It has been created a `WalletAccountsAdaptor.qml` file.
// Probably this data transformation should live there since they have common base.
readonly property var nonWatchAccounts: SortFilterProxyModel {
sourceModel: root.swapStore.accounts
filters: ValueFilter {
@ -62,7 +64,7 @@ QObject {
FastExpressionRole {
name: "colorizedChainPrefixes"
function getChainShortNames(chainIds) {
const chainShortNames = root.getNetworkShortNames(chainIds)
const chainShortNames = WalletUtils.getNetworkShortNames(chainIds, root.filteredFlatNetworksModel)
return WalletUtils.colorizedChainPrefix(chainShortNames)
}
expression: getChainShortNames(model.preferredSharingChainIds)
@ -217,18 +219,6 @@ QObject {
d.txHash = ""
}
function getNetworkShortNames(chainIds) {
var networkString = ""
let chainIdsArray = chainIds.split(":")
for (let i = 0; i< chainIdsArray.length; i++) {
let nwShortName = ModelUtils.getByKey(root.filteredFlatNetworksModel, "chainId", Number(chainIdsArray[i]), "shortName")
if(!!nwShortName) {
networkString = networkString + nwShortName + ':'
}
}
return networkString
}
function formatCurrencyAmount(balance, symbol, options = null, locale = null) {
return root.currencyStore.formatCurrencyAmount(balance, symbol, options, locale)
}

View File

@ -5,7 +5,6 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import AppLayouts.Wallet 1.0
import AppLayouts.Wallet.stores 1.0 as WalletStores
import AppLayouts.Wallet.services.dapps 1.0
import AppLayouts.Wallet.services.dapps.types 1.0
import AppLayouts.Profile.stores 1.0
@ -31,7 +30,7 @@ QObject {
required property WalletConnectSDKBase wcSDK
required property DAppsStore store
required property WalletStores.RootStore walletRootStore
required property var walletRootStore
readonly property string selectedAccountAddress: walletRootStore.selectedAddress

View File

@ -21,6 +21,7 @@ import StatusQ.Core.Utils 0.1
import StatusQ.Popups.Dialog 0.1
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.adaptors 1.0
import shared.popups.send.panels 1.0
import "./controls"
@ -80,6 +81,12 @@ StatusDialog {
QtObject {
id: d
readonly property WalletAccountsAdaptor accountsAdaptor: WalletAccountsAdaptor {
accountsModel: popup.store.accounts
flatNetworksModel: popup.store.flatNetworksModel
areTestNetworksEnabled: popup.store.areTestNetworksEnabled
}
property bool ensOrStickersPurpose: popup.preSelectedSendType === Constants.SendType.ENSRegister ||
popup.preSelectedSendType === Constants.SendType.ENSRelease ||
popup.preSelectedSendType === Constants.SendType.ENSSetPubKey ||
@ -470,20 +477,7 @@ StatusDialog {
visible: !recipientInputLoader.ready && !d.isBridgeTx && !!d.selectedHolding
savedAddressesModel: popup.store.savedAddressesModel
myAccountsModel: SortFilterProxyModel {
sourceModel: popup.store.accounts
proxyRoles: FastExpressionRole {
function getColorizedChainShortNames(preferredSharingChainIds, address){
const chainShortNames = popup.store.getNetworkShortNames(preferredSharingChainIds)
return WalletUtils.colorizedChainPrefix(chainShortNames) + address
}
name: "colorizedChainShortNames"
expectedRoles: ["preferredSharingChainIds", "address"]
expression: getColorizedChainShortNames(model.preferredSharingChainIds, model.address)
}
}
myAccountsModel: d.accountsAdaptor.model
recentRecipientsModel: popup.store.tempActivityController1Model // Use Layer1 controller since this could go on top of other activity lists
onRecipientSelected: {