From 0bc6142ea74f30f849898dadd752f6e44bf1b5dd Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 26 Feb 2025 11:39:48 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../converter/UserWalletItemUMConverter.kt | 5 ++-- .../domain/tokens/FetchTokenListUseCase.kt | 8 ++++++ .../tokens/GetWalletTotalBalanceUseCase.kt | 26 ++++++++++++------- .../CachedCurrenciesStatusesOperations.kt | 10 +++++-- .../details/model/UserWalletListModel.kt | 6 ++--- .../details/utils/UserWalletsFetcher.kt | 7 +++-- .../model/AddToPortfolioBSContentUMFactory.kt | 1 - .../intents/WalletWarningsClickIntents.kt | 6 ++++- 8 files changed, 45 insertions(+), 24 deletions(-) diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt index e3ee5ae7a0..24fc6cd8b2 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/UserWalletItemUMConverter.kt @@ -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 { @@ -75,7 +74,7 @@ class UserWalletItemUMConverter( UserWalletItemUM.Balance.Loaded( value = formattedAmount, - isFlickering = isLoading, + isFlickering = balance.source == StatusSource.CACHE, ) } else { UserWalletItemUM.Balance.Failed diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt index eafad782ed..408c4e81ca 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/FetchTokenListUseCase.kt @@ -49,6 +49,14 @@ class FetchTokenListUseCase( ): Either = either { val currencies = fetchCurrencies(userWalletId, refresh = mode.refreshCurrencies) + invoke(userWalletId = userWalletId, currencies = currencies, mode = mode) + } + + suspend operator fun invoke( + userWalletId: UserWalletId, + currencies: List, + mode: RefreshMode = RefreshMode.NONE, + ): Either = either { coroutineScope { val fetchStatuses = async { fetchNetworksStatuses( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt index 5f874b7419..8b6ba7ade2 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt @@ -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 { - return currenciesStatusesOperations.getCurrenciesStatuses(userWalletId) - .transformLatest { maybeStatuses -> - val balance = createBalance(maybeStatuses) - - emit(balance) - } + return currenciesStatusesOperations.getCurrenciesStatuses(userWalletId).map(::createBalance) } private fun createBalance( maybeStatuses: Lce>, ): Lce = 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() }, diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt index cd0a3639c9..969e56d6ef 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CachedCurrenciesStatusesOperations.kt @@ -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> = 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()) { diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt index ef9905ff46..d7cc987538 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt @@ -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) } diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletsFetcher.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletsFetcher.kt index c9115930ec..4fce54d271 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletsFetcher.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletsFetcher.kt @@ -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) } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt index 5f82c6c481..aecd1f943e 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt @@ -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 diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt index 115c9535ab..b3dc26a447 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt @@ -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") } },