From 592351f421ab458e830ec422979cc6fca22e170b Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 28 Feb 2025 13:35:09 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../repository/DefaultQuotesRepository.kt | 16 ++++++++- .../BaseCurrencyStatusOperations.kt | 36 +++++++++++++++---- .../CachedCurrenciesStatusesOperations.kt | 24 ++++++------- .../CurrenciesStatusesOperations.kt | 7 ++++ .../domain/GetSingleWalletWarningsFactory.kt | 15 ++++++++ 5 files changed, 77 insertions(+), 21 deletions(-) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt index 0874594282..1a40fa78b5 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt @@ -35,8 +35,22 @@ internal class DefaultQuotesRepository( private var quotesFetchedForAppCurrency: String? = null private val mutex = Mutex() + @OptIn(ExperimentalCoroutinesApi::class) override fun getQuotesUpdates(currenciesIds: Set): Flow> { - return quotesStore.get(currenciesIds) + return appPreferencesStore.getObject( + key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY, + ) + .distinctUntilChanged() + .filterNotNull() + .flatMapLatest { appCurrency -> + fetchExpiredQuotes( + currenciesIds = currenciesIds, + appCurrencyId = appCurrency.id, + refresh = true, + ) + + quotesStore.get(currenciesIds) + } .flowOn(dispatchers.io) } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt index 474974bf82..f765bd2dec 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/BaseCurrencyStatusOperations.kt @@ -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> + protected abstract suspend fun fetchComponents( + userWalletId: UserWalletId, + networks: Set, + currenciesIds: Set, + currencies: List, + ): Either + 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) } } 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 969e56d6ef..c06a0481bd 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 @@ -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.fetchComponents( + override suspend fun fetchComponents( userWalletId: UserWalletId, - networks: NonEmptySet, - currenciesIds: NonEmptySet, - currencies: NonEmptyList, - ) = coroutineScope { - catch( - block = { + networks: Set, + currenciesIds: Set, + currencies: List, + ): Either { + 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( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt index 8178ee7ecd..e71d7a55f4 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/operations/CurrenciesStatusesOperations.kt @@ -43,6 +43,13 @@ class CurrenciesStatusesOperations( .onEmpty { emit(Error.EmptyNetworksStatuses.left()) } } + override suspend fun fetchComponents( + userWalletId: UserWalletId, + networks: Set, + currenciesIds: Set, + currencies: List, + ): Either = Unit.right() + sealed class Error { data object EmptyCurrencies : Error() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt index 21f40750f2..d36afb7f8d 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetSingleWalletWarningsFactory.kt @@ -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.addUsedOutdatedDataNotification( + maybePrimaryCurrencyStatus: Either, + ) { + addIf( + element = WalletNotification.UsedOutdatedData, + condition = maybePrimaryCurrencyStatus.fold( + ifLeft = { false }, + ifRight = { it.value.source == StatusSource.ONLY_CACHE }, + ), + ) + } + private fun MutableList.addCriticalNotifications(cardTypesResolver: CardTypesResolver) { addIf( element = WalletNotification.Critical.DevCard,