Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-15 23:12:51 +04:00
parent ac87667f88
commit 4a6dee8e56
5 changed files with 57 additions and 10 deletions

View file

@ -2,7 +2,7 @@ package com.tangem.domain.balancehiding.error
sealed class HideBalancesError {
object HidingDisabled : HideBalancesError()
data object HidingDisabled : HideBalancesError()
data class DataError(val cause: Throwable) : HideBalancesError()
}

View file

@ -107,4 +107,43 @@ sealed class Lce<out E : Any, out C : Any> {
ifContent = { null },
ifError = ::identity,
)
/**
* Returns `true` if this [Lce] is a [Lce.Loading] state and the given predicate is `true`.
*
* @param predicate The predicate to apply to the partial content.
* By default, the predicate is `true` for any partial content.
* @return `true` if this [Lce] is a [Lce.Loading] state and the given predicate is `true`, `false` otherwise.
*/
fun isLoading(predicate: (maybeContent: C?) -> Boolean = { true }): Boolean = fold(
ifLoading = { predicate(it) },
ifContent = { false },
ifError = { false },
)
/**
* Returns `true` if this [Lce] is a [Lce.Error] state and the given predicate is `true`.
*
* @param predicate The predicate to apply to the error.
* By default, the predicate is `true` for any error.
* @return `true` if this [Lce] is a [Lce.Error] state and the given predicate is `true`, `false` otherwise.
*/
fun isError(predicate: (error: E) -> Boolean = { true }): Boolean = fold(
ifLoading = { false },
ifContent = { false },
ifError = { predicate(it) },
)
/**
* Returns `true` if this [Lce] is a [Lce.Content] state and the given predicate is `true`.
*
* @param predicate The predicate to apply to the content.
* By default, the predicate is `true` for any content.
* @return `true` if this [Lce] is a [Lce.Content] state and the given predicate is `true`, `false` otherwise.
*/
fun isContent(predicate: (content: C) -> Boolean = { true }): Boolean = fold(
ifLoading = { false },
ifContent = { predicate(it) },
ifError = { false },
)
}

View file

@ -46,7 +46,7 @@ class LceRaise<E : Any> @PublishedApi internal constructor(
* */
@RaiseDSL
@OptIn(ExperimentalTypeInference::class)
inline fun <OtherError : Any, C : Any> withError(
inline fun <OtherError : Any, C> withError(
transform: (OtherError) -> E,
@BuilderInference block: LceRaise<OtherError>.() -> C,
): C = recover(

View file

@ -1,5 +1,6 @@
package com.tangem.domain.tokens
import arrow.atomic.update
import arrow.core.raise.ensureNotNull
import arrow.core.toNonEmptyListOrNull
import com.tangem.domain.core.lce.Lce
@ -16,9 +17,10 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
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.transform
import kotlinx.coroutines.flow.transformLatest
class GetWalletTotalBalanceUseCase(
private val currenciesRepository: CurrenciesRepository,
@ -28,9 +30,9 @@ class GetWalletTotalBalanceUseCase(
) {
suspend operator fun invoke(
userWallestIds: Collection<UserWalletId>,
userTallestIds: Collection<UserWalletId>,
): LceFlow<TokenListError, Map<UserWalletId, TotalFiatBalance>> {
val flows = userWallestIds.distinct()
val flows = userTallestIds.distinct()
.map { userWalletId ->
invoke(userWalletId).map { maybeBalance ->
userWalletId to maybeBalance
@ -39,17 +41,23 @@ class GetWalletTotalBalanceUseCase(
return combine(flows) { balances ->
lce {
balances.associate { (userWalletId, maybeBalance) ->
userWalletId to maybeBalance.bind()
balances.fold(mutableMapOf()) { acc, (userWalletId, maybeBalance) ->
val balance = maybeBalance.bindOrNull() ?: TotalFiatBalance.Loading
isLoading.update { it || balance is TotalFiatBalance.Loading }
acc[userWalletId] = balance
acc
}
}
}
}
@OptIn(ExperimentalCoroutinesApi::class)
suspend operator fun invoke(userWalletId: UserWalletId): LceFlow<TokenListError, TotalFiatBalance> {
val currenciesStatuses = getStatuses(userWalletId)
return currenciesStatuses.transform { maybeStatuses ->
return currenciesStatuses.transformLatest { maybeStatuses ->
val balance = createBalance(maybeStatuses)
emit(balance)

View file

@ -33,7 +33,7 @@ internal class CurrenciesStatusesLceOperations(
return transformToCurrenciesStatuses(
userWalletId = userWalletId,
flow = if (isSingleCurrencyWalletsAllowed) {
getWalletCurrenies(userWalletId)
getWalletCurrencies(userWalletId)
} else {
getMultiCurrencyWalletCurrencies(userWalletId)
},
@ -105,7 +105,7 @@ internal class CurrenciesStatusesLceOperations(
return statuses
}
private fun getWalletCurrenies(userWalletId: UserWalletId): LceFlow<TokenListError, List<CryptoCurrency>> {
private fun getWalletCurrencies(userWalletId: UserWalletId): LceFlow<TokenListError, List<CryptoCurrency>> {
return currenciesRepository.getWalletCurrenciesUpdates(userWalletId)
.map { maybeCurrencies ->
maybeCurrencies.mapError { TokenListError.DataError(it) }