Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-23 15:36:52 +04:00
parent a70d51e55d
commit 72989eab5a
10 changed files with 19 additions and 43 deletions

View file

@ -26,6 +26,7 @@ import com.tangem.domain.news.repository.NewsRepository
import com.tangem.pagination.*
import com.tangem.pagination.exception.EndOfPaginationException
import com.tangem.pagination.fetcher.BatchFetcher
import com.tangem.utils.SupportedLanguages
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runSuspendCatching
import com.tangem.utils.logging.TangemLogger
@ -47,6 +48,9 @@ internal class DefaultNewsRepository(
private val newsErrorResolver: NewsErrorResolver,
) : NewsRepository {
private val language: String
get() = SupportedLanguages.getCurrentSupportedLanguageCode()
override fun getNewsListBatchFlow(context: NewsListBatchingContext, batchSize: Int): NewsListBatchFlow {
val newsBatchFlow = BatchListSource(
fetchDispatcher = dispatchers.io,
@ -63,7 +67,7 @@ internal class DefaultNewsRepository(
val items = newsApi.getNews(
page = FIRST_PAGE,
limit = limit,
language = config.language,
language = language,
snapshot = config.snapshot,
tokenIds = config.tokenIds.takeIf { it.isNotEmpty() },
categoryIds = config.categoryIds.takeIf { it.isNotEmpty() },
@ -105,12 +109,10 @@ internal class DefaultNewsRepository(
}
}
override suspend fun fetchDetailedArticles(
newsIds: Collection<Int>,
language: String?,
): Either<Map<Int, Throwable>, Unit> = fetchDetailedArticlesInternal(newsIds = newsIds, language = language)
override suspend fun fetchDetailedArticles(newsIds: Collection<Int>): Either<Map<Int, Throwable>, Unit> =
fetchDetailedArticlesInternal(newsIds = newsIds, language = language)
override suspend fun fetchTrendingNews(limit: Int, language: String?) {
override suspend fun fetchTrendingNews(limit: Int) {
fetchAndStoreTrendingNews(limit = limit, language = language)
}
@ -259,7 +261,7 @@ internal class DefaultNewsRepository(
)
}
private class NewsBatchFetcher(
private inner class NewsBatchFetcher(
private val newsApi: NewsApi,
private val batchSize: Int,
private val newsViewedStore: NewsViewedStore,
@ -326,7 +328,7 @@ internal class DefaultNewsRepository(
val response = newsApi.getNews(
page = page,
limit = limit,
language = params.language,
language = language,
snapshot = snapshotOverride?.takeIf { it.isNotEmpty() },
tokenIds = params.tokenIds.takeIf { it.isNotEmpty() },
categoryIds = params.categoryIds.takeIf { it.isNotEmpty() },

View file

@ -7,14 +7,12 @@ import kotlinx.serialization.Serializable
*
[REDACTED_AUTHOR]
*
* @param language device locale (ex: en, ru).
* @param snapshot id snapshot (`meta.asOf`) to stabilize responses.
* @param tokenIds filter by tokens.
* @param categoryIds filter by category.
*/
@Serializable
data class NewsListConfig(
val language: String,
val snapshot: String?,
val tokenIds: List<String> = emptyList(),
val categoryIds: List<Int> = emptyList(),

View file

@ -38,15 +38,14 @@ interface NewsRepository {
/**
* Fetches and caches detailed articles for provided ids in parallel.
*/
suspend fun fetchDetailedArticles(newsIds: Collection<Int>, language: String?): Either<Map<Int, Throwable>, Unit>
suspend fun fetchDetailedArticles(newsIds: Collection<Int>): Either<Map<Int, Throwable>, Unit>
/**
* Fetch list of trending news by limit and with correct locale and store it in runtime data store.
*
* @param limit
* @param language current device locale
*/
suspend fun fetchTrendingNews(limit: Int, language: String?)
suspend fun fetchTrendingNews(limit: Int)
/**
* Observes trending news with runtime viewed flag support.

View file

@ -2,7 +2,6 @@ package com.tangem.domain.news.usecase
import arrow.core.Either
import com.tangem.domain.news.repository.NewsRepository
import java.util.Locale
/**
* Fetches trending news to store it in runtime data store.
@ -11,10 +10,7 @@ import java.util.Locale
class FetchTrendingNewsUseCase(private val newsRepository: NewsRepository) {
suspend operator fun invoke(): Either<Throwable, Unit> = Either.catch {
newsRepository.fetchTrendingNews(
limit = LIMIT_FOR_TRENDING_NEWS,
language = Locale.getDefault().language,
)
newsRepository.fetchTrendingNews(limit = LIMIT_FOR_TRENDING_NEWS)
}
companion object {

View file

@ -24,6 +24,6 @@ class ObserveNewsDetailsUseCase(
/**
* Prefetches the given article ids (can be called with current + next ids for pager preloading).
*/
suspend fun prefetch(newsIds: Collection<Int>, language: String?): Either<Map<Int, Throwable>, Unit> =
repository.fetchDetailedArticles(newsIds, language)
suspend fun prefetch(newsIds: Collection<Int>): Either<Map<Int, Throwable>, Unit> =
repository.fetchDetailedArticles(newsIds)
}

View file

@ -336,7 +336,6 @@ internal class MarketsTokenDetailsModel @Inject constructor(
getNewsUseCase.getNews(
limit = RELATED_NEWS_LIMIT,
newsListConfig = NewsListConfig(
language = Locale.getDefault().language,
snapshot = null,
tokenIds = listOf(params.token.id.value),
),

View file

@ -32,12 +32,11 @@ import com.tangem.features.feed.ui.news.details.state.NewsDetailsUM
import com.tangem.features.feed.ui.news.details.state.RelatedTokensUM
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import com.tangem.utils.logging.TangemLogger
import java.util.Locale
import javax.inject.Inject
@Stable
@ -60,14 +59,12 @@ internal class NewsDetailsModel @Inject constructor(
) : Model() {
private val params = paramsContainer.require<DefaultNewsDetailsComponent.Params>()
private val currentLanguage = Locale.getDefault().language
private val newsDetailsConverter = NewsDetailsConverter(onRelatedArticleClick = ::onRelatedArticleClick)
private val paginationManager: NewsDetailsPaginationManager? = params.paginationConfig?.let { config ->
NewsDetailsPaginationManager(
getNewsListBatchFlowUseCase = getNewsListBatchFlowUseCase,
currentLanguage = Provider { config.language },
currentCategoryIds = Provider { config.categoryIds },
modelScope = modelScope,
dispatchers = dispatchers,
@ -212,10 +209,7 @@ internal class NewsDetailsModel @Inject constructor(
}
private suspend fun initialPrefetch() {
observeNewsDetailsUseCase.prefetch(
newsIds = params.preselectedArticlesId,
language = currentLanguage,
).onLeft { errors ->
observeNewsDetailsUseCase.prefetch(newsIds = params.preselectedArticlesId).onLeft { errors ->
errors.onEach { (newsId, error) ->
when {
// an article is opened from deeplink and is not found

View file

@ -14,7 +14,6 @@ import kotlinx.coroutines.launch
@Suppress("LongParameterList")
internal class NewsDetailsPaginationManager(
private val observeNewsDetailsUseCase: ObserveNewsDetailsUseCase,
private val currentLanguage: Provider<String>,
getNewsListBatchFlowUseCase: GetNewsListBatchFlowUseCase,
dispatchers: CoroutineDispatcherProvider,
currentCategoryIds: Provider<List<Int>>,
@ -23,7 +22,6 @@ internal class NewsDetailsPaginationManager(
isRedesignEnabled: Boolean,
) : NewsListBatchFlowManager(
getNewsListBatchFlowUseCase = getNewsListBatchFlowUseCase,
currentLanguage = currentLanguage,
currentCategoryIds = currentCategoryIds,
modelScope = modelScope,
dispatchers = dispatchers,
@ -53,10 +51,7 @@ internal class NewsDetailsPaginationManager(
.distinctUntilChanged()
.collect { newIds ->
if (newIds.isNotEmpty()) {
observeNewsDetailsUseCase.prefetch(
newsIds = newIds,
language = currentLanguage(),
)
observeNewsDetailsUseCase.prefetch(newsIds = newIds)
_cachedPrefetchedIds.update { it + newIds }
}
}

View file

@ -11,13 +11,12 @@ import com.tangem.domain.news.usecase.GetNewsCategoriesUseCase
import com.tangem.domain.news.usecase.GetNewsListBatchFlowUseCase
import com.tangem.features.feed.components.news.list.DefaultNewsListComponent
import com.tangem.features.feed.model.news.list.analytics.NewsListAnalyticsEvent
import com.tangem.features.feed.model.news.list.statemanager.NewsListStateManager
import com.tangem.features.feed.model.news.list.loader.NewsCategoriesLoader
import com.tangem.features.feed.model.news.list.statemanager.NewsListBatchFlowManager
import com.tangem.features.feed.model.news.list.statemanager.NewsListStateManager
import com.tangem.features.feed.ui.news.list.state.NewsListState
import com.tangem.features.feed.ui.news.list.state.NewsListUM
import com.tangem.utils.Provider
import com.tangem.utils.SupportedLanguages
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -41,7 +40,6 @@ internal class NewsListModel @Inject constructor(
private val params = paramsContainer.require<DefaultNewsListComponent.Params>()
private val selectedCategoryId = MutableStateFlow<Int?>(null)
private val currentLanguage = SupportedLanguages.getCurrentSupportedLanguageCode()
private val categoriesLoader by lazy {
NewsCategoriesLoader(
@ -54,7 +52,6 @@ internal class NewsListModel @Inject constructor(
private val batchFlowManager by lazy {
NewsListBatchFlowManager(
getNewsListBatchFlowUseCase = getNewsListBatchFlowUseCase,
currentLanguage = Provider { currentLanguage },
currentCategoryIds = Provider {
selectedCategoryId.value?.takeIf { it > 0 }?.let { listOf(it) }.orEmpty()
},
@ -158,7 +155,6 @@ internal class NewsListModel @Inject constructor(
private fun createNewsListConfig(): NewsListConfig {
return NewsListConfig(
language = currentLanguage,
snapshot = null,
tokenIds = emptyList(),
categoryIds = selectedCategoryId.value?.takeIf { it > 0 }?.let { listOf(it) }.orEmpty(),

View file

@ -20,11 +20,9 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
@Suppress("LongParameterList")
internal open class NewsListBatchFlowManager(
private val isRedesignEnabled: Boolean,
getNewsListBatchFlowUseCase: GetNewsListBatchFlowUseCase,
private val currentLanguage: Provider<String>,
private val currentCategoryIds: Provider<List<Int>>,
protected val modelScope: CoroutineScope,
protected val dispatchers: CoroutineDispatcherProvider,
@ -146,7 +144,6 @@ internal open class NewsListBatchFlowManager(
private fun createNewsListConfig(): NewsListConfig {
return NewsListConfig(
language = currentLanguage(),
snapshot = null,
tokenIds = emptyList(),
categoryIds = currentCategoryIds(),