Updated on 2026-08-14
This commit is contained in:
parent
75e81283f8
commit
faaa2aad8f
28 changed files with 795 additions and 316 deletions
|
|
@ -45,8 +45,8 @@ internal class DefaultNewsRepository(
|
|||
return updateViewedStatusForNewsBatch(newsBatchFlow, context.coroutineScope)
|
||||
}
|
||||
|
||||
override suspend fun getNews(config: NewsListConfig, limit: Int): List<ShortArticle> {
|
||||
return withContext(dispatchers.io) {
|
||||
override fun getNews(config: NewsListConfig, limit: Int): Flow<List<ShortArticle>> {
|
||||
return flow {
|
||||
val response = newsApi.getNews(
|
||||
page = FIRST_PAGE,
|
||||
limit = limit,
|
||||
|
|
@ -56,25 +56,16 @@ internal class DefaultNewsRepository(
|
|||
categoryIds = config.categoryIds.takeIf { it.isNotEmpty() },
|
||||
).getOrThrow()
|
||||
|
||||
val articles = response.items.map { it.toDomainShortArticle() }
|
||||
val viewedFlags = newsViewedStore.getSync()
|
||||
|
||||
articles.map { article ->
|
||||
val isViewed = viewedFlags[article.id] == true
|
||||
article.copy(viewed = isViewed)
|
||||
val shortArticles = response.items.map { it.toDomainShortArticle() }
|
||||
emit(shortArticles)
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
.combine(newsViewedStore.getAll()) { articlesToUpdate, viewedFlags ->
|
||||
articlesToUpdate.map { article ->
|
||||
val isViewed = viewedFlags[article.id] == true
|
||||
article.copy(viewed = isViewed)
|
||||
}.sortedBy { it.viewed }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getDetailedArticle(newsId: Int, language: String?): DetailedArticle {
|
||||
val cached = newsDetailsStore.getSyncOrNull(newsId)
|
||||
if (cached != null) return cached
|
||||
|
||||
fetchDetailedArticlesInternal(newsIds = listOf(newsId), language = language)
|
||||
|
||||
return requireNotNull(newsDetailsStore.getSyncOrNull(newsId)) {
|
||||
"Unable to load detailed article with id=$newsId"
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeDetailedArticles(): Flow<Map<Int, DetailedArticle>> {
|
||||
|
|
@ -98,10 +89,11 @@ internal class DefaultNewsRepository(
|
|||
) { trendingNews, viewedFlags ->
|
||||
when (trendingNews) {
|
||||
is TrendingNews.Data -> {
|
||||
val articlesWithViewedFlags = trendingNews.articles.map { article ->
|
||||
val isViewed = viewedFlags[article.id] == true
|
||||
article.copy(viewed = isViewed)
|
||||
}
|
||||
val articlesWithViewedFlags = trendingNews.articles
|
||||
.map { article ->
|
||||
article.copy(viewed = viewedFlags[article.id] == true)
|
||||
}
|
||||
.sortedBy { it.viewed }
|
||||
TrendingNews.Data(articlesWithViewedFlags)
|
||||
}
|
||||
is TrendingNews.Error -> trendingNews
|
||||
|
|
@ -128,32 +120,11 @@ internal class DefaultNewsRepository(
|
|||
newsBatchFlow: NewsListBatchFlow,
|
||||
scope: CoroutineScope,
|
||||
): NewsListBatchFlow {
|
||||
return object : NewsListBatchFlow {
|
||||
override val state: StateFlow<BatchListState<Int, List<ShortArticle>>> =
|
||||
combine(
|
||||
newsBatchFlow.state,
|
||||
newsViewedStore.getAll(),
|
||||
) { batchListState, viewedFlags ->
|
||||
val updatedBatches = batchListState.data.map { batch ->
|
||||
val updatedArticles = batch.data.map { article ->
|
||||
val isViewed = viewedFlags[article.id] == true
|
||||
article.copy(viewed = isViewed)
|
||||
}
|
||||
Batch(key = batch.key, data = updatedArticles)
|
||||
}
|
||||
BatchListState(
|
||||
data = updatedBatches,
|
||||
status = batchListState.status,
|
||||
)
|
||||
}.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = BatchListState(emptyList(), newsBatchFlow.state.value.status),
|
||||
)
|
||||
|
||||
override val updateResults: SharedFlow<Pair<Nothing, BatchUpdateResult<Int, List<ShortArticle>>>> =
|
||||
newsBatchFlow.updateResults
|
||||
}
|
||||
return NewsBatchFlowWithViewedStatus(
|
||||
upstream = newsBatchFlow,
|
||||
newsViewedStore = newsViewedStore,
|
||||
scope = scope,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun fetchDetailedArticlesInternal(newsIds: Collection<Int>, language: String?) =
|
||||
|
|
@ -340,6 +311,37 @@ internal class DefaultNewsRepository(
|
|||
val params: NewsListConfig,
|
||||
)
|
||||
|
||||
private class NewsBatchFlowWithViewedStatus(
|
||||
private val upstream: NewsListBatchFlow,
|
||||
newsViewedStore: NewsViewedStore,
|
||||
scope: CoroutineScope,
|
||||
) : NewsListBatchFlow {
|
||||
|
||||
override val state: StateFlow<BatchListState<Int, List<ShortArticle>>> = combine(
|
||||
upstream.state,
|
||||
newsViewedStore.getAll(),
|
||||
) { batchListState, viewedFlags ->
|
||||
val updatedBatches = batchListState.data.map { batch ->
|
||||
val updatedArticles = batch.data.map { article ->
|
||||
val isViewed = viewedFlags[article.id] == true
|
||||
article.copy(viewed = isViewed)
|
||||
}
|
||||
Batch(key = batch.key, data = updatedArticles)
|
||||
}
|
||||
BatchListState(
|
||||
data = updatedBatches,
|
||||
status = batchListState.status,
|
||||
)
|
||||
}.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = BatchListState(emptyList(), upstream.state.value.status),
|
||||
)
|
||||
|
||||
override val updateResults: SharedFlow<Pair<Nothing, BatchUpdateResult<Int, List<ShortArticle>>>>
|
||||
get() = upstream.updateResults
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val INITIAL_BATCH_KEY = 0
|
||||
private const val FIRST_PAGE = 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue