From 5b3a115f55aee03c999cc947ce6c4af83b1404b2 Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Wed, 22 Mar 2023 23:08:36 +0100 Subject: [PATCH] fix(@desktop/wallet): Loading screen after adding account 1. Removing logic for loading to nim 2. Handling error state for asset view also on the nim side fixes #9648 --- .../main/wallet_section/accounts/item.nim | 11 +++++- .../main/wallet_section/accounts/model.nim | 8 +++- .../main/wallet_section/accounts/module.nim | 5 +-- .../main/wallet_section/accounts/utils.nim | 3 +- .../wallet_section/current_account/module.nim | 34 +++++++++++++--- .../wallet_section/current_account/view.nim | 14 +++++++ .../modules/main/wallet_section/module.nim | 5 --- src/app/modules/main/wallet_section/view.nim | 15 ------- src/app/modules/shared_models/token_item.nim | 39 ++++++++++++++++--- src/app/modules/shared_models/token_model.nim | 10 ++--- src/app/modules/shared_models/token_utils.nim | 2 +- src/app_service/service/message/service.nim | 2 +- src/app_service/service/token/dto.nim | 4 -- src/app_service/service/token/service.nim | 11 +----- .../service/wallet_account/dto.nim | 6 +-- .../service/wallet_account/service.nim | 17 ++++++-- .../ui-test/src/screens/StatusWalletScreen.py | 4 +- .../src/StatusQ/Components/StatusListItem.qml | 2 +- .../AppLayouts/Wallet/panels/WalletHeader.qml | 4 +- ui/app/AppLayouts/Wallet/stores/RootStore.qml | 1 - .../Wallet/views/AssetsDetailView.qml | 19 ++++----- .../AppLayouts/Wallet/views/LeftTabView.qml | 4 +- .../AppLayouts/Wallet/views/RightTabView.qml | 1 + ui/imports/shared/controls/TokenDelegate.qml | 23 ++++++----- .../shared/stores/NetworkConnectionStore.qml | 6 +-- ui/imports/shared/stores/RootStore.qml | 1 - ui/imports/shared/views/AssetsView.qml | 31 +++++++++------ ui/imports/utils/Constants.qml | 1 - 28 files changed, 171 insertions(+), 112 deletions(-) diff --git a/src/app/modules/main/wallet_section/accounts/item.nim b/src/app/modules/main/wallet_section/accounts/item.nim index 0dc58569b4..57506f4a4d 100644 --- a/src/app/modules/main/wallet_section/accounts/item.nim +++ b/src/app/modules/main/wallet_section/accounts/item.nim @@ -22,6 +22,7 @@ type keyUid: string migratedToKeycard: bool ens: string + assetsLoading: bool proc initItem*( name: string = "", @@ -40,7 +41,8 @@ proc initItem*( relatedAccounts: compact_model.Model = nil, keyUid: string = "", migratedToKeycard: bool = false, - ens: string = "" + ens: string = "", + assetsLoading: bool = true ): Item = result.name = name result.address = address @@ -59,6 +61,7 @@ proc initItem*( result.keyUid = keyUid result.migratedToKeycard = migratedToKeycard result.ens = ens + result.assetsLoading = assetsLoading proc `$`*(self: Item): string = result = fmt"""WalletAccountItem( @@ -78,7 +81,8 @@ proc `$`*(self: Item): string = relatedAccounts: {self.relatedAccounts} keyUid: {self.keyUid}, migratedToKeycard: {self.migratedToKeycard}, - ens: {self.ens} + ens: {self.ens}, + assetsLoading: {self.assetsLoading} ]""" proc getName*(self: Item): string = @@ -131,3 +135,6 @@ proc getMigratedToKeycard*(self: Item): bool = proc getEns*(self: Item): string = return self.ens + +proc getAssetsLoading*(self: Item): bool = + return self.assetsLoading diff --git a/src/app/modules/main/wallet_section/accounts/model.nim b/src/app/modules/main/wallet_section/accounts/model.nim index 600f8dce50..0318bad9cd 100644 --- a/src/app/modules/main/wallet_section/accounts/model.nim +++ b/src/app/modules/main/wallet_section/accounts/model.nim @@ -18,7 +18,8 @@ type DerivedFrom, RelatedAccounts, KeyUid, - MigratedToKeycard + MigratedToKeycard, + AssetsLoading QtObject: type @@ -68,7 +69,8 @@ QtObject: ModelRole.DerivedFrom.int: "derivedfrom", ModelRole.RelatedAccounts.int: "relatedAccounts", ModelRole.KeyUid.int: "keyUid", - ModelRole.MigratedToKeycard.int: "migratedToKeycard" + ModelRole.MigratedToKeycard.int: "migratedToKeycard", + ModelRole.AssetsLoading.int: "assetsLoading" }.toTable @@ -119,6 +121,8 @@ QtObject: result = newQVariant(item.getKeyUid()) of ModelRole.MigratedToKeycard: result = newQVariant(item.getMigratedToKeycard()) + of ModelRole.AssetsLoading: + result = newQVariant(item.getAssetsLoading()) proc getAccountNameByAddress*(self: Model, address: string): string = for account in self.items: diff --git a/src/app/modules/main/wallet_section/accounts/module.nim b/src/app/modules/main/wallet_section/accounts/module.nim index d93359f9ac..777338e4ae 100644 --- a/src/app/modules/main/wallet_section/accounts/module.nim +++ b/src/app/modules/main/wallet_section/accounts/module.nim @@ -128,9 +128,6 @@ method load*(self: Module) = self.events.on(SIGNAL_WALLET_ACCOUNT_UPDATED) do(e:Args): self.refreshWalletAccounts() - self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args): - self.refreshWalletAccounts() - self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args): self.refreshWalletAccounts() @@ -321,4 +318,4 @@ method addNewWalletAccountGeneratedFromKeycard*(self: Module, accountType: strin self.processingWalletAccount.keyUid, accountType, color, - emoji) \ No newline at end of file + emoji) diff --git a/src/app/modules/main/wallet_section/accounts/utils.nim b/src/app/modules/main/wallet_section/accounts/utils.nim index 7bbcb5b357..0e1e599ca7 100644 --- a/src/app/modules/main/wallet_section/accounts/utils.nim +++ b/src/app/modules/main/wallet_section/accounts/utils.nim @@ -68,5 +68,6 @@ proc walletAccountToItem*( relatedAccounts, w.keyUid, keyPairMigrated, - w.ens + w.ens, + w.assetsLoading ) diff --git a/src/app/modules/main/wallet_section/current_account/module.nim b/src/app/modules/main/wallet_section/current_account/module.nim index 7da617ebe4..3e5b7a8602 100644 --- a/src/app/modules/main/wallet_section/current_account/module.nim +++ b/src/app/modules/main/wallet_section/current_account/module.nim @@ -6,7 +6,10 @@ import ../../../../../app_service/service/token/service as token_service import ../../../../../app_service/service/currency/service as currency_service import ../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../app_service/service/network/service as network_service +import ../../../../../app_service/service/node/service as node_service +import ../../../../../app_service/service/network_connection/service as network_connection import ../../../shared_models/currency_amount_utils +import ../../../shared_models/currency_amount import ../../../shared_models/token_model as token_model import ../../../shared_models/token_item as token_item import ../../../shared_models/token_utils @@ -52,6 +55,13 @@ proc newModule*( method delete*(self: Module) = self.view.delete +proc setLoadingAssets(self: Module) = + var loadingTokenItems: seq[token_item.Item] + for i in 0 ..< 25: + loadingTokenItems.add(token_item.initLoadingItem()) + self.view.getAssetsModel().setItems(loadingTokenItems) + self.view.setCurrencyBalance(newCurrencyAmount()) + method load*(self: Module) = singletonInstance.engine.setRootContextProperty("walletSectionCurrent", newQVariant(self.view)) @@ -70,9 +80,6 @@ method load*(self: Module) = self.events.on(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED) do(e:Args): self.switchAccount(self.currentAccountIndex) - self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args): - self.switchAccount(self.currentAccountIndex) - self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e: Args): self.switchAccount(self.currentAccountIndex) @@ -83,6 +90,15 @@ method load*(self: Module) = self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args): self.onCurrencyFormatsUpdated() + self.events.on(SIGNAL_NETWORK_DISCONNECTED) do(e: Args): + if self.view.getAssetsModel().getCount() == 0: + self.setLoadingAssets() + + self.events.on(SIGNAL_CONNECTION_UPDATE) do(e:Args): + let args = NetworkConnectionsArgs(e) + if args.website == BLOCKCHAINS and args.completelyDown and self.view.getAssetsModel().getCount() == 0: + self.setLoadingAssets() + self.controller.init() self.view.load() @@ -157,7 +173,11 @@ method switchAccount*(self: Module, accountIndex: int) = ) self.view.setData(accountItem) - self.setAssetsAndBalance(walletAccount.tokens) + + if walletAccount.tokens.len == 0 and walletAccount.assetsLoading: + self.setLoadingAssets() + else: + self.setAssetsAndBalance(walletAccount.tokens) method update*(self: Module, address: string, accountName: string, color: string, emoji: string) = self.controller.update(address, accountName, color, emoji) @@ -166,12 +186,16 @@ proc onTokensRebuilt(self: Module, accountsTokens: OrderedTable[string, seq[Wall let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex) if not accountsTokens.contains(walletAccount.address): return + self.view.setAssetsLoading(false) self.setAssetsAndBalance(accountsTokens[walletAccount.address]) proc onCurrencyFormatsUpdated(self: Module) = # Update assets let walletAccount = self.controller.getWalletAccount(self.currentAccountIndex) - self.setAssetsAndBalance(walletAccount.tokens) + if walletAccount.tokens.len == 0 and walletAccount.assetsLoading: + self.setLoadingAssets() + else: + self.setAssetsAndBalance(walletAccount.tokens) method findTokenSymbolByAddress*(self: Module, address: string): string = return self.controller.findTokenSymbolByAddress(address) diff --git a/src/app/modules/main/wallet_section/current_account/view.nim b/src/app/modules/main/wallet_section/current_account/view.nim index 1b513690d7..0ec9095bc8 100644 --- a/src/app/modules/main/wallet_section/current_account/view.nim +++ b/src/app/modules/main/wallet_section/current_account/view.nim @@ -34,6 +34,7 @@ QtObject: ens: string tmpChainID: int # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs tmpSymbol: string # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs + assetsLoading: bool proc setup(self: View) = self.QObject.setup @@ -182,6 +183,18 @@ QtObject: read = getRelatedAccounts notify = relatedAccountsChanged + proc getAssetsLoading(self: View): QVariant {.slot.} = + return newQVariant(self.assetsLoading) + proc assetsLoadingChanged(self: View) {.signal.} + QtProperty[QVariant] assetsLoading: + read = getAssetsLoading + notify = assetsLoadingChanged + + proc setAssetsLoading*(self:View, assetLoading: bool) = + if assetLoading != self.assetsLoading: + self.assetsLoading = assetLoading + self.assetsLoadingChanged() + proc update(self: View, address: string, accountName: string, color: string, emoji: string) {.slot.} = self.delegate.update(address, accountName, color, emoji) @@ -230,6 +243,7 @@ QtObject: if(self.ens != item.getEns()): self.ens = item.getEns() self.ensChanged() + self.setAssetsLoading(item.getAssetsLoading()) # Set related accounts self.relatedAccounts = item.getRelatedAccounts() self.relatedAccountsChanged() diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index c15989ec3f..f1e0bf7126 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -118,15 +118,10 @@ method load*(self: Module) = self.events.on(SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED) do(e:Args): self.view.setCurrentCurrency(self.controller.getCurrency()) self.setTotalCurrencyBalance() - self.events.on(SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED) do(e:Args): - self.setTotalCurrencyBalance() self.events.on(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED) do(e:Args): self.setTotalCurrencyBalance() self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e:Args): self.setTotalCurrencyBalance() - self.view.setTokensLoading(false) - self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED) do(e:Args): - self.view.setTokensLoading(true) self.events.on(SIGNAL_CURRENCY_FORMATS_UPDATED) do(e:Args): self.setTotalCurrencyBalance() diff --git a/src/app/modules/main/wallet_section/view.nim b/src/app/modules/main/wallet_section/view.nim index 4b1930364c..1d13ef5397 100644 --- a/src/app/modules/main/wallet_section/view.nim +++ b/src/app/modules/main/wallet_section/view.nim @@ -11,7 +11,6 @@ QtObject: totalCurrencyBalance: CurrencyAmount signingPhrase: string isMnemonicBackedUp: bool - tokensLoading: bool tmpAmount: float # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs tmpSymbol: string # shouldn't be used anywhere except in prepareCurrencyAmount/getPreparedCurrencyAmount procs @@ -24,7 +23,6 @@ QtObject: proc newView*(delegate: io_interface.AccessInterface): View = new(result, delete) result.delegate = delegate - result.tokensLoading = true result.setup() proc load*(self: View) = @@ -53,15 +51,6 @@ QtObject: read = getTotalCurrencyBalance notify = totalCurrencyBalanceChanged - proc tokensLoadingChanged*(self: View) {.signal.} - - proc getTokensLoading(self: View): QVariant {.slot.} = - return newQVariant(self.tokensLoading) - - QtProperty[QVariant] tokensLoading: - read = getTokensLoading - notify = tokensLoadingChanged - proc getSigningPhrase(self: View): QVariant {.slot.} = return newQVariant(self.signingPhrase) @@ -103,10 +92,6 @@ QtObject: self.tmpSymbol = "ERROR" return newQVariant(currencyAmount) - proc setTokensLoading*(self: View, loading: bool) = - self.tokensLoading = loading - self.tokensLoadingChanged() - proc setData*(self: View, currency, signingPhrase: string, mnemonicBackedUp: bool) = self.currentCurrency = currency self.signingPhrase = signingPhrase diff --git a/src/app/modules/shared_models/token_item.nim b/src/app/modules/shared_models/token_item.nim index cc046a2f55..a92b8c703b 100644 --- a/src/app/modules/shared_models/token_item.nim +++ b/src/app/modules/shared_models/token_item.nim @@ -29,7 +29,7 @@ type change24hour: float64 currencyPrice: CurrencyAmount decimals: int - pegSymbol: string + loading: bool proc initItem*( name, symbol: string, @@ -53,7 +53,7 @@ proc initItem*( change24hour: float64, currencyPrice: CurrencyAmount, decimals: int, - pegSymbol: string, + loading: bool = false ): Item = result.name = name result.symbol = symbol @@ -78,7 +78,7 @@ proc initItem*( result.change24hour = change24hour result.currencyPrice = currencyPrice result.decimals = decimals - result.pegSymbol = pegSymbol + result.loading = loading proc `$`*(self: Item): string = result = fmt"""AllTokensItem( @@ -103,9 +103,36 @@ proc `$`*(self: Item): string = change24hour: {self.change24hour}, currencyPrice: {self.currencyPrice}, decimals: {self.decimals}, - pegSymbol: {self.pegSymbol}, + loading: {self.loading}, ]""" +proc initLoadingItem*(): Item = + return initItem( + name = "", + symbol = "", + totalBalance = newCurrencyAmount(), + totalCurrencyBalance = newCurrencyAmount(), + enabledNetworkBalance = newCurrencyAmount(), + enabledNetworkCurrencyBalance = newCurrencyAmount(), + visibleForNetwork = false, + visibleForNetworkWithPositiveBalance = false, + balances = @[], + description = "", + assetWebsiteUrl = "", + builtOn = "", + address = "", + marketCap = newCurrencyAmount(), + highDay = newCurrencyAmount(), + lowDay = newCurrencyAmount(), + changePctHour = 0, + changePctDay = 0, + changePct24hour = 0, + change24hour = 0, + currencyPrice = newCurrencyAmount(), + decimals = 0, + loading = true + ) + proc getName*(self: Item): string = return self.name @@ -172,5 +199,5 @@ proc getCurrencyPrice*(self: Item): CurrencyAmount = proc getDecimals*(self: Item): int = return self.decimals -proc getPegSymbol*(self: Item): string = - return self.pegSymbol +proc getLoading*(self: Item): bool = + return self.loading diff --git a/src/app/modules/shared_models/token_model.nim b/src/app/modules/shared_models/token_model.nim index 24d8c08f0d..1f926e3fce 100644 --- a/src/app/modules/shared_models/token_model.nim +++ b/src/app/modules/shared_models/token_model.nim @@ -27,7 +27,7 @@ type Change24hour CurrencyPrice Decimals - PegSymbol + Loading QtObject: type @@ -85,7 +85,7 @@ QtObject: ModelRole.Change24hour.int:"change24hour", ModelRole.CurrencyPrice.int:"currencyPrice", ModelRole.Decimals.int:"decimals", - ModelRole.PegSymbol.int:"pegSymbol", + ModelRole.Loading.int:"loading", }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -143,8 +143,8 @@ QtObject: result = newQVariant(item.getCurrencyPrice()) of ModelRole.Decimals: result = newQVariant(item.getDecimals()) - of ModelRole.PegSymbol: - result = newQVariant(item.getPegSymbol()) + of ModelRole.Loading: + result = newQVariant(item.getLoading()) proc rowData(self: Model, index: int, column: string): string {.slot.} = if (index >= self.items.len): @@ -172,7 +172,7 @@ QtObject: of "change24hour": result = $item.getChange24hour() of "currencyPrice": result = $item.getCurrencyPrice() of "decimals": result = $item.getDecimals() - of "pegSymbol": result = $item.getPegSymbol() + of "loading": result = $item.getLoading() proc setItems*(self: Model, items: seq[Item]) = self.beginResetModel() diff --git a/src/app/modules/shared_models/token_utils.nim b/src/app/modules/shared_models/token_utils.nim index aa24afb66d..168cb790b9 100644 --- a/src/app/modules/shared_models/token_utils.nim +++ b/src/app/modules/shared_models/token_utils.nim @@ -38,5 +38,5 @@ proc walletTokenToItem*( marketValues.change24hour, currencyAmountToItem(marketValues.price, currencyFormat), t.decimals, - t.pegSymbol + loading = false ) diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim index ddd2eee016..9a8951bae3 100644 --- a/src/app_service/service/message/service.nim +++ b/src/app_service/service/message/service.nim @@ -366,7 +366,7 @@ QtObject: proc getTransactionDetails*(self: Service, message: MessageDto): (string, string) = let networksDto = self.networkService.getNetworks() - var token = newTokenDto(networksDto[0].nativeCurrencyName, networksDto[0].chainId, parseAddress(ZERO_ADDRESS), networksDto[0].nativeCurrencySymbol, networksDto[0].nativeCurrencyDecimals, true, "") + var token = newTokenDto(networksDto[0].nativeCurrencyName, networksDto[0].chainId, parseAddress(ZERO_ADDRESS), networksDto[0].nativeCurrencySymbol, networksDto[0].nativeCurrencyDecimals, true) if message.transactionParameters.contract != "": for networkDto in networksDto: diff --git a/src/app_service/service/token/dto.nim b/src/app_service/service/token/dto.nim index 0bc5060a1d..3532fc2cb3 100644 --- a/src/app_service/service/token/dto.nim +++ b/src/app_service/service/token/dto.nim @@ -23,7 +23,6 @@ type color*: string isCustom* {.dontSerialize.}: bool isVisible* {.dontSerialize.}: bool - pegSymbol*: string proc newTokenDto*( name: string, @@ -32,7 +31,6 @@ proc newTokenDto*( symbol: string, decimals: int, hasIcon: bool, - pegSymbol: string, isCustom: bool = false, ): TokenDto = return TokenDto( @@ -42,7 +40,6 @@ proc newTokenDto*( symbol: symbol, decimals: decimals, hasIcon: hasIcon, - pegSymbol: pegSymbol, isCustom: isCustom ) @@ -57,7 +54,6 @@ proc toTokenDto*(jsonObj: JsonNode, isVisible: bool, hasIcon: bool = false, isCu discard jsonObj.getProp("symbol", result.symbol) discard jsonObj.getProp("decimals", result.decimals) discard jsonObj.getProp("color", result.color) - discard jsonObj.getProp("pegSymbol", result.pegSymbol) result.isVisible = isVisible proc addressAsString*(self: TokenDto): string = diff --git a/src/app_service/service/token/service.nim b/src/app_service/service/token/service.nim index 29f77cc8a6..6ab66df066 100644 --- a/src/app_service/service/token/service.nim +++ b/src/app_service/service/token/service.nim @@ -109,8 +109,7 @@ QtObject: address = Address.fromHex("0x0000000000000000000000000000000000000000"), symbol = network.nativeCurrencySymbol, decimals = network.nativeCurrencyDecimals, - hasIcon = false, - pegSymbol = "" + hasIcon = false ) if not self.tokensToAddressesMap.hasKey(network.nativeCurrencySymbol): @@ -246,14 +245,6 @@ QtObject: proc updateCachedTokenPrice(self: Service, crypto: string, fiat: string, price: float64) = let cacheKey = getTokenPriceCacheKey(crypto, fiat) self.priceCache.set(cacheKey, price) - - proc getTokenPegSymbol*(self: Service, symbol: string): string = - for _, tokens in self.tokens: - for token in tokens: - if token.symbol == symbol: - return token.pegSymbol - - return "" # History Data proc tokenHistoricalDataResolved*(self: Service, response: string) {.slot.} = diff --git a/src/app_service/service/wallet_account/dto.nim b/src/app_service/service/wallet_account/dto.nim index 8dca054482..66fb99c5c6 100644 --- a/src/app_service/service/wallet_account/dto.nim +++ b/src/app_service/service/wallet_account/dto.nim @@ -75,7 +75,6 @@ type description*: string assetWebsiteUrl*: string builtOn*: string - pegSymbol*: string marketValuesPerCurrency*: Table[string, TokenMarketValuesDto] type @@ -95,6 +94,7 @@ type derivedfrom*: string relatedAccounts*: seq[WalletAccountDto] ens*: string + assetsLoading*: bool proc newDto*( name: string, @@ -137,6 +137,7 @@ proc toWalletAccountDto*(jsonObj: JsonNode): WalletAccountDto = discard jsonObj.getProp("type", result.walletType) discard jsonObj.getProp("emoji", result.emoji) discard jsonObj.getProp("derived-from", result.derivedfrom) + result.assetsLoading = true proc getCurrencyBalance*(self: BalanceDto, currencyPrice: float64): float64 = return self.balance * currencyPrice @@ -211,7 +212,6 @@ proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto = discard jsonObj.getProp("description", result.description) discard jsonObj.getProp("assetWebsiteUrl", result.assetWebsiteUrl) discard jsonObj.getProp("builtOn", result.builtOn) - discard jsonObj.getProp("pegSymbol", result.pegSymbol) var marketValuesPerCurrencyObj: JsonNode if(jsonObj.getProp("marketValuesPerCurrency", marketValuesPerCurrencyObj)): @@ -221,4 +221,4 @@ proc toWalletTokenDto*(jsonObj: JsonNode): WalletTokenDto = var balancesPerChainObj: JsonNode if(jsonObj.getProp("balancesPerChain", balancesPerChainObj)): for chainId, balanceObj in balancesPerChainObj: - result.balancesPerChain[parseInt(chainId)] = toBalanceDto(balanceObj) \ No newline at end of file + result.balancesPerChain[parseInt(chainId)] = toBalanceDto(balanceObj) diff --git a/src/app_service/service/wallet_account/service.nim b/src/app_service/service/wallet_account/service.nim index 930545ce22..e7c3611bab 100644 --- a/src/app_service/service/wallet_account/service.nim +++ b/src/app_service/service/wallet_account/service.nim @@ -28,12 +28,10 @@ logScope: const SIGNAL_WALLET_ACCOUNT_SAVED* = "walletAccount/accountSaved" const SIGNAL_WALLET_ACCOUNT_DELETED* = "walletAccount/accountDeleted" const SIGNAL_WALLET_ACCOUNT_CURRENCY_UPDATED* = "walletAccount/currencyUpdated" -const SIGNAL_WALLET_ACCOUNT_TOKEN_VISIBILITY_UPDATED* = "walletAccount/tokenVisibilityUpdated" const SIGNAL_WALLET_ACCOUNT_UPDATED* = "walletAccount/walletAccountUpdated" const SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED* = "walletAccount/networkEnabledUpdated" const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_READY* = "walletAccount/derivedAddressesReady" const SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT* = "walletAccount/tokensRebuilt" -const SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED* = "walletAccount/tokenFetching" const SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_DETAILS_FETCHED* = "walletAccount/derivedAddressDetailsFetched" const SIGNAL_KEYCARDS_SYNCHRONIZED* = "keycardsSynchronized" @@ -536,6 +534,11 @@ QtObject: data.error = e.msg self.events.emit(SIGNAL_WALLET_ACCOUNT_DERIVED_ADDRESS_DETAILS_FETCHED, data) + proc updateAssetsLoadingState(self: Service, wAddress: string, loading: bool) = + withLock self.walletAccountsLock: + if self.walletAccounts.hasKey(wAddress): + self.walletAccounts[wAddress].assetsLoading = loading + proc onAllTokensBuilt*(self: Service, response: string) {.slot.} = try: var visibleSymbols: seq[string] @@ -555,6 +558,10 @@ QtObject: tokens = map(tokensDetailsObj.getElems(), proc(x: JsonNode): WalletTokenDto = x.toWalletTokenDto()) tokens.sort(priorityTokenCmp) data.accountsTokens[wAddress] = tokens + + # set assetsLoading to false once the tokens are loaded + self.updateAssetsLoadingState(wAddress, false) + if storeResult: self.storeTokensForAccount(wAddress, tokens) self.tokenService.updateTokenPrices(tokens) # For efficiency. Will be removed when token info fetching gets moved to the tokenService @@ -580,7 +587,11 @@ QtObject: accounts: accounts, storeResult: store ) - self.events.emit(SIGNAL_WALLET_ACCOUNT_TOKENS_BEING_FETCHED, Args()) + + # set assetsLoading to true as the tokens are being loaded + for waddress in accounts: + self.updateAssetsLoadingState(waddress, true) + self.threadpool.start(arg) proc getCurrentCurrencyIfEmpty(self: Service, currency = ""): string = diff --git a/test/ui-test/src/screens/StatusWalletScreen.py b/test/ui-test/src/screens/StatusWalletScreen.py index 4f9ed7c4be..bc56b66376 100644 --- a/test/ui-test/src/screens/StatusWalletScreen.py +++ b/test/ui-test/src/screens/StatusWalletScreen.py @@ -301,9 +301,9 @@ class StatusWalletScreen: for index in range(list.count): tokenListItem = list.itemAtIndex(index) - if tokenListItem != None and tokenListItem.objectName == "AssetView_LoadingTokenDelegate_"+str(index): + if tokenListItem != None and tokenListItem.item != None and tokenListItem.item.objectName == "AssetView_LoadingTokenDelegate_"+str(index): return (False, ) - if tokenListItem != None and tokenListItem.objectName == "AssetView_TokenListItem_" + symbol and tokenListItem.balance != "0": + if tokenListItem != None and tokenListItem.item != None and tokenListItem.item.objectName == "AssetView_TokenListItem_" + symbol and tokenListItem.item.balance != "0": return (True, tokenListItem) return (False, ) diff --git a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml index 1c23529705..4f3cb61d8e 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml @@ -262,7 +262,7 @@ Rectangle { icon.height: 14 icon.name: "tiny/warning" icon.color: Theme.palette.dangerColor1 - visible: root.errorMode && !!toolTip.text + visible: root.errorMode && !!errorIcon.tooltip.text } RowLayout { diff --git a/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml b/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml index 29a524266a..d9d12433d7 100644 --- a/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml +++ b/ui/app/AppLayouts/Wallet/panels/WalletHeader.qml @@ -46,8 +46,8 @@ Item { font.pixelSize: 28 font.bold: true customColor: Theme.palette.baseColor1 - text: LocaleUtils.currencyAmountToLocaleString(root.currentAccount.currencyBalance) - loading: root.walletStore.tokensLoading + text: loading ? Constants.dummyText : LocaleUtils.currencyAmountToLocaleString(root.currentAccount.currencyBalance) + loading: root.currentAccount.assetsLoading visible: !networkConnectionStore.tokenBalanceNotAvailable } } diff --git a/ui/app/AppLayouts/Wallet/stores/RootStore.qml b/ui/app/AppLayouts/Wallet/stores/RootStore.qml index 7c2f311c0f..359cc2adbd 100644 --- a/ui/app/AppLayouts/Wallet/stores/RootStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/RootStore.qml @@ -24,7 +24,6 @@ QtObject { property bool hideSignPhraseModal: accountSensitiveSettings.hideSignPhraseModal property var totalCurrencyBalance: walletSection.totalCurrencyBalance - property bool tokensLoading: walletSection.tokensLoading property string signingPhrase: walletSection.signingPhrase property string mnemonicBackedUp: walletSection.isMnemonicBackedUp diff --git a/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml b/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml index 4de54b9363..744f74f840 100644 --- a/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml +++ b/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml @@ -23,6 +23,7 @@ Item { property var token: ({}) property var networkConnectionStore /*required*/ property string address: "" + property var account QtObject { id: d @@ -56,8 +57,8 @@ Item { secondaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkBalance) : Constants.dummyText tertiaryText: token ? LocaleUtils.currencyAmountToLocaleString(token.enabledNetworkCurrencyBalance) : Constants.dummyText balances: token && token.balances ? token.balances : null - isLoading: RootStore.tokensLoading - errorTooltipText: token && token.balances ? networkConnectionStore.getNetworkDownTextForToken(token.balances): "" + isLoading: account.assetsLoading + errorTooltipText: token && token.balances ? networkConnectionStore.getBlockchainNetworkDownTextForToken(token.balances): "" getNetworkColor: function(chainId){ return RootStore.getNetworkColor(chainId) } @@ -278,19 +279,19 @@ Item { maxWidth: parent.width primaryText: qsTr("Market Cap") secondaryText: token && token.marketCap ? LocaleUtils.currencyAmountToLocaleString(token.marketCap) : Constants.dummyText - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } InformationTile { maxWidth: parent.width primaryText: qsTr("Day Low") secondaryText: token && token.lowDay ? LocaleUtils.currencyAmountToLocaleString(token.lowDay) : Constants.dummyText - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } InformationTile { maxWidth: parent.width primaryText: qsTr("Day High") secondaryText: token && token.highDay ? LocaleUtils.currencyAmountToLocaleString(token.highDay) : Constants.dummyText - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } Item { Layout.fillWidth: true @@ -303,7 +304,7 @@ Item { secondaryLabel.customColor: changePctHour === 0 ? Theme.palette.directColor1 : changePctHour < 0 ? Theme.palette.dangerColor1 : Theme.palette.successColor1 - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } InformationTile { readonly property double changePctDay: token.changePctDay ?? 0 @@ -313,7 +314,7 @@ Item { secondaryLabel.customColor: changePctDay === 0 ? Theme.palette.directColor1 : changePctDay < 0 ? Theme.palette.dangerColor1 : Theme.palette.successColor1 - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } InformationTile { readonly property double changePct24hour: token.changePct24hour ?? 0 @@ -323,7 +324,7 @@ Item { secondaryLabel.customColor: changePct24hour === 0 ? Theme.palette.directColor1 : changePct24hour < 0 ? Theme.palette.dangerColor1 : Theme.palette.successColor1 - isLoading: RootStore.tokensLoading + isLoading: account.assetsLoading } } @@ -369,7 +370,7 @@ Item { elide: Text.ElideRight wrapMode: Text.Wrap textFormat: Qt.RichText - loading: RootStore.tokensLoading + loading: account.assetsLoading } ColumnLayout { id: tagsLayout diff --git a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml index bff41bca99..45d3427a34 100644 --- a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml @@ -118,7 +118,7 @@ Rectangle { width: parent.width font.weight: Font.Medium font.pixelSize: 22 - loading: RootStore.tokensLoading + loading: RootStore.currentAccount.assetsLoading visible: !networkConnectionStore.tokenBalanceNotAvailable } @@ -177,7 +177,7 @@ Rectangle { asset.bgColor: Theme.palette.primaryColor3 statusListItemTitle.font.weight: Font.Medium color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent" - statusListItemSubTitle.loading: RootStore.tokensLoading + statusListItemSubTitle.loading: model.assetsLoading errorMode: networkConnectionStore.tokenBalanceNotAvailable errorIcon.tooltip.maxWidth: 300 errorIcon.tooltip.text: networkConnectionStore.tokenBalanceNotAvailableText diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index cf764590d9..d61d71c3bd 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -127,6 +127,7 @@ Item { Layout.fillHeight: true visible: (stack.currentIndex === 2) + account: RootStore.currentAccount address: RootStore.currentAccount.mixedcaseAddress networkConnectionStore: root.networkConnectionStore } diff --git a/ui/imports/shared/controls/TokenDelegate.qml b/ui/imports/shared/controls/TokenDelegate.qml index e0c1fe2062..43de047b47 100644 --- a/ui/imports/shared/controls/TokenDelegate.qml +++ b/ui/imports/shared/controls/TokenDelegate.qml @@ -17,16 +17,19 @@ StatusListItem { property alias change24HourPercentage: change24HourPercentageText property string currentCurrencySymbol - property string textColor: changePct24hour === undefined ? Theme.palette.baseColor1 : - Math.sign(changePct24hour) === 0 ? Theme.palette.baseColor1 : - Math.sign(changePct24hour) === -1 ? Theme.palette.dangerColor1 : - Theme.palette.successColor1 + property string textColor: modelData.changePct24hour === undefined ? + Theme.palette.baseColor1 : + modelData.changePct24hour === 0 ? + Theme.palette.baseColor1 : + modelData.changePct24hour < 0 ? + Theme.palette.dangerColor1 : + Theme.palette.successColor1 property string errorTooltipText_1 property string errorTooltipText_2 - title: name - subTitle: LocaleUtils.currencyAmountToLocaleString(enabledNetworkBalance) - asset.name: symbol ? Style.png("tokens/" + symbol) : "" + title: modelData.name + subTitle: LocaleUtils.currencyAmountToLocaleString(modelData.enabledNetworkBalance) + asset.name: modelData.symbol ? Style.png("tokens/" + modelData.symbol) : "" asset.isImage: true statusListItemTitleIcons.sourceComponent: StatusFlatRoundButton { @@ -60,7 +63,7 @@ StatusListItem { id: localeCurrencyBalance anchors.right: parent.right font.pixelSize: 15 - text: LocaleUtils.currencyAmountToLocaleString(enabledNetworkCurrencyBalance) + text: LocaleUtils.currencyAmountToLocaleString(modelData.enabledNetworkCurrencyBalance) visible: !errorIcon.visible } Row { @@ -71,7 +74,7 @@ StatusListItem { id: change24HourText font.pixelSize: 15 customColor: root.textColor - text: LocaleUtils.currencyAmountToLocaleString(currencyPrice) + text: LocaleUtils.currencyAmountToLocaleString(modelData.currencyPrice) } Rectangle { width: 1 @@ -82,7 +85,7 @@ StatusListItem { id: change24HourPercentageText font.pixelSize: 15 customColor: root.textColor - text: changePct24hour !== "" ? "%1%".arg(LocaleUtils.numberToLocaleString(changePct24hour, 2)) : "---" + text: modelData.changePct24hour !== "" ? "%1%".arg(LocaleUtils.numberToLocaleString(modelData.changePct24hour, 2)) : "---" } } } diff --git a/ui/imports/shared/stores/NetworkConnectionStore.qml b/ui/imports/shared/stores/NetworkConnectionStore.qml index ccbb8a6c28..cdd4819877 100644 --- a/ui/imports/shared/stores/NetworkConnectionStore.qml +++ b/ui/imports/shared/stores/NetworkConnectionStore.qml @@ -11,8 +11,6 @@ QtObject { readonly property var blockchainNetworksDown: networkConnectionModule.blockchainNetworkConnection.chainIds.split(";") readonly property bool atleastOneBlockchainNetworkAvailable: blockchainNetworksDown.length < networksModule.all.count - readonly property bool noBlockchainConnWithoutCache: (!mainModule.isOnline || networkConnectionModule.blockchainNetworkConnection.completelyDown) && - !walletSection.tokensLoading && walletSectionCurrent.assets.count === 0 readonly property bool sendBuyBridgeEnabled: localAppSettings.testEnvironment || (mainModule.isOnline && (!networkConnectionModule.blockchainNetworkConnection.completelyDown && atleastOneBlockchainNetworkAvailable) && @@ -29,7 +27,7 @@ QtObject { readonly property bool tokenBalanceNotAvailable: ((!mainModule.isOnline || networkConnectionModule.blockchainNetworkConnection.completelyDown) && - !walletSection.tokensLoading && walletSectionCurrent.assets.count === 0) || + !walletSectionCurrent.assetsLoading && walletSectionCurrent.assets.count === 0) || (networkConnectionModule.marketValuesNetworkConnection.completelyDown && !networkConnectionModule.marketValuesNetworkConnection.withCache) readonly property string tokenBalanceNotAvailableText: !mainModule.isOnline ? @@ -59,7 +57,7 @@ QtObject { function getMarketNetworkDownText() { if(networkConnectionModule.blockchainNetworkConnection.completelyDown && - !walletSection.tokensLoading && walletSectionCurrent.assets.count === 0 && + !walletSectionCurrent.assetsLoading && walletSectionCurrent.assets.count === 0 && networkConnectionModule.marketValuesNetworkConnection.completelyDown && !networkConnectionModule.marketValuesNetworkConnection.withCache) return qsTr("Market values and token balances use CryptoCompare/CoinGecko and POKT/Infura which are all currently unavailable.") diff --git a/ui/imports/shared/stores/RootStore.qml b/ui/imports/shared/stores/RootStore.qml index 590a0fef33..1e5713f57e 100644 --- a/ui/imports/shared/stores/RootStore.qml +++ b/ui/imports/shared/stores/RootStore.qml @@ -40,7 +40,6 @@ QtObject { property var historyTransactions: Global.appIsReady? walletSectionTransactions.model : null property bool isNonArchivalNode: history ? history.isNonArchivalNode : false - property bool tokensLoading: Global.appIsReady? walletSection.tokensLoading : false property var currentAccount: Global.appIsReady? walletSectionCurrent : null property var marketValueStore: TokenMarketValuesStore{} diff --git a/ui/imports/shared/views/AssetsView.qml b/ui/imports/shared/views/AssetsView.qml index 02f5ea2cdd..2b85436e54 100644 --- a/ui/imports/shared/views/AssetsView.qml +++ b/ui/imports/shared/views/AssetsView.qml @@ -33,9 +33,8 @@ Item { id: assetListView objectName: "assetViewStatusListView" anchors.fill: parent - // To-do: will try to move the loading tokens to the nim side under this task https://github.com/status-im/status-desktop/issues/9648 - model: RootStore.tokensLoading || networkConnectionStore.noBlockchainConnWithoutCache ? Constants.dummyModelItems : filteredModel - delegate: RootStore.tokensLoading || networkConnectionStore.noBlockchainConnWithoutCache ? loadingTokenDelegate : tokenDelegate + model: filteredModel + delegate: delegateLoader } SortFilterProxyModel { @@ -43,36 +42,44 @@ Item { sourceModel: account.assets filters: [ ExpressionFilter { - expression: visibleForNetworkWithPositiveBalance + expression: visibleForNetworkWithPositiveBalance || loading } ] } + Component { + id: delegateLoader + Loader { + property var modelData: model + property int index: index + width: ListView.view.width + sourceComponent: loading ? loadingTokenDelegate: tokenDelegate + } + } + Component { id: loadingTokenDelegate LoadingTokenDelegate { objectName: "AssetView_LoadingTokenDelegate_" + index - width: ListView.view.width } } Component { id: tokenDelegate TokenDelegate { - objectName: "AssetView_TokenListItem_" + symbol - readonly property string balance: "%1".arg(enabledNetworkBalance.amount) // Needed for the tests - errorTooltipText_1: networkConnectionStore.getBlockchainNetworkDownTextForToken(balances) + objectName: "AssetView_TokenListItem_" + modelData.symbol + readonly property string balance: "%1".arg(modelData.enabledNetworkBalance.amount) // Needed for the tests + errorTooltipText_1: networkConnectionStore.getBlockchainNetworkDownTextForToken(modelData.balances) errorTooltipText_2: networkConnectionStore.getMarketNetworkDownText() - width: ListView.view.width onClicked: { - RootStore.getHistoricalDataForToken(symbol, RootStore.currencyStore.currentCurrency) + RootStore.getHistoricalDataForToken(modelData.symbol, RootStore.currencyStore.currentCurrency) d.selectedAssetIndex = index - assetClicked(model) + assetClicked(modelData) } Component.onCompleted: { // on Model reset if the detail view is shown, update the data in background. if(root.assetDetailsLaunched && index === d.selectedAssetIndex) - assetClicked(model) + assetClicked(modelData) } } } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 70c14ab00f..674d5fdaf8 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -690,7 +690,6 @@ QtObject { } readonly property string dummyText: "Dummy" - readonly property int dummyModelItems: 25 readonly property string windows: "windows" readonly property string linux: "linux"