Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-07 19:22:44 +04:00
parent 9ad06df95c
commit 01348109c2
6 changed files with 63 additions and 26 deletions

View file

@ -36,8 +36,25 @@ internal class DefaultQuotesRepository(
private var quotesFetchedForAppCurrency: String? = null
private val mutex = Mutex()
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>): Flow<Set<Quote>> {
TODO("Will be implemented in [REDACTED_TASK_KEY]")
}
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean) {
withContext(dispatchers.io) {
val selectedAppCurrency = requireNotNull(
value = appPreferencesStore.getObjectSyncOrNull<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
),
lazyMessage = { "Unable to get selected application currency to update quotes" },
)
fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, refresh)
}
}
@OptIn(ExperimentalCoroutinesApi::class)
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Flow<Set<Quote>> {
override fun getQuotesUpdatesLegacy(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Flow<Set<Quote>> {
return appPreferencesStore.getObject<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
)
@ -51,19 +68,6 @@ internal class DefaultQuotesRepository(
.flowOn(dispatchers.io)
}
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>) {
withContext(dispatchers.io) {
val selectedAppCurrency = requireNotNull(
value = appPreferencesStore.getObjectSyncOrNull<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
),
lazyMessage = { "Unable to get selected application currency to update quotes" },
)
fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, true)
}
}
override suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Set<Quote> {
return withContext(dispatchers.io) {
val selectedAppCurrency = requireNotNull(

View file

@ -1,10 +1,15 @@
package com.tangem.domain.markets
import arrow.core.*
import arrow.core.None
import arrow.core.Option
import arrow.core.toOption
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.repository.QuotesRepository
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@Suppress("UnusedPrivateMember")
class GetCurrencyQuotesUseCase(
@ -18,7 +23,7 @@ class GetCurrencyQuotesUseCase(
): Flow<Option<Quote.Value>> {
val rawId = currencyID.rawCurrencyId ?: return flowOf(None)
return quotesRepository.getQuotesUpdates(
return quotesRepository.getQuotesUpdatesLegacy(
currenciesIds = setOf(rawId),
refresh = refresh,
).map { it.filterIsInstance<Quote.Value>().firstOrNull().toOption() }.catch { emit(None) }

View file

@ -47,7 +47,10 @@ class RefreshMultiCurrencyWalletQuotesUseCase(
private suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.ID>) {
catch(
block = {
quotesRepository.fetchQuotes(currenciesIds.mapNotNullTo(hashSetOf(), CryptoCurrency.ID::rawCurrencyId))
quotesRepository.fetchQuotes(
currenciesIds = currenciesIds.mapNotNullTo(hashSetOf(), CryptoCurrency.ID::rawCurrencyId),
refresh = true,
)
},
catch = { /* Ignore error */ },
)

View file

@ -164,7 +164,7 @@ internal class CurrenciesStatusesLceOperations(
}
private fun getQuotes(tokensIds: NonEmptySet<CryptoCurrency.ID>): Flow<Either<TokenListError, Set<Quote>>> {
return quotesRepository.getQuotesUpdates(tokensIds.mapNotNull { it.rawCurrencyId }.toSet())
return quotesRepository.getQuotesUpdatesLegacy(tokensIds.mapNotNull { it.rawCurrencyId }.toSet())
.map<Set<Quote>, Either<TokenListError, Set<Quote>>> { it.right() }
.retryWhen { cause, _ ->
emit(TokenListError.DataError(cause).left())

View file

@ -9,6 +9,27 @@ import kotlinx.coroutines.flow.Flow
* */
interface QuotesRepository {
/**
* Retrieves updates of quotes for a set of specified cryptocurrencies,
* identified by their unique IDs from the local cache.
*
* To fetch and populate the cache with quotes, use [fetchQuotes].
*
* @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved.
* @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies.
*/
fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>): Flow<Set<Quote>>
/**
* Fetches quotes for a set of specified cryptocurrencies, identified by their unique IDs.
*
* Fetched quotes are stored in the local cache and can be retrieved by calling [getQuotesUpdates].
*
* @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved.
* @param refresh A boolean flag indicating whether the data should be refreshed.
* */
suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean = false)
/**
* Retrieves updates of quotes for a set of specified cryptocurrencies, identified by their unique IDs.
*
@ -17,7 +38,7 @@ interface QuotesRepository {
* @param currenciesIds The unique identifiers of the cryptocurrencies for which quotes are to be retrieved.
* @return A [Flow] emitting a set of quotes corresponding to the specified cryptocurrencies.
*/
fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean = false): Flow<Set<Quote>>
fun getQuotesUpdatesLegacy(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean = false): Flow<Set<Quote>>
/**
* Retrieves quotes for a set of specified cryptocurrencies, identified by their unique IDs.
@ -31,6 +52,4 @@ interface QuotesRepository {
suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Set<Quote>
suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote?
suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>)
}

View file

@ -13,18 +13,24 @@ internal class MockQuotesRepository(
private val quotes: Flow<Either<DataError, Set<Quote>>>,
) : QuotesRepository {
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Flow<Set<Quote>> {
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.RawID>): Flow<Set<Quote>> {
return quotes.map { it.getOrElse { e -> throw e } }
}
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean) {
/* no-op */
}
override fun getQuotesUpdatesLegacy(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Flow<Set<Quote>> {
return quotes.map { it.getOrElse { e -> throw e } }
}
override suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.RawID>, refresh: Boolean): Set<Quote> {
return getQuotesUpdates(currenciesIds).first()
return getQuotesUpdatesLegacy(currenciesIds).first()
}
override suspend fun getQuoteSync(currencyId: CryptoCurrency.RawID): Quote {
return quotes.map { it.getOrElse { e -> throw e } }.first()
.first { it.rawCurrencyId == currencyId }
}
override suspend fun fetchQuotes(currenciesIds: Set<CryptoCurrency.RawID>) {}
}