Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-28 13:35:09 +04:00
parent e32d1a2b65
commit 592351f421
5 changed files with 77 additions and 21 deletions

View file

@ -35,8 +35,22 @@ internal class DefaultQuotesRepository(
private var quotesFetchedForAppCurrency: String? = null
private val mutex = Mutex()
@OptIn(ExperimentalCoroutinesApi::class)
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>): Flow<Set<Quote>> {
return quotesStore.get(currenciesIds)
return appPreferencesStore.getObject<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
)
.distinctUntilChanged()
.filterNotNull()
.flatMapLatest { appCurrency ->
fetchExpiredQuotes(
currenciesIds = currenciesIds,
appCurrencyId = appCurrency.id,
refresh = true,
)
quotesStore.get(currenciesIds)
}
.flowOn(dispatchers.io)
}

View file

@ -17,6 +17,7 @@ import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.utils.CurrencyStatusProxyCreator
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
/**
* Base operations for working with currency status
@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.*
*
[REDACTED_AUTHOR]
*/
@Suppress("LargeClass")
abstract class BaseCurrencyStatusOperations(
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
@ -44,6 +46,13 @@ abstract class BaseCurrencyStatusOperations(
network: Network,
): EitherFlow<Error, Set<NetworkStatus>>
protected abstract suspend fun fetchComponents(
userWalletId: UserWalletId,
networks: Set<Network>,
currenciesIds: Set<CryptoCurrency.ID>,
currencies: List<CryptoCurrency>,
): Either<Throwable, Unit>
suspend fun getCurrencyStatusFlow(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
@ -93,13 +102,26 @@ abstract class BaseCurrencyStatusOperations(
val yieldBalanceFlow = getYieldBalance(userWalletId = userWalletId, cryptoCurrency = currency)
return combine(quoteFlow, statusFlow, yieldBalanceFlow) { maybeQuote, maybeNetworkStatus, maybeYieldBalance ->
currencyStatusProxyCreator.createCurrencyStatus(
currency = currency,
maybeQuote = maybeQuote,
maybeNetworkStatus = maybeNetworkStatus,
maybeYieldBalance = maybeYieldBalance,
)
return channelFlow {
launch {
fetchComponents(
userWalletId = userWalletId,
networks = nonEmptySetOf(currency.network),
currenciesIds = nonEmptySetOf(currency.id),
currencies = nonEmptyListOf(currency),
)
}
combine(quoteFlow, statusFlow, yieldBalanceFlow) { maybeQuote, maybeNetworkStatus, maybeYieldBalance ->
currencyStatusProxyCreator.createCurrencyStatus(
currency = currency,
maybeQuote = maybeQuote,
maybeNetworkStatus = maybeNetworkStatus,
maybeYieldBalance = maybeYieldBalance,
)
}
.onEach(::send)
.launchIn(this)
}
}

View file

@ -1,7 +1,7 @@
package com.tangem.domain.tokens.operations
import arrow.core.*
import arrow.core.raise.*
import arrow.core.raise.recover
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.lce.lce
@ -98,14 +98,14 @@ class CachedCurrenciesStatusesOperations(
.launchIn(scope = this)
}
private suspend fun Raise<TokenListError>.fetchComponents(
override suspend fun fetchComponents(
userWalletId: UserWalletId,
networks: NonEmptySet<Network>,
currenciesIds: NonEmptySet<CryptoCurrency.ID>,
currencies: NonEmptyList<CryptoCurrency>,
) = coroutineScope {
catch(
block = {
networks: Set<Network>,
currenciesIds: Set<CryptoCurrency.ID>,
currencies: List<CryptoCurrency>,
): Either<Throwable, Unit> {
return coroutineScope {
Either.catch {
awaitAll(
async { networksRepository.fetchNetworkStatuses(userWalletId, networks) },
async {
@ -114,11 +114,9 @@ class CachedCurrenciesStatusesOperations(
},
async { stakingRepository.fetchMultiYieldBalance(userWalletId, currencies) },
)
},
catch = {
raise(TokenListError.DataError(it))
},
)
}
.map { }
}
}
private fun createCurrenciesStatuses(

View file

@ -43,6 +43,13 @@ class CurrenciesStatusesOperations(
.onEmpty { emit(Error.EmptyNetworksStatuses.left()) }
}
override suspend fun fetchComponents(
userWalletId: UserWalletId,
networks: Set<Network>,
currenciesIds: Set<CryptoCurrency.ID>,
currencies: List<CryptoCurrency>,
): Either<Throwable, Unit> = Unit.right()
sealed class Error {
data object EmptyCurrencies : Error()

View file

@ -4,6 +4,7 @@ import arrow.core.Either
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.models.StatusSource
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
import com.tangem.domain.tokens.error.CurrencyStatusError
@ -42,6 +43,8 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
) { maybePrimaryCurrencyStatus, isReadyToShowRating, isNeedToBackup, userWallets ->
readyForRateAppNotification = true
buildList {
addUsedOutdatedDataNotification(maybePrimaryCurrencyStatus)
addCriticalNotifications(
cardTypesResolver = cardTypesResolver,
)
@ -68,6 +71,18 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
}
}
private fun MutableList<WalletNotification>.addUsedOutdatedDataNotification(
maybePrimaryCurrencyStatus: Either<CurrencyStatusError, CryptoCurrencyStatus>,
) {
addIf(
element = WalletNotification.UsedOutdatedData,
condition = maybePrimaryCurrencyStatus.fold(
ifLeft = { false },
ifRight = { it.value.source == StatusSource.ONLY_CACHE },
),
)
}
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
addIf(
element = WalletNotification.Critical.DevCard,