Skip to content

Commit 18b2b85

Browse files
committed
- Update TopicViewModel to use PagingData<TopicUi> directly, removing the intermediate UiState and fetchTopicList logic.
- Modify `TopicRepository.getTopicsPage` to return `List<TopicUi>`. - Make `TopicRepository.getTopics` private as it's now an internal detail. - Update UI components (`TopicList`, `TopicCard`, `TopicScreenUI`) and preview utils to reflect these changes. - Adjust `TopicPagingSource` to work with `TopicUi`. - Rename `ItemTopic` to `TopicUi` and move it to a separate file.
1 parent 8af5f62 commit 18b2b85

File tree

9 files changed

+30
-87
lines changed

9 files changed

+30
-87
lines changed

composeApp/src/androidMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/previews/PreviewUtils.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.Kotl
66
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.Section
77
import com.developersbreach.kotlindictionarymultiplatform.data.detail.model.Syntax
88
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
9-
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.ItemTopic
9+
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.TopicUi
1010
import kotlinx.coroutines.flow.Flow
1111
import kotlinx.coroutines.flow.flowOf
1212

@@ -79,16 +79,16 @@ private fun sampleTopicList(): List<Topic> {
7979
)
8080
}
8181

82-
internal fun sampleTopicUiList(): List<ItemTopic> {
82+
internal fun sampleTopicUiList(): List<TopicUi> {
8383
return sampleTopicList().map { topic ->
84-
ItemTopic(
84+
TopicUi(
8585
name = topic.name ?: "",
8686
initial = topic.name?.firstOrNull()?.uppercase() ?: "",
8787
description = topic.description ?: "",
8888
)
8989
}
9090
}
9191

92-
internal fun samplePagingData(): Flow<PagingData<ItemTopic>> {
92+
internal fun samplePagingData(): Flow<PagingData<TopicUi>> {
9393
return flowOf(PagingData.from(sampleTopicUiList()))
9494
}

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/data/topic/repository/TopicRepository.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
66
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
77
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.toTopic
88
import com.developersbreach.kotlindictionarymultiplatform.core.network.topicSource.FirestoreConstants
9-
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.ItemTopic
9+
import com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic.TopicUi
1010
import io.ktor.client.HttpClient
1111
import io.ktor.client.call.body
1212
import io.ktor.client.request.get
1313

1414
class TopicRepository(
1515
private val httpClient: HttpClient,
1616
) {
17-
suspend fun getTopics(): Either<Throwable, List<Topic>> {
17+
private suspend fun getTopics(): Either<Throwable, List<Topic>> {
1818
return Either.catch {
1919
val topicResponse: TopicResponse = httpClient.get(FirestoreConstants.TOPICS_URL).body()
2020
topicResponse.topics.map { it.toTopic() }
@@ -25,20 +25,20 @@ class TopicRepository(
2525
page: Int,
2626
pageSize: Int,
2727
query: String,
28-
): List<ItemTopic> {
28+
): List<TopicUi> {
2929
val allTopics = getTopics().getOrElse { emptyList() }
30-
val filtered = allTopics
30+
val filteredTopics = allTopics
3131
.filter { it.name?.contains(query, ignoreCase = true) == true }
3232
.sortedBy { it.name?.lowercase() ?: "" }
3333
.map { topic ->
34-
ItemTopic(
34+
TopicUi(
3535
name = topic.name ?: "",
3636
initial = topic.name?.firstOrNull()?.uppercase() ?: "",
3737
description = topic.description ?: "",
3838
)
3939
}
4040
val fromIndex = (page - 1) * pageSize
41-
val toIndex = (fromIndex + pageSize).coerceAtMost(filtered.size)
42-
return if (fromIndex < filtered.size) filtered.subList(fromIndex, toIndex) else emptyList()
41+
val toIndex = (fromIndex + pageSize).coerceAtMost(filteredTopics.size)
42+
return if (fromIndex < filteredTopics.size) filteredTopics.subList(fromIndex, toIndex) else emptyList()
4343
}
4444
}

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicCard.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import com.developersbreach.designsystem.components.KdText
2525

2626
@Composable
2727
fun TopicCard(
28-
itemTopic: ItemTopic,
28+
topicUI: TopicUi,
2929
topic: String,
3030
description: String,
3131
onCardClick: () -> Unit,
@@ -60,7 +60,7 @@ fun TopicCard(
6060
) {
6161
KdText(
6262
modifier = Modifier,
63-
text = itemTopic.initial,
63+
text = topicUI.initial,
6464
)
6565
}
6666

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicList.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import app.cash.paging.compose.LazyPagingItems
1010

1111
@Composable
1212
fun TopicList(
13-
topics: LazyPagingItems<ItemTopic>,
13+
topics: LazyPagingItems<TopicUi>,
1414
onTopicClick: (String) -> Unit,
1515
) {
1616
LazyColumn(
@@ -22,7 +22,7 @@ fun TopicList(
2222
topic?.let {
2323
TopicCard(
2424
topic = it.name,
25-
itemTopic = it,
25+
topicUI = it,
2626
description = it.description,
2727
onCardClick = { onTopicClick(it.name) },
2828
)

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicPagingSource.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,27 @@ import com.developersbreach.kotlindictionarymultiplatform.data.topic.repository.
77
class TopicPagingSource(
88
private val repository: TopicRepository,
99
private val query: String,
10-
) : PagingSource<Int, ItemTopic>() {
10+
) : PagingSource<Int, TopicUi>() {
1111

1212
override suspend fun load(
1313
params: LoadParams<Int>,
14-
): LoadResult<Int, ItemTopic> {
14+
): LoadResult<Int, TopicUi> {
1515
val page = params.key ?: 1
1616
val pageSize = params.loadSize
1717
return try {
18-
val topics = repository.getTopicsPage(page, pageSize, query)
18+
val pageItems = repository.getTopicsPage(page, pageSize, query)
1919
LoadResult.Page(
20-
data = topics,
20+
data = pageItems,
2121
prevKey = if (page == 1) null else page - 1,
22-
nextKey = if (topics.isEmpty()) null else page + 1,
22+
nextKey = if (pageItems.isEmpty()) null else page + 1,
2323
)
2424
} catch (e: Exception) {
2525
LoadResult.Error(e)
2626
}
2727
}
2828

2929
override fun getRefreshKey(
30-
state: PagingState<Int, ItemTopic>,
30+
state: PagingState<Int, TopicUi>,
3131
): Int {
3232
return 1
3333
}

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicScreenUI.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import app.cash.paging.compose.LazyPagingItems
1313

1414
@Composable
1515
fun TopicScreenUI(
16-
topics: LazyPagingItems<ItemTopic>,
16+
topics: LazyPagingItems<TopicUi>,
1717
searchQuery: String,
1818
onQueryChange: (String) -> Unit,
1919
onTopicClick: (String) -> Unit,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.developersbreach.kotlindictionarymultiplatform.ui.screens.topic
2+
3+
data class TopicUi(
4+
val name: String,
5+
val initial: String,
6+
val description: String,
7+
)

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicUiState.kt

Lines changed: 0 additions & 16 deletions
This file was deleted.

composeApp/src/commonMain/kotlin/com/developersbreach/kotlindictionarymultiplatform/ui/screens/topic/TopicViewModel.kt

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ import androidx.lifecycle.viewModelScope
55
import app.cash.paging.Pager
66
import app.cash.paging.PagingConfig
77
import app.cash.paging.PagingData
8-
import com.developersbreach.kotlindictionarymultiplatform.data.topic.model.Topic
9-
import kotlinx.coroutines.launch
108
import com.developersbreach.kotlindictionarymultiplatform.data.topic.repository.TopicRepository
11-
import com.developersbreach.kotlindictionarymultiplatform.ui.components.UiState
129
import kotlinx.coroutines.ExperimentalCoroutinesApi
1310
import kotlinx.coroutines.flow.Flow
1411
import kotlinx.coroutines.flow.MutableStateFlow
@@ -25,11 +22,8 @@ class TopicViewModel(
2522
private val _searchQuery = MutableStateFlow("")
2623
val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()
2724

28-
private val _uiState: MutableStateFlow<UiState<TopicUi>> = MutableStateFlow(UiState.Loading)
29-
val uiState: StateFlow<UiState<TopicUi>> = _uiState.asStateFlow()
30-
3125
@OptIn(ExperimentalCoroutinesApi::class)
32-
val pagingDataFlow: Flow<PagingData<ItemTopic>> = searchQuery
26+
val pagingDataFlow: Flow<PagingData<TopicUi>> = searchQuery
3327
.flatMapLatest { query ->
3428
Pager(
3529
config = PagingConfig(pageSize = 8),
@@ -42,51 +36,9 @@ class TopicViewModel(
4236
PagingData.empty(),
4337
)
4438

45-
init {
46-
viewModelScope.launch {
47-
fetchTopicList()
48-
}
49-
}
50-
51-
private suspend fun fetchTopicList() {
52-
_uiState.value = UiState.Success(TopicUi(isLoading = true))
53-
repository.getTopics().fold(
54-
ifLeft = { _uiState.value = UiState.Error(it) },
55-
ifRight = { list ->
56-
val sorted = list.sortedBy { it.name?.lowercase() ?: "" }
57-
applyFilters(sorted, _searchQuery.value)
58-
},
59-
)
60-
}
61-
6239
fun updateSearchQuery(
6340
newQuery: String,
6441
) {
6542
_searchQuery.value = newQuery
66-
// Optionally, you may want to refresh the paging source here if needed
67-
}
68-
69-
private fun applyFilters(
70-
topics: List<Topic>,
71-
query: String,
72-
) {
73-
val filtered = topics
74-
.filter { it.name?.contains(query, ignoreCase = true) == true }
75-
.map { topic ->
76-
ItemTopic(
77-
name = topic.name ?: "",
78-
initial = topic.name?.firstOrNull()?.uppercase() ?: "",
79-
description = topic.description ?: "",
80-
)
81-
}
82-
83-
_uiState.value = UiState.Success(
84-
TopicUi(
85-
isLoading = false,
86-
searchQuery = query,
87-
topics = topics,
88-
filteredTopics = filtered,
89-
),
90-
)
9143
}
9244
}

0 commit comments

Comments
 (0)