From 543ea15efb39b44c6752598818b4c00c6335b4d2 Mon Sep 17 00:00:00 2001 From: ERussel Date: Wed, 7 Feb 2024 12:01:56 +0100 Subject: [PATCH 1/2] display full amount for total balance --- .../AssetBalanceFormatterFactory.swift | 63 ++++++++++++------- .../ViewModel/AssetListViewModelFactory.swift | 38 +++++++++-- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/novawallet/Common/Helpers/AssetBalanceFormatterFactory.swift b/novawallet/Common/Helpers/AssetBalanceFormatterFactory.swift index 036f55e28c..89329e4056 100644 --- a/novawallet/Common/Helpers/AssetBalanceFormatterFactory.swift +++ b/novawallet/Common/Helpers/AssetBalanceFormatterFactory.swift @@ -17,6 +17,8 @@ protocol AssetBalanceFormatterFactoryProtocol { func createAssetPriceFormatter(for info: AssetBalanceDisplayInfo) -> LocalizableResource + func createTotalPriceFormatter(for info: AssetBalanceDisplayInfo) -> LocalizableResource + func createInputTokenFormatter( for info: AssetBalanceDisplayInfo ) -> LocalizableResource @@ -40,12 +42,14 @@ class AssetBalanceFormatterFactory { private func createTokenFormatterCommon( for info: AssetBalanceDisplayInfo, roundingMode: NumberFormatter.RoundingMode, - preferredPrecisionOffset: UInt8 = 0 + preferredPrecisionOffset: UInt8 = 0, + usesSuffixForBigNumbers: Bool = true ) -> LocalizableResource { let formatter = createCompoundFormatter( for: info.displayPrecision, roundingMode: roundingMode, - prefferedPrecisionOffset: preferredPrecisionOffset + prefferedPrecisionOffset: preferredPrecisionOffset, + usesSuffixForBigNumber: usesSuffixForBigNumbers ) let tokenFormatter = TokenFormatter( @@ -65,9 +69,10 @@ class AssetBalanceFormatterFactory { private func createCompoundFormatter( for preferredPrecision: UInt16, roundingMode: NumberFormatter.RoundingMode = .down, - prefferedPrecisionOffset: UInt8 = 0 + prefferedPrecisionOffset: UInt8 = 0, + usesSuffixForBigNumber: Bool = true ) -> LocalizableDecimalFormatting { - let abbreviations: [BigNumberAbbreviation] = [ + var abbreviations: [BigNumberAbbreviation] = [ BigNumberAbbreviation( threshold: 0, divisor: 1.0, @@ -93,27 +98,32 @@ class AssetBalanceFormatterFactory { divisor: 1.0, suffix: "", formatter: nil - ), - BigNumberAbbreviation( - threshold: 1_000_000, - divisor: 1_000_000.0, - suffix: "M", - formatter: nil - ), - BigNumberAbbreviation( - threshold: 1_000_000_000, - divisor: 1_000_000_000.0, - suffix: "B", - formatter: nil - ), - BigNumberAbbreviation( - threshold: 1_000_000_000_000, - divisor: 1_000_000_000_000.0, - suffix: "T", - formatter: nil ) ] + if usesSuffixForBigNumber { + abbreviations.append(contentsOf: [ + BigNumberAbbreviation( + threshold: 1_000_000, + divisor: 1_000_000.0, + suffix: "M", + formatter: nil + ), + BigNumberAbbreviation( + threshold: 1_000_000_000, + divisor: 1_000_000_000.0, + suffix: "B", + formatter: nil + ), + BigNumberAbbreviation( + threshold: 1_000_000_000_000, + divisor: 1_000_000_000_000.0, + suffix: "T", + formatter: nil + ) + ]) + } + return BigNumberFormatter( abbreviations: abbreviations, precision: 2, @@ -154,6 +164,15 @@ extension AssetBalanceFormatterFactory: AssetBalanceFormatterFactoryProtocol { createTokenFormatterCommon(for: info, roundingMode: .down, preferredPrecisionOffset: 2) } + func createTotalPriceFormatter(for info: AssetBalanceDisplayInfo) -> LocalizableResource { + createTokenFormatterCommon( + for: info, + roundingMode: .down, + preferredPrecisionOffset: 2, + usesSuffixForBigNumbers: false + ) + } + func createInputTokenFormatter( for info: AssetBalanceDisplayInfo ) -> LocalizableResource { diff --git a/novawallet/Modules/AssetList/ViewModel/AssetListViewModelFactory.swift b/novawallet/Modules/AssetList/ViewModel/AssetListViewModelFactory.swift index 36e49f4c42..6e87615454 100644 --- a/novawallet/Modules/AssetList/ViewModel/AssetListViewModelFactory.swift +++ b/novawallet/Modules/AssetList/ViewModel/AssetListViewModelFactory.swift @@ -55,8 +55,8 @@ final class AssetListViewModelFactory: AssetListAssetViewModelFactory { private lazy var iconGenerator = NovaIconGenerator() - private func formatTotalPrice(from prices: [AssetListAssetAccountPrice], locale: Locale) -> String { - let totalPrice = prices.reduce(Decimal(0)) { result, item in + private func calculateTotalPrice(from prices: [AssetListAssetAccountPrice]) -> Decimal { + prices.reduce(Decimal(0)) { result, item in let balance = Decimal.fromSubstrateAmount( item.balance, precision: item.assetInfo.assetPrecision @@ -66,8 +66,18 @@ final class AssetListViewModelFactory: AssetListAssetViewModelFactory { return result + balance * price } + } + + private func createTotalPriceString( + from price: Decimal, + priceData: PriceData?, + locale: Locale + ) -> String { + let currencyId = priceData?.currencyId ?? currencyManager.selectedCurrency.id + let assetDisplayInfo = priceAssetInfoFactory.createAssetBalanceDisplayInfo(from: currencyId) + let priceFormatter = assetFormatterFactory.createTotalPriceFormatter(for: assetDisplayInfo) - return formatPrice(amount: totalPrice, priceData: prices.first?.price, locale: locale) + return priceFormatter.value(for: locale).stringFromDecimal(price) ?? "" } private func createTotalPrice( @@ -78,10 +88,20 @@ final class AssetListViewModelFactory: AssetListAssetViewModelFactory { case .loading: return .loading case let .cached(value): - let formattedPrice = formatTotalPrice(from: value, locale: locale) + let formattedPrice = createTotalPriceString( + from: calculateTotalPrice(from: value), + priceData: value.first?.price, + locale: locale + ) + return .cached(value: .init(amount: formattedPrice, decimalSeparator: locale.decimalSeparator)) case let .loaded(value): - let formattedPrice = formatTotalPrice(from: value, locale: locale) + let formattedPrice = createTotalPriceString( + from: calculateTotalPrice(from: value), + priceData: value.first?.price, + locale: locale + ) + return .loaded(value: .init(amount: formattedPrice, decimalSeparator: locale.decimalSeparator)) } } @@ -107,7 +127,13 @@ extension AssetListViewModelFactory: AssetListViewModelFactoryProtocol { walletConnectSessionsCount: formattedWalletConnectSessionsCount, title: params.title, amount: totalPrice, - locksAmount: params.locks.map { formatTotalPrice(from: $0, locale: locale) }, + locksAmount: params.locks.map { lock in + formatPrice( + amount: calculateTotalPrice(from: lock), + priceData: lock.first?.price, + locale: locale + ) + }, walletSwitch: walletSwitch, hasSwaps: params.hasSwaps ) From 992dbc4b4e9e4de664cd56b76fac5d8bd88cf050 Mon Sep 17 00:00:00 2001 From: ERussel Date: Wed, 7 Feb 2024 12:14:07 +0100 Subject: [PATCH 2/2] fix crash on DApp browser when address prefix too large --- .../DAppBrowser/StateMachine/DAppBrowserStateDataSource.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/novawallet/Modules/DApp/DAppBrowser/StateMachine/DAppBrowserStateDataSource.swift b/novawallet/Modules/DApp/DAppBrowser/StateMachine/DAppBrowserStateDataSource.swift index 75f361e770..ff1f87f1e9 100644 --- a/novawallet/Modules/DApp/DAppBrowser/StateMachine/DAppBrowserStateDataSource.swift +++ b/novawallet/Modules/DApp/DAppBrowser/StateMachine/DAppBrowserStateDataSource.swift @@ -75,10 +75,8 @@ final class DAppBrowserStateDataSource { return nil } - let addressPrefix = UInt16(addressPrefixValue) - return chainStore.values.first { model in - model.isEthereumBased && model.addressPrefix == addressPrefix + model.isEthereumBased && BigUInt(model.addressPrefix) == addressPrefixValue } }