Skip to content

Commit 836c888

Browse files
committed
[Jetcaster] Improve scrolling in Home screen
Changes: * Support scrolling entire content in home screen * Fix `PreviewHomeContent` * Remove non-screen composable view model usages
1 parent d04126c commit 836c888

File tree

8 files changed

+318
-243
lines changed

8 files changed

+318
-243
lines changed

Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/Home.kt

Lines changed: 121 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.example.jetcaster.ui.home
1818

19+
import android.util.Log
1920
import androidx.compose.foundation.ExperimentalFoundationApi
2021
import androidx.compose.foundation.Image
2122
import androidx.compose.foundation.background
@@ -37,6 +38,7 @@ import androidx.compose.foundation.layout.statusBars
3738
import androidx.compose.foundation.layout.systemBars
3839
import androidx.compose.foundation.layout.windowInsetsPadding
3940
import androidx.compose.foundation.layout.windowInsetsTopHeight
41+
import androidx.compose.foundation.lazy.LazyColumn
4042
import androidx.compose.foundation.pager.HorizontalPager
4143
import androidx.compose.foundation.pager.PagerState
4244
import androidx.compose.foundation.pager.rememberPagerState
@@ -46,6 +48,7 @@ import androidx.compose.material.Icon
4648
import androidx.compose.material.IconButton
4749
import androidx.compose.material.LocalContentAlpha
4850
import androidx.compose.material.MaterialTheme
51+
import androidx.compose.material.Scaffold
4952
import androidx.compose.material.Surface
5053
import androidx.compose.material.Tab
5154
import androidx.compose.material.TabPosition
@@ -74,8 +77,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
7477
import androidx.lifecycle.viewmodel.compose.viewModel
7578
import coil.compose.AsyncImage
7679
import com.example.jetcaster.R
80+
import com.example.jetcaster.data.Category
7781
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
7985
import com.example.jetcaster.ui.theme.JetcasterTheme
8086
import com.example.jetcaster.ui.theme.Keyline1
8187
import com.example.jetcaster.ui.theme.MinContrastOfPrimaryVsSurface
@@ -102,9 +108,13 @@ fun Home(
102108
isRefreshing = viewState.refreshing,
103109
homeCategories = viewState.homeCategories,
104110
selectedHomeCategory = viewState.selectedHomeCategory,
105-
onCategorySelected = viewModel::onHomeCategorySelected,
111+
discoverViewState = viewState.discoverViewState,
112+
podcastCategoryViewState = viewState.podcastCategoryViewState,
113+
onHomeCategorySelected = viewModel::onHomeCategorySelected,
114+
onCategorySelected = viewModel::onCategorySelected,
106115
onPodcastUnfollowed = viewModel::onPodcastUnfollowed,
107116
navigateToPlayer = navigateToPlayer,
117+
onTogglePodcastFollowed = viewModel::onTogglePodcastFollowed,
108118
modifier = Modifier.fillMaxSize()
109119
)
110120
}
@@ -163,10 +173,14 @@ fun HomeContent(
163173
isRefreshing: Boolean,
164174
selectedHomeCategory: HomeCategory,
165175
homeCategories: List<HomeCategory>,
176+
discoverViewState: DiscoverViewState,
177+
podcastCategoryViewState: PodcastCategoryViewState,
166178
modifier: Modifier = Modifier,
167179
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,
170184
) {
171185
Column(
172186
modifier = modifier.windowInsetsPadding(
@@ -198,72 +212,106 @@ fun HomeContent(
198212
}
199213
}
200214

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-
)
215+
val scrimColor = MaterialTheme.colors.primary.copy(alpha = 0.38f)
216+
Scaffold(
217+
topBar = {
218+
Column(
219+
modifier = Modifier
220+
.fillMaxWidth()
221+
.background(color = scrimColor)
222+
) {
223+
// Draw a scrim over the status bar which matches the app bar
224+
Spacer(
225+
Modifier
226+
.background(appBarColor)
227+
.fillMaxWidth()
228+
.windowInsetsTopHeight(WindowInsets.statusBars)
229+
)
230+
HomeAppBar(
231+
backgroundColor = appBarColor,
232+
modifier = Modifier.fillMaxWidth()
233+
)
234+
}
235+
},
236+
) { contentPadding ->
237+
LazyColumn(
238+
contentPadding = contentPadding,
239+
modifier = Modifier.fillMaxSize()
240+
) {
241+
if (featuredPodcasts.isNotEmpty()) {
242+
item {
243+
FollowedPodcastItem(
244+
items = featuredPodcasts,
245+
pagerState = pagerState,
246+
onPodcastUnfollowed = onPodcastUnfollowed,
247+
modifier = Modifier
248+
.fillMaxWidth()
249+
.verticalGradientScrim(
250+
color = scrimColor,
251+
startYPercentage = 1f,
252+
endYPercentage = 0f
253+
)
254+
)
255+
}
217256

218-
HomeAppBar(
219-
backgroundColor = appBarColor,
220-
modifier = Modifier.fillMaxWidth()
221-
)
257+
if (isRefreshing) {
258+
// TODO show a progress indicator or similar
259+
}
222260

223-
if (featuredPodcasts.isNotEmpty()) {
224-
Spacer(Modifier.height(16.dp))
261+
stickyHeader {
262+
if (homeCategories.isNotEmpty()) {
263+
HomeCategoryTabs(
264+
categories = homeCategories,
265+
selectedCategory = selectedHomeCategory,
266+
onCategorySelected = onHomeCategorySelected
267+
)
268+
}
269+
}
225270

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-
)
271+
when (selectedHomeCategory) {
272+
HomeCategory.Library -> {
273+
// TODO
274+
}
235275

236-
Spacer(Modifier.height(16.dp))
276+
HomeCategory.Discover -> {
277+
discoverItems(
278+
discoverViewState = discoverViewState,
279+
podcastCategoryViewState = podcastCategoryViewState,
280+
navigateToPlayer = navigateToPlayer,
281+
onCategorySelected = onCategorySelected,
282+
onTogglePodcastFollowed = onTogglePodcastFollowed
283+
)
284+
}
285+
}
286+
}
237287
}
238288
}
239289
}
290+
}
291+
}
240292

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-
}
293+
@OptIn(ExperimentalFoundationApi::class)
294+
@Composable
295+
private fun FollowedPodcastItem(
296+
items: PersistentList<PodcastWithExtraInfo>,
297+
pagerState: PagerState,
298+
onPodcastUnfollowed: (String) -> Unit,
299+
modifier: Modifier = Modifier,
300+
) {
301+
Column(modifier = modifier) {
302+
Spacer(Modifier.height(16.dp))
252303

253-
when (selectedHomeCategory) {
254-
HomeCategory.Library -> {
255-
// TODO
256-
}
304+
FollowedPodcasts(
305+
items = items,
306+
pagerState = pagerState,
307+
onPodcastUnfollowed = onPodcastUnfollowed,
308+
modifier = Modifier
309+
.padding(start = Keyline1, top = 16.dp, end = Keyline1)
310+
.fillMaxWidth()
311+
.height(200.dp)
312+
)
257313

258-
HomeCategory.Discover -> {
259-
Discover(
260-
navigateToPlayer = navigateToPlayer,
261-
Modifier
262-
.fillMaxWidth()
263-
.weight(1f)
264-
)
265-
}
266-
}
314+
Spacer(Modifier.height(16.dp))
267315
}
268316
}
269317

@@ -410,23 +458,31 @@ private fun lastUpdated(updated: OffsetDateTime): String {
410458
}
411459
}
412460

413-
/*
414-
TODO: Fix preview error
415461
@Composable
416462
@Preview
417463
fun PreviewHomeContent() {
418464
JetcasterTheme {
419465
HomeContent(
420466
featuredPodcasts = PreviewPodcastsWithExtraInfo,
421467
isRefreshing = false,
422-
homeCategories = HomeCategory.values().asList(),
468+
homeCategories = HomeCategory.entries,
423469
selectedHomeCategory = HomeCategory.Discover,
470+
discoverViewState = DiscoverViewState(
471+
categories = PreviewCategories,
472+
selectedCategory = PreviewCategories.first(),
473+
),
474+
podcastCategoryViewState = PodcastCategoryViewState(
475+
topPodcasts = PreviewPodcastsWithExtraInfo,
476+
episodes = PreviewEpisodeToPodcasts,
477+
),
424478
onCategorySelected = {},
425-
onPodcastUnfollowed = {}
479+
onPodcastUnfollowed = {},
480+
navigateToPlayer = {},
481+
onHomeCategorySelected = {},
482+
onTogglePodcastFollowed = {}
426483
)
427484
}
428485
}
429-
*/
430486

431487
@Composable
432488
@Preview

0 commit comments

Comments
 (0)