Updated on 2026-08-14
This commit is contained in:
parent
777ebd58cb
commit
0bc6142ea7
8 changed files with 45 additions and 24 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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() },
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue