@@ -52,6 +52,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilte
5252import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel
5353import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
5454import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
55+ import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource
5556import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources
5657import com.google.samples.apps.nowinandroid.core.model.data.previewTopics
5758import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
@@ -66,24 +67,27 @@ fun TopicRoute(
6667 modifier : Modifier = Modifier ,
6768 viewModel : TopicViewModel = hiltViewModel(),
6869) {
69- val uiState: TopicScreenUiState by viewModel.uiState.collectAsStateWithLifecycle()
70+ val topicUiState: TopicUiState by viewModel.topicUiState.collectAsStateWithLifecycle()
71+ val newsUiState: NewsUiState by viewModel.newUiState.collectAsStateWithLifecycle()
7072
7173 TopicScreen (
72- topicState = uiState.topicState ,
73- newsState = uiState.newsState ,
74+ topicUiState = topicUiState ,
75+ newsUiState = newsUiState ,
7476 modifier = modifier,
7577 onBackClick = onBackClick,
7678 onFollowClick = viewModel::followTopicToggle,
79+ onBookmarkChanged = viewModel::bookmarkNews,
7780 )
7881}
7982
8083@VisibleForTesting
8184@Composable
8285internal fun TopicScreen (
83- topicState : TopicUiState ,
84- newsState : NewsUiState ,
86+ topicUiState : TopicUiState ,
87+ newsUiState : NewsUiState ,
8588 onBackClick : () -> Unit ,
8689 onFollowClick : (Boolean ) -> Unit ,
90+ onBookmarkChanged : (String , Boolean ) -> Unit ,
8791 modifier : Modifier = Modifier ,
8892) {
8993 LazyColumn (
@@ -93,7 +97,7 @@ internal fun TopicScreen(
9397 item {
9498 Spacer (Modifier .windowInsetsTopHeight(WindowInsets .safeDrawing))
9599 }
96- when (topicState ) {
100+ when (topicUiState ) {
97101 Loading -> item {
98102 NiaLoadingWheel (
99103 modifier = modifier,
@@ -106,14 +110,15 @@ internal fun TopicScreen(
106110 TopicToolbar (
107111 onBackClick = onBackClick,
108112 onFollowClick = onFollowClick,
109- uiState = topicState .followableTopic,
113+ uiState = topicUiState .followableTopic,
110114 )
111115 }
112116 TopicBody (
113- name = topicState.followableTopic.topic.name,
114- description = topicState.followableTopic.topic.longDescription,
115- news = newsState,
116- imageUrl = topicState.followableTopic.topic.imageUrl
117+ name = topicUiState.followableTopic.topic.name,
118+ description = topicUiState.followableTopic.topic.longDescription,
119+ news = newsUiState,
120+ imageUrl = topicUiState.followableTopic.topic.imageUrl,
121+ onBookmarkChanged = onBookmarkChanged
117122 )
118123 }
119124 }
@@ -127,14 +132,15 @@ private fun LazyListScope.TopicBody(
127132 name : String ,
128133 description : String ,
129134 news : NewsUiState ,
130- imageUrl : String
135+ imageUrl : String ,
136+ onBookmarkChanged : (String , Boolean ) -> Unit
131137) {
132138 // TODO: Show icon if available
133139 item {
134140 TopicHeader (name, description, imageUrl)
135141 }
136142
137- TopicCards (news)
143+ TopicCards (news, onBookmarkChanged )
138144}
139145
140146@Composable
@@ -161,14 +167,17 @@ private fun TopicHeader(name: String, description: String, imageUrl: String) {
161167 }
162168}
163169
164- private fun LazyListScope.TopicCards (news : NewsUiState ) {
170+ private fun LazyListScope.TopicCards (
171+ news : NewsUiState ,
172+ onBookmarkChanged : (String , Boolean ) -> Unit
173+ ) {
165174 when (news) {
166175 is NewsUiState .Success -> {
167176 newsResourceCardItems(
168177 items = news.news,
169- newsResourceMapper = { it },
170- isBookmarkedMapper = { /* TODO */ false },
171- onToggleBookmark = { /* TODO */ },
178+ newsResourceMapper = { it.newsResource },
179+ isBookmarkedMapper = { it.isSaved },
180+ onToggleBookmark = { onBookmarkChanged(it.newsResource.id, ! it.isSaved) },
172181 itemModifier = Modifier .padding(24 .dp)
173182 )
174183 }
@@ -188,7 +197,7 @@ private fun TopicBodyPreview() {
188197 LazyColumn {
189198 TopicBody (
190199 " Jetpack Compose" , " Lorem ipsum maximum" ,
191- NewsUiState .Success (emptyList()), " "
200+ NewsUiState .Success (emptyList()), " " , { _, _ -> }
192201 )
193202 }
194203 }
@@ -237,10 +246,18 @@ fun TopicScreenPopulated() {
237246 NiaTheme {
238247 NiaBackground {
239248 TopicScreen (
240- topicState = TopicUiState .Success (FollowableTopic (previewTopics[0 ], false )),
241- newsState = NewsUiState .Success (previewNewsResources),
249+ topicUiState = TopicUiState .Success (FollowableTopic (previewTopics[0 ], false )),
250+ newsUiState = NewsUiState .Success (
251+ previewNewsResources.mapIndexed { index, newsResource ->
252+ SaveableNewsResource (
253+ newsResource = newsResource,
254+ isSaved = index % 2 == 0 ,
255+ )
256+ }
257+ ),
242258 onBackClick = {},
243- onFollowClick = {}
259+ onFollowClick = {},
260+ onBookmarkChanged = { _, _ -> },
244261 )
245262 }
246263 }
@@ -252,10 +269,11 @@ fun TopicScreenLoading() {
252269 NiaTheme {
253270 NiaBackground {
254271 TopicScreen (
255- topicState = TopicUiState .Loading ,
256- newsState = NewsUiState .Loading ,
272+ topicUiState = TopicUiState .Loading ,
273+ newsUiState = NewsUiState .Loading ,
257274 onBackClick = {},
258- onFollowClick = {}
275+ onFollowClick = {},
276+ onBookmarkChanged = { _, _ -> },
259277 )
260278 }
261279 }
0 commit comments