Updated on 2026-08-14
This commit is contained in:
parent
4ec02d0447
commit
f426a1f922
26 changed files with 748 additions and 247 deletions
|
|
@ -10,7 +10,7 @@ import com.tangem.domain.markets.repositories.MarketsTokenRepository
|
|||
import com.tangem.pagination.*
|
||||
import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
internal class DefaultMarketsTokenRepository(
|
||||
private val marketsApi: TangemTechMarketsApi,
|
||||
|
|
@ -20,42 +20,61 @@ internal class DefaultMarketsTokenRepository(
|
|||
|
||||
private val tokenListConverter = TokenMarketListConverter()
|
||||
|
||||
private val tokenMarketsFetcher
|
||||
get() = LimitOffsetBatchFetcher(
|
||||
prefetchDistance = 150,
|
||||
batchSize = 100,
|
||||
subFetcher = object : LimitOffsetBatchFetcher.SubFetcher<TokenMarketListConfig, List<TokenMarket>> {
|
||||
private fun createTokenMarketsFetcher(firstBatchSize: Int, nextBatchSize: Int) = LimitOffsetBatchFetcher(
|
||||
prefetchDistance = firstBatchSize,
|
||||
batchSize = nextBatchSize,
|
||||
subFetcher = object : LimitOffsetBatchFetcher.SubFetcher<TokenMarketListConfig, List<TokenMarket>> {
|
||||
|
||||
var requestTimeStamp: Long? = null // TODO when backend is ready
|
||||
val requestTimeStamp = AtomicLong(0)
|
||||
|
||||
override suspend fun fetch(
|
||||
request: LimitOffsetBatchFetcher.Request<TokenMarketListConfig>,
|
||||
lastResult: BatchFetchResult<List<TokenMarket>>?,
|
||||
): BatchFetchResult<List<TokenMarket>> {
|
||||
val res = retryOnError(priority = true) {
|
||||
marketsApi.getCoinsList(
|
||||
currency = request.params.fiatPriceCurrency,
|
||||
interval = request.params.priceChangeInterval.toRequestParam(),
|
||||
order = request.params.order.toRequestParam(),
|
||||
search = request.params.searchText,
|
||||
generalCoins = request.params.showUnder100kMarketCapTokens.not(),
|
||||
offset = request.offset,
|
||||
limit = request.limit,
|
||||
).getOrThrow()
|
||||
}
|
||||
override suspend fun fetch(
|
||||
request: LimitOffsetBatchFetcher.Request<TokenMarketListConfig>,
|
||||
lastResult: BatchFetchResult<List<TokenMarket>>?,
|
||||
isFirstBatchFetching: Boolean,
|
||||
): BatchFetchResult<List<TokenMarket>> {
|
||||
val searchText =
|
||||
if (request.params.searchText.isNullOrBlank()) null else request.params.searchText
|
||||
|
||||
val last = res.tokens.size < request.limit
|
||||
|
||||
return BatchFetchResult.Success(
|
||||
data = tokenListConverter.convert(res),
|
||||
last = last,
|
||||
)
|
||||
val requestCall = suspend {
|
||||
marketsApi.getCoinsList(
|
||||
currency = request.params.fiatPriceCurrency,
|
||||
interval = request.params.priceChangeInterval.toRequestParam(),
|
||||
order = request.params.order.toRequestParam(),
|
||||
search = searchText,
|
||||
generalCoins = request.params.showUnder100kMarketCapTokens.not(),
|
||||
offset = request.offset,
|
||||
limit = request.limit,
|
||||
).getOrThrow()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// we shouldn't infinitely retry on the first batch request
|
||||
val res = if (isFirstBatchFetching) {
|
||||
requestCall()
|
||||
} else {
|
||||
retryOnError(priority = true) {
|
||||
requestCall()
|
||||
}
|
||||
}
|
||||
|
||||
if (isFirstBatchFetching) {
|
||||
requestTimeStamp.set(0) // TODO when backend is ready
|
||||
}
|
||||
|
||||
val last = res.tokens.size < request.limit
|
||||
|
||||
return BatchFetchResult.Success(
|
||||
data = tokenListConverter.convert(res),
|
||||
last = last,
|
||||
empty = res.tokens.isEmpty(),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
override fun getTokenListFlow(
|
||||
batchingContext: BatchingContext<Int, TokenMarketListConfig, TokenMarketUpdateRequest>,
|
||||
firstBatchSize: Int,
|
||||
nextBatchSize: Int,
|
||||
): BatchFlow<Int, List<TokenMarket>, TokenMarketUpdateRequest> {
|
||||
val tokenMarketsUpdateFetcher = MarketsBatchUpdateFetcher(
|
||||
tangemTechApi = tangemTechApi,
|
||||
|
|
@ -66,7 +85,7 @@ internal class DefaultMarketsTokenRepository(
|
|||
fetchDispatcher = dispatcherProvider.io,
|
||||
context = batchingContext,
|
||||
generateNewKey = { it.size },
|
||||
batchFetcher = tokenMarketsFetcher,
|
||||
batchFetcher = createTokenMarketsFetcher(firstBatchSize = firstBatchSize, nextBatchSize = nextBatchSize),
|
||||
updateFetcher = tokenMarketsUpdateFetcher,
|
||||
).toBatchFlow()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ import com.tangem.utils.converter.Converter
|
|||
class TokenMarketListConverter : Converter<TokenMarketListResponse, List<TokenMarket>> {
|
||||
|
||||
override fun convert(value: TokenMarketListResponse): List<TokenMarket> {
|
||||
val imageHost = value.imageHost ?: run {
|
||||
if (value.tokens.isEmpty()) {
|
||||
return emptyList()
|
||||
} else {
|
||||
error("imageHost cannot be null")
|
||||
}
|
||||
}
|
||||
|
||||
return value.tokens.map { token ->
|
||||
TokenMarket(
|
||||
id = token.id,
|
||||
|
|
@ -16,7 +24,7 @@ class TokenMarketListConverter : Converter<TokenMarketListResponse, List<TokenMa
|
|||
symbol = token.symbol,
|
||||
marketRating = token.marketRating,
|
||||
marketCap = token.marketCap,
|
||||
imageHost = value.imageHost,
|
||||
imageHost = imageHost,
|
||||
tokenQuotes = TokenQuotes(
|
||||
currentPrice = token.currentPrice,
|
||||
priceChanges = mapOf(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue