Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-26 11:39:48 +04:00
parent 777ebd58cb
commit 0bc6142ea7
8 changed files with 45 additions and 24 deletions

View file

@ -9,6 +9,7 @@ import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.common.util.getCardsCount
import com.tangem.domain.models.StatusSource
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
@ -20,7 +21,6 @@ import com.tangem.utils.converter.Converter
* @property onClick lambda be invoked when item is clicked
* @property appCurrency selected app currency
* @property balance wallet balance
* @property isLoading wallet loading state
* @property isBalanceHidden wallet balance is hidden
*
[REDACTED_AUTHOR]
@ -29,7 +29,6 @@ class UserWalletItemUMConverter(
private val onClick: (UserWalletId) -> Unit,
private val appCurrency: AppCurrency? = null,
private val balance: TotalFiatBalance? = null,
private val isLoading: Boolean = true,
private val isBalanceHidden: Boolean = false,
private val endIcon: UserWalletItemUM.EndIcon = UserWalletItemUM.EndIcon.None,
) : Converter<UserWallet, UserWalletItemUM> {
@ -75,7 +74,7 @@ class UserWalletItemUMConverter(
UserWalletItemUM.Balance.Loaded(
value = formattedAmount,
isFlickering = isLoading,
isFlickering = balance.source == StatusSource.CACHE,
)
} else {
UserWalletItemUM.Balance.Failed

View file

@ -49,6 +49,14 @@ class FetchTokenListUseCase(
): Either<TokenListError, Unit> = either {
val currencies = fetchCurrencies(userWalletId, refresh = mode.refreshCurrencies)
invoke(userWalletId = userWalletId, currencies = currencies, mode = mode)
}
suspend operator fun invoke(
userWalletId: UserWalletId,
currencies: List<CryptoCurrency>,
mode: RefreshMode = RefreshMode.NONE,
): Either<TokenListError, Unit> = either {
coroutineScope {
val fetchStatuses = async {
fetchNetworksStatuses(

View file

@ -13,10 +13,8 @@ import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.tokens.operations.BaseCurrenciesStatusesOperations
import com.tangem.domain.tokens.operations.TokenListFiatBalanceOperations
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.transformLatest
import timber.log.Timber
class GetWalletTotalBalanceUseCase(
@ -54,20 +52,28 @@ class GetWalletTotalBalanceUseCase(
}
}
@OptIn(ExperimentalCoroutinesApi::class)
operator fun invoke(userWalletId: UserWalletId): LceFlow<TokenListError, TotalFiatBalance> {
return currenciesStatusesOperations.getCurrenciesStatuses(userWalletId)
.transformLatest { maybeStatuses ->
val balance = createBalance(maybeStatuses)
emit(balance)
}
return currenciesStatusesOperations.getCurrenciesStatuses(userWalletId).map(::createBalance)
}
private fun createBalance(
maybeStatuses: Lce<TokenListError, List<CryptoCurrencyStatus>>,
): Lce<TokenListError, TotalFiatBalance> = lce {
val statuses = maybeStatuses.bind()
val statuses = when (maybeStatuses) {
is Lce.Content -> maybeStatuses.content
is Lce.Error -> raise(maybeStatuses)
is Lce.Loading -> {
val content = maybeStatuses.partialContent
if (content == null) {
isLoading.set(true)
raise(lceLoading())
} else {
content
}
}
}
val operations = TokenListFiatBalanceOperations(
currencies = ensureNotNull(statuses.toNonEmptyListOrNull()) { lceLoading() },

View file

@ -7,6 +7,7 @@ import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.lce.lce
import com.tangem.domain.core.lce.lceFlow
import com.tangem.domain.core.utils.EitherFlow
import com.tangem.domain.core.utils.lceError
import com.tangem.domain.staking.model.stakekit.YieldBalance
import com.tangem.domain.staking.model.stakekit.YieldBalanceList
import com.tangem.domain.staking.repositories.StakingRepository
@ -45,9 +46,14 @@ class CachedCurrenciesStatusesOperations(
): LceFlow<TokenListError, List<CryptoCurrencyStatus>> = lceFlow {
currenciesFlow.flatMapLatest { maybeCurrencies ->
val isUpdating = MutableStateFlow(value = true)
val nonEmptyCurrencies = maybeCurrencies.bind().toNonEmptyListOrNull()
ensureNotNull(nonEmptyCurrencies) { TokenListError.EmptyTokens }
val nonEmptyCurrencies = maybeCurrencies
.getOrElse { return@flatMapLatest flowOf(it.lceError()) }
.toNonEmptyListOrNull()
if (nonEmptyCurrencies.isNullOrEmpty()) {
return@flatMapLatest flowOf(TokenListError.EmptyTokens.lceError())
}
// This is only 'true' when the flow here is empty, such as during initial loading
if (isLoading.get()) {

View file

@ -40,9 +40,9 @@ internal class UserWalletListModel @Inject constructor(
init {
combine(
userWalletsFetcher.userWallets,
shouldSaveUserWalletsUseCase(),
isWalletSavingInProgress,
flow = userWalletsFetcher.userWallets,
flow2 = shouldSaveUserWalletsUseCase(),
flow3 = isWalletSavingInProgress,
transform = ::updateState,
).launchIn(modelScope)
}

View file

@ -49,9 +49,9 @@ internal class UserWalletsFetcher @Inject constructor(
emit(uiModels)
combine(
getSelectedAppCurrencyUseCase().distinctUntilChanged(),
getBalanceHidingSettingsUseCase().distinctUntilChanged(),
getWalletTotalBalanceUseCase(wallets.map(UserWallet::walletId)).distinctUntilChanged(),
flow = getSelectedAppCurrencyUseCase().distinctUntilChanged(),
flow2 = getBalanceHidingSettingsUseCase().distinctUntilChanged(),
flow3 = getWalletTotalBalanceUseCase(wallets.map(UserWallet::walletId)).distinctUntilChanged(),
) { maybeAppCurrency, balanceHidingSettings, maybeBalances ->
val models = createUiModels(
wallets = wallets,
@ -99,7 +99,6 @@ internal class UserWalletsFetcher @Inject constructor(
appCurrency = appCurrency,
balance = balance,
isBalanceHidden = balanceHidingSettings.isBalanceHidden,
isLoading = maybeBalances.isLoading(),
)
.convert(userWallet)
}

View file

@ -127,7 +127,6 @@ internal class AddToPortfolioBSContentUMFactory(
},
appCurrency = portfolioData.appCurrency,
balance = balance?.getOrNull(),
isLoading = balance?.isLoading() == true,
isBalanceHidden = portfolioData.isBalanceHidden,
endIcon = if (userWallet.walletId == selectedWalletId) {
UserWalletItemUM.EndIcon.Checkmark

View file

@ -147,7 +147,11 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
).fold(
ifLeft = { Timber.e(it, "Failed to derive public keys") },
ifRight = {
fetchTokenListUseCase(userWallet.walletId, mode = RefreshMode.SKIP_CURRENCIES).onLeft {
fetchTokenListUseCase(
userWalletId = userWallet.walletId,
mode = RefreshMode.SKIP_CURRENCIES,
currencies = missedAddressCurrencies,
).onLeft {
Timber.e("Unable to refresh token list: $it")
}
},