16
16
17
17
package com.example.jetcaster.ui.home
18
18
19
+ import android.util.Log
19
20
import androidx.compose.foundation.ExperimentalFoundationApi
20
21
import androidx.compose.foundation.Image
21
22
import androidx.compose.foundation.background
@@ -37,6 +38,7 @@ import androidx.compose.foundation.layout.statusBars
37
38
import androidx.compose.foundation.layout.systemBars
38
39
import androidx.compose.foundation.layout.windowInsetsPadding
39
40
import androidx.compose.foundation.layout.windowInsetsTopHeight
41
+ import androidx.compose.foundation.lazy.LazyColumn
40
42
import androidx.compose.foundation.pager.HorizontalPager
41
43
import androidx.compose.foundation.pager.PagerState
42
44
import androidx.compose.foundation.pager.rememberPagerState
@@ -46,6 +48,7 @@ import androidx.compose.material.Icon
46
48
import androidx.compose.material.IconButton
47
49
import androidx.compose.material.LocalContentAlpha
48
50
import androidx.compose.material.MaterialTheme
51
+ import androidx.compose.material.Scaffold
49
52
import androidx.compose.material.Surface
50
53
import androidx.compose.material.Tab
51
54
import androidx.compose.material.TabPosition
@@ -74,8 +77,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
74
77
import androidx.lifecycle.viewmodel.compose.viewModel
75
78
import coil.compose.AsyncImage
76
79
import com.example.jetcaster.R
80
+ import com.example.jetcaster.data.Category
77
81
import com.example.jetcaster.data.PodcastWithExtraInfo
78
- import com.example.jetcaster.ui.home.discover.Discover
82
+ import com.example.jetcaster.ui.home.category.PodcastCategoryViewState
83
+ import com.example.jetcaster.ui.home.discover.DiscoverViewState
84
+ import com.example.jetcaster.ui.home.discover.discoverItems
79
85
import com.example.jetcaster.ui.theme.JetcasterTheme
80
86
import com.example.jetcaster.ui.theme.Keyline1
81
87
import com.example.jetcaster.ui.theme.MinContrastOfPrimaryVsSurface
@@ -102,9 +108,13 @@ fun Home(
102
108
isRefreshing = viewState.refreshing,
103
109
homeCategories = viewState.homeCategories,
104
110
selectedHomeCategory = viewState.selectedHomeCategory,
105
- onCategorySelected = viewModel::onHomeCategorySelected,
111
+ discoverViewState = viewState.discoverViewState,
112
+ podcastCategoryViewState = viewState.podcastCategoryViewState,
113
+ onHomeCategorySelected = viewModel::onHomeCategorySelected,
114
+ onCategorySelected = viewModel::onCategorySelected,
106
115
onPodcastUnfollowed = viewModel::onPodcastUnfollowed,
107
116
navigateToPlayer = navigateToPlayer,
117
+ onTogglePodcastFollowed = viewModel::onTogglePodcastFollowed,
108
118
modifier = Modifier .fillMaxSize()
109
119
)
110
120
}
@@ -163,10 +173,14 @@ fun HomeContent(
163
173
isRefreshing : Boolean ,
164
174
selectedHomeCategory : HomeCategory ,
165
175
homeCategories : List <HomeCategory >,
176
+ discoverViewState : DiscoverViewState ,
177
+ podcastCategoryViewState : PodcastCategoryViewState ,
166
178
modifier : Modifier = Modifier ,
167
179
onPodcastUnfollowed : (String ) -> Unit ,
168
- onCategorySelected : (HomeCategory ) -> Unit ,
169
- navigateToPlayer : (String ) -> Unit
180
+ onHomeCategorySelected : (HomeCategory ) -> Unit ,
181
+ onCategorySelected : (Category ) -> Unit ,
182
+ navigateToPlayer : (String ) -> Unit ,
183
+ onTogglePodcastFollowed : (String ) -> Unit ,
170
184
) {
171
185
Column (
172
186
modifier = modifier.windowInsetsPadding(
@@ -191,79 +205,114 @@ fun HomeContent(
191
205
192
206
// When the selected image url changes, call updateColorsFromImageUrl() or reset()
193
207
LaunchedEffect (selectedImageUrl) {
208
+ Log .d(" Jetcaster" , " selectedImageUrl: $selectedImageUrl " )
194
209
if (selectedImageUrl != null ) {
195
210
dominantColorState.updateColorsFromImageUrl(selectedImageUrl)
196
211
} else {
197
212
dominantColorState.reset()
198
213
}
199
214
}
200
215
201
- Column (
202
- modifier = Modifier
203
- .fillMaxWidth()
204
- .verticalGradientScrim(
205
- color = MaterialTheme .colors.primary.copy(alpha = 0.38f ),
206
- startYPercentage = 1f ,
207
- endYPercentage = 0f
208
- )
209
- ) {
210
- // Draw a scrim over the status bar which matches the app bar
211
- Spacer (
212
- Modifier
213
- .background(appBarColor)
214
- .fillMaxWidth()
215
- .windowInsetsTopHeight(WindowInsets .statusBars)
216
- )
216
+ val scrimColor = MaterialTheme .colors.primary.copy(alpha = 0.38f )
217
+ Scaffold (
218
+ topBar = {
219
+ Column (
220
+ modifier = Modifier
221
+ .fillMaxWidth()
222
+ .background(color = scrimColor)
223
+ ) {
224
+ // Draw a scrim over the status bar which matches the app bar
225
+ Spacer (
226
+ Modifier
227
+ .background(appBarColor)
228
+ .fillMaxWidth()
229
+ .windowInsetsTopHeight(WindowInsets .statusBars)
230
+ )
231
+ HomeAppBar (
232
+ backgroundColor = appBarColor,
233
+ modifier = Modifier .fillMaxWidth()
234
+ )
235
+ }
236
+ },
237
+ ) { contentPadding ->
238
+ LazyColumn (
239
+ contentPadding = contentPadding,
240
+ modifier = Modifier .fillMaxSize()
241
+ ) {
242
+ if (featuredPodcasts.isNotEmpty()) {
243
+ item {
244
+ FollowedPodcastItem (
245
+ items = featuredPodcasts,
246
+ pagerState = pagerState,
247
+ onPodcastUnfollowed = onPodcastUnfollowed,
248
+ modifier = Modifier
249
+ .fillMaxWidth()
250
+ .verticalGradientScrim(
251
+ color = scrimColor,
252
+ startYPercentage = 1f ,
253
+ endYPercentage = 0f
254
+ )
255
+ )
256
+ }
217
257
218
- HomeAppBar (
219
- backgroundColor = appBarColor,
220
- modifier = Modifier .fillMaxWidth()
221
- )
258
+ if (isRefreshing) {
259
+ // TODO show a progress indicator or similar
260
+ }
222
261
223
- if (featuredPodcasts.isNotEmpty()) {
224
- Spacer (Modifier .height(16 .dp))
262
+ stickyHeader {
263
+ if (homeCategories.isNotEmpty()) {
264
+ HomeCategoryTabs (
265
+ categories = homeCategories,
266
+ selectedCategory = selectedHomeCategory,
267
+ onCategorySelected = onHomeCategorySelected
268
+ )
269
+ }
270
+ }
225
271
226
- FollowedPodcasts (
227
- items = featuredPodcasts,
228
- pagerState = pagerState,
229
- onPodcastUnfollowed = onPodcastUnfollowed,
230
- modifier = Modifier
231
- .padding(start = Keyline1 , top = 16 .dp, end = Keyline1 )
232
- .fillMaxWidth()
233
- .height(200 .dp)
234
- )
272
+ when (selectedHomeCategory) {
273
+ HomeCategory .Library -> {
274
+ // TODO
275
+ }
235
276
236
- Spacer (Modifier .height(16 .dp))
277
+ HomeCategory .Discover -> {
278
+ discoverItems(
279
+ discoverViewState = discoverViewState,
280
+ podcastCategoryViewState = podcastCategoryViewState,
281
+ navigateToPlayer = navigateToPlayer,
282
+ onCategorySelected = onCategorySelected,
283
+ onTogglePodcastFollowed = onTogglePodcastFollowed
284
+ )
285
+ }
286
+ }
287
+ }
237
288
}
238
289
}
239
290
}
291
+ }
292
+ }
240
293
241
- if (isRefreshing) {
242
- // TODO show a progress indicator or similar
243
- }
244
-
245
- if (homeCategories.isNotEmpty()) {
246
- HomeCategoryTabs (
247
- categories = homeCategories,
248
- selectedCategory = selectedHomeCategory,
249
- onCategorySelected = onCategorySelected
250
- )
251
- }
294
+ @OptIn(ExperimentalFoundationApi ::class )
295
+ @Composable
296
+ private fun FollowedPodcastItem (
297
+ items : PersistentList <PodcastWithExtraInfo >,
298
+ pagerState : PagerState ,
299
+ onPodcastUnfollowed : (String ) -> Unit ,
300
+ modifier : Modifier = Modifier ,
301
+ ) {
302
+ Column (modifier = modifier) {
303
+ Spacer (Modifier .height(16 .dp))
252
304
253
- when (selectedHomeCategory) {
254
- HomeCategory .Library -> {
255
- // TODO
256
- }
305
+ FollowedPodcasts (
306
+ items = items,
307
+ pagerState = pagerState,
308
+ onPodcastUnfollowed = onPodcastUnfollowed,
309
+ modifier = Modifier
310
+ .padding(start = Keyline1 , top = 16 .dp, end = Keyline1 )
311
+ .fillMaxWidth()
312
+ .height(200 .dp)
313
+ )
257
314
258
- HomeCategory .Discover -> {
259
- Discover (
260
- navigateToPlayer = navigateToPlayer,
261
- Modifier
262
- .fillMaxWidth()
263
- .weight(1f )
264
- )
265
- }
266
- }
315
+ Spacer (Modifier .height(16 .dp))
267
316
}
268
317
}
269
318
@@ -410,23 +459,31 @@ private fun lastUpdated(updated: OffsetDateTime): String {
410
459
}
411
460
}
412
461
413
- /*
414
- TODO: Fix preview error
415
462
@Composable
416
463
@Preview
417
464
fun PreviewHomeContent () {
418
465
JetcasterTheme {
419
466
HomeContent (
420
467
featuredPodcasts = PreviewPodcastsWithExtraInfo ,
421
468
isRefreshing = false ,
422
- homeCategories = HomeCategory.values().asList() ,
469
+ homeCategories = HomeCategory .entries ,
423
470
selectedHomeCategory = HomeCategory .Discover ,
471
+ discoverViewState = DiscoverViewState (
472
+ categories = PreviewCategories ,
473
+ selectedCategory = PreviewCategories .first(),
474
+ ),
475
+ podcastCategoryViewState = PodcastCategoryViewState (
476
+ topPodcasts = PreviewPodcastsWithExtraInfo ,
477
+ episodes = PreviewEpisodeToPodcasts ,
478
+ ),
424
479
onCategorySelected = {},
425
- onPodcastUnfollowed = {}
480
+ onPodcastUnfollowed = {},
481
+ navigateToPlayer = {},
482
+ onHomeCategorySelected = {},
483
+ onTogglePodcastFollowed = {}
426
484
)
427
485
}
428
486
}
429
- */
430
487
431
488
@Composable
432
489
@Preview
0 commit comments