Updated on 2026-08-14
This commit is contained in:
parent
87c43ab20f
commit
27b0d0f461
6 changed files with 92 additions and 46 deletions
|
|
@ -5,10 +5,30 @@ import com.tangem.tap.domain.model.WalletStoreModel
|
|||
import java.math.BigDecimal
|
||||
|
||||
interface TotalFiatBalanceCalculator {
|
||||
|
||||
/**
|
||||
* Calculate total fiat balance for list of [WalletStoreModel]
|
||||
* @param prevAmount Previous amount, used in [TotalFiatBalance.Refreshing]
|
||||
* @param walletStores List of [WalletStoreModel] to calculate fiat amount
|
||||
* @param initial Initial [TotalFiatBalance] state, used when list of [WalletStoreModel] is empty
|
||||
* @return [TotalFiatBalance] with state found with the [WalletStoreModel] list
|
||||
* */
|
||||
suspend fun calculate(
|
||||
prevAmount: BigDecimal,
|
||||
prevAmount: BigDecimal?,
|
||||
walletStores: List<WalletStoreModel>,
|
||||
initial: TotalFiatBalance,
|
||||
): TotalFiatBalance
|
||||
|
||||
/**
|
||||
* Same as [TotalFiatBalanceCalculator.calculate] but returns null if list of [WalletStoreModel] is empty
|
||||
* @param prevAmount Previous amount, used in [TotalFiatBalance.Refreshing]
|
||||
* @param walletStores List of [WalletStoreModel] to calculate fiat amount
|
||||
* @return [TotalFiatBalance] with state found with the [WalletStoreModel] list
|
||||
* */
|
||||
suspend fun calculateOrNull(
|
||||
prevAmount: BigDecimal?,
|
||||
walletStores: List<WalletStoreModel>,
|
||||
): TotalFiatBalance?
|
||||
|
||||
companion object
|
||||
}
|
||||
|
|
@ -11,11 +11,19 @@ import java.math.BigDecimal
|
|||
|
||||
internal class DefaultTotalFiatBalanceCalculator : TotalFiatBalanceCalculator {
|
||||
override suspend fun calculate(
|
||||
prevAmount: BigDecimal,
|
||||
prevAmount: BigDecimal?,
|
||||
walletStores: List<WalletStoreModel>,
|
||||
initial: TotalFiatBalance,
|
||||
): TotalFiatBalance {
|
||||
return calculateOrNull(prevAmount, walletStores) ?: initial
|
||||
}
|
||||
|
||||
override suspend fun calculateOrNull(
|
||||
prevAmount: BigDecimal?,
|
||||
walletStores: List<WalletStoreModel>,
|
||||
): TotalFiatBalance? {
|
||||
return if (walletStores.isEmpty()) {
|
||||
TotalFiatBalance.Loading
|
||||
null
|
||||
} else {
|
||||
withContext(Dispatchers.Default) {
|
||||
val walletsData = walletStores
|
||||
|
|
@ -25,7 +33,9 @@ internal class DefaultTotalFiatBalanceCalculator : TotalFiatBalanceCalculator {
|
|||
|
||||
when (walletsData.findStatus()) {
|
||||
TotalFiatBalanceStatus.Loading -> TotalFiatBalance.Loading
|
||||
TotalFiatBalanceStatus.Refreshing -> TotalFiatBalance.Refreshing(prevAmount)
|
||||
TotalFiatBalanceStatus.Refreshing -> TotalFiatBalance.Refreshing(
|
||||
amount = prevAmount ?: BigDecimal.ZERO,
|
||||
)
|
||||
TotalFiatBalanceStatus.Error -> TotalFiatBalance.Error(calculateAmount())
|
||||
TotalFiatBalanceStatus.Loaded -> TotalFiatBalance.Loaded(calculateAmount())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,28 +294,29 @@ class WalletMiddleware {
|
|||
}
|
||||
is WalletAction.UserWalletChanged -> Unit
|
||||
is WalletAction.WalletStoresChanged -> {
|
||||
scope.launch(Dispatchers.Default) {
|
||||
fetchTotalFiatBalance(action.walletStores, walletState)
|
||||
findMissedDerivations(action.walletStores)
|
||||
tryToShowAppRatingWarning(action.walletStores)
|
||||
}
|
||||
fetchTotalFiatBalance(action.walletStores, walletState)
|
||||
findMissedDerivations(action.walletStores)
|
||||
tryToShowAppRatingWarning(action.walletStores)
|
||||
}
|
||||
is WalletAction.TotalFiatBalanceChanged -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchTotalFiatBalance(walletStores: List<WalletStoreModel>, state: WalletState) {
|
||||
scope.launch {
|
||||
val totalFiatBalance = totalFiatBalanceCalculator.calculate(
|
||||
prevAmount = state.totalBalance?.fiatAmount ?: BigDecimal.ZERO,
|
||||
scope.launch(Dispatchers.Default) {
|
||||
val totalFiatBalance = totalFiatBalanceCalculator.calculateOrNull(
|
||||
prevAmount = state.totalBalance?.fiatAmount,
|
||||
walletStores = walletStores,
|
||||
)
|
||||
store.dispatchOnMain(WalletAction.TotalFiatBalanceChanged(totalFiatBalance))
|
||||
|
||||
if (totalFiatBalance != null) {
|
||||
store.dispatchOnMain(WalletAction.TotalFiatBalanceChanged(totalFiatBalance))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findMissedDerivations(wallStores: List<WalletStoreModel>) {
|
||||
scope.launch {
|
||||
scope.launch(Dispatchers.Default) {
|
||||
val missedDerivations = wallStores
|
||||
.filter { store ->
|
||||
store.walletsData.any { it.status is WalletDataModel.MissedDerivation }
|
||||
|
|
@ -327,11 +328,13 @@ class WalletMiddleware {
|
|||
}
|
||||
|
||||
private fun tryToShowAppRatingWarning(walletStores: List<WalletStoreModel>) {
|
||||
warningsMiddleware.tryToShowAppRatingWarning(
|
||||
hasNonZeroWallets = walletStores
|
||||
.flatMap { it.walletsData }
|
||||
.any { it.status.amount.isGreaterThan(BigDecimal.ZERO) },
|
||||
)
|
||||
scope.launch(Dispatchers.Default) {
|
||||
warningsMiddleware.tryToShowAppRatingWarning(
|
||||
hasNonZeroWallets = walletStores
|
||||
.flatMap { it.walletsData }
|
||||
.any { it.status.amount.isGreaterThan(BigDecimal.ZERO) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSaveWalletIfNeeded() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ import com.tangem.domain.common.TapWorkarounds.isTestCard
|
|||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.analytics.events.Portfolio
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.extensions.animateVisibility
|
||||
import com.tangem.tap.common.extensions.formatAmountAsSpannedString
|
||||
import com.tangem.tap.common.extensions.getQuantityString
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.tokens.CurrenciesRepository
|
||||
|
|
@ -43,6 +47,7 @@ class MultiWalletView : WalletView() {
|
|||
lAddress.root.hide()
|
||||
rowButtons.hide()
|
||||
lSingleWalletBalance.root.hide()
|
||||
lCardTotalBalance.root.show()
|
||||
rvMultiwallet.show()
|
||||
btnAddToken.show()
|
||||
setupWalletCardNumber(binding)
|
||||
|
|
@ -134,21 +139,20 @@ class MultiWalletView : WalletView() {
|
|||
totalBalance: TotalBalance?,
|
||||
progressState: ProgressState,
|
||||
) = with(binding.lCardTotalBalance) {
|
||||
root.isVisible = totalBalance != null
|
||||
if (totalBalance != null) {
|
||||
// Skip changes when on refreshing state
|
||||
if (totalBalance.state == ProgressState.Refreshing ||
|
||||
progressState == ProgressState.Refreshing
|
||||
) return@with
|
||||
if (totalBalance == null) {
|
||||
veilBalance.animateVisibility(show = true)
|
||||
root.isVisible = progressState == ProgressState.Loading
|
||||
} else {
|
||||
root.isVisible = true
|
||||
|
||||
if (totalBalance.state == ProgressState.Loading) {
|
||||
veilBalance.veil()
|
||||
} else {
|
||||
veilBalance.unVeil()
|
||||
// Skip changes when on refreshing state
|
||||
if (totalBalance.state == ProgressState.Refreshing || progressState == ProgressState.Refreshing) {
|
||||
return@with
|
||||
}
|
||||
tvProcessing.animateVisibility(
|
||||
show = totalBalance.state == ProgressState.Error,
|
||||
)
|
||||
|
||||
veilBalance.animateVisibility(show = totalBalance.state == ProgressState.Loading)
|
||||
tvBalance.animateVisibility(show = totalBalance.state != ProgressState.Loading)
|
||||
tvProcessing.animateVisibility(show = totalBalance.state == ProgressState.Error)
|
||||
|
||||
tvBalance.text = totalBalance.fiatAmount.formatAmountAsSpannedString(
|
||||
currencySymbol = totalBalance.fiatCurrency.symbol,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.tap.common.extensions.onUserWalletSelected
|
|||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.model.TotalFiatBalance
|
||||
import com.tangem.tap.domain.model.UserWallet
|
||||
import com.tangem.tap.domain.model.WalletStoreModel
|
||||
import com.tangem.tap.domain.model.builders.UserWalletBuilder
|
||||
|
|
@ -26,6 +27,7 @@ import kotlinx.coroutines.flow.first
|
|||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Middleware
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class WalletSelectorMiddleware {
|
||||
val middleware: Middleware<AppState> = { _, appStateProvider ->
|
||||
|
|
@ -221,7 +223,6 @@ internal class WalletSelectorMiddleware {
|
|||
is UserWalletModel.Type.MultiCurrency -> type.copy(
|
||||
tokensCount = walletStores.flatMap { it.walletsData }.size,
|
||||
)
|
||||
|
||||
is UserWalletModel.Type.SingleCurrency -> type.copy(
|
||||
blockchainName = walletStores
|
||||
.firstOrNull()
|
||||
|
|
@ -233,6 +234,7 @@ internal class WalletSelectorMiddleware {
|
|||
fiatBalance = totalFiatBalanceCalculator.calculate(
|
||||
prevAmount = fiatBalance.amount,
|
||||
walletStores = walletStores,
|
||||
initial = TotalFiatBalance.Loaded(BigDecimal.ZERO),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue