diff --git a/app-tv/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailShell.kt b/app-tv/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailShell.kt index fcfcab87..d746f510 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailShell.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailShell.kt @@ -15,14 +15,10 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -31,13 +27,13 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import hu.bbara.purefin.ui.common.image.PurefinAsyncImage -import hu.bbara.purefin.image.ImageUrlBuilder import hu.bbara.purefin.image.ArtworkKind +import hu.bbara.purefin.image.ImageUrlBuilder +import hu.bbara.purefin.ui.common.image.PurefinAsyncImage internal val MediaDetailHorizontalPadding = 48.dp -private val MediaDetailHeaderTopPadding = 104.dp -private val MediaDetailHeaderBottomPadding = 36.dp +private val MediaDetailHeaderTopPadding = 24.dp +private val MediaDetailHeaderBottomPadding = 24.dp private const val MediaDetailBodyImageWidthFraction = 0.66f internal val TvMediaDetailBringIntoViewSpec: BringIntoViewSpec = @@ -61,19 +57,13 @@ internal val TvMediaDetailBringIntoViewSpec: BringIntoViewSpec = internal fun TvMediaDetailScaffold( resetScrollKey: Any, modifier: Modifier = Modifier, - bodyContent: LazyListScope.(Modifier) -> Unit = { _ -> } + bodyContent: @Composable (Modifier) -> Unit = {} ) { val scheme = MaterialTheme.colorScheme val contentPadding = Modifier.padding(horizontal = MediaDetailHorizontalPadding) - val listState = rememberLazyListState() - - LaunchedEffect(resetScrollKey) { - listState.scrollToItem(0) - } CompositionLocalProvider(LocalBringIntoViewSpec provides TvMediaDetailBringIntoViewSpec) { - LazyColumn( - state = listState, + Column( modifier = modifier .fillMaxSize() .background(scheme.background) diff --git a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/episode/TvEpisodeScreen.kt b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/episode/TvEpisodeScreen.kt index c4888b60..62484ea5 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/episode/TvEpisodeScreen.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/episode/TvEpisodeScreen.kt @@ -85,50 +85,44 @@ internal fun TvEpisodeScreenContent( resetScrollKey = episode.id, modifier = modifier ) { - item(key = "episode-hero") { - TvMediaDetailBodyBox( - backgroundImageUrl = ImageUrlBuilder.finishImageUrl(episode.imageUrlPrefix, ArtworkKind.PRIMARY), - modifier = it - ) { - TvEpisodeHeroSection( - episode = episode, - seriesTitle = seriesTitle, - onPlay = onPlay, - playFocusRequester = playFocusRequester, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(12.dp)) - } + TvMediaDetailBodyBox( + backgroundImageUrl = ImageUrlBuilder.finishImageUrl( + episode.imageUrlPrefix, + ArtworkKind.PRIMARY + ), + modifier = it + ) { + TvEpisodeHeroSection( + episode = episode, + seriesTitle = seriesTitle, + onPlay = onPlay, + playFocusRequester = playFocusRequester, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(12.dp)) } - item(key = "episode-overview") { - Column(modifier = it.fillMaxWidth()) { - Spacer(modifier = Modifier.height(16.dp)) - MediaDetailOverviewSection( - synopsis = episode.synopsis, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - } + Column(modifier = it.fillMaxWidth()) { + Spacer(modifier = Modifier.height(16.dp)) + MediaDetailOverviewSection( + synopsis = episode.synopsis, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(20.dp)) } - item(key = "episode-playback") { - Column(modifier = it.fillMaxWidth()) { - MediaDetailPlaybackSection( - audioTrack = "ENG", - subtitles = "ENG", - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - } + Column(modifier = it.fillMaxWidth()) { + MediaDetailPlaybackSection( + audioTrack = "ENG", + subtitles = "ENG", + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(20.dp)) } - if (episode.cast.isNotEmpty()) { - item(key = "episode-cast") { - Column(modifier = it.fillMaxWidth()) { - MediaDetailSectionTitle(text = "Cast") - Spacer(modifier = Modifier.height(14.dp)) -// MediaCastRow(cast = episode.cast) - Spacer(modifier = Modifier.height(24.dp)) - } - } + Column(modifier = it.fillMaxWidth()) { + MediaDetailSectionTitle(text = "Cast") + Spacer(modifier = Modifier.height(14.dp)) +// MediaCastRow(cast = episode.cast) + Spacer(modifier = Modifier.height(24.dp)) } } } + diff --git a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/movie/TvMovieScreen.kt b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/movie/TvMovieScreen.kt index e216f7be..8112196a 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/movie/TvMovieScreen.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/movie/TvMovieScreen.kt @@ -27,7 +27,9 @@ import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen @Composable fun TvMovieScreen( - movie: MovieDto, viewModel: MovieScreenViewModel = hiltViewModel(), modifier: Modifier = Modifier + movie: MovieDto, + viewModel: MovieScreenViewModel = hiltViewModel(), + modifier: Modifier = Modifier ) { LaunchedEffect(movie.id) { viewModel.selectMovie(movie.id) @@ -63,49 +65,41 @@ internal fun TvMovieScreenContent( resetScrollKey = movie.id, modifier = modifier ) { - item(key = "movie-hero") { - TvMediaDetailBodyBox( - backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix), - modifier = it - ) { - TvMovieHeroSection( - movie = movie, - onPlay = onPlay, - playFocusRequester = playFocusRequester, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(12.dp)) - } + TvMediaDetailBodyBox( + backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix), + modifier = Modifier + ) { + TvMovieHeroSection( + movie = movie, + onPlay = onPlay, + playFocusRequester = playFocusRequester, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(12.dp)) } - item(key = "movie-overview") { - Column(modifier = it.fillMaxWidth()) { - Spacer(modifier = Modifier.height(16.dp)) - MediaDetailOverviewSection( - synopsis = movie.synopsis, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - } + Column(modifier = Modifier.fillMaxWidth()) { + Spacer(modifier = Modifier.height(16.dp)) + MediaDetailOverviewSection( + synopsis = movie.synopsis, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(20.dp)) } - item(key = "movie-playback") { - Column(modifier = it.fillMaxWidth()) { - MediaDetailPlaybackSection( - audioTrack = "ENG", - subtitles = "ENG", - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - } - } - if (movie.cast.isNotEmpty()) { - item(key = "movie-cast") { - Column(modifier = it.fillMaxWidth()) { - MediaDetailSectionTitle(text = "Cast") - Spacer(modifier = Modifier.height(14.dp)) + } + Column(modifier = Modifier.fillMaxWidth()) { + MediaDetailPlaybackSection( + audioTrack = "ENG", + subtitles = "ENG", + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(20.dp)) + } + if (movie.cast.isNotEmpty()) { + Column(modifier = Modifier.fillMaxWidth()) { + MediaDetailSectionTitle(text = "Cast") + Spacer(modifier = Modifier.height(14.dp)) // MediaCastRow(cast = movie.cast) - Spacer(modifier = Modifier.height(24.dp)) - } - } + Spacer(modifier = Modifier.height(24.dp)) } } } diff --git a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/series/TvSeriesScreen.kt b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/series/TvSeriesScreen.kt index f67b5e8f..002e9fc4 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/series/TvSeriesScreen.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/series/TvSeriesScreen.kt @@ -81,63 +81,54 @@ internal fun TvSeriesScreenContent( resetScrollKey = series.id, modifier = modifier ) { - item(key = "series-hero") { - TvMediaDetailBodyBox( - backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix), - modifier = it - ) { - TvSeriesHeroSection( - series = series, - nextUpEpisode = nextUpEpisode, - onPlayEpisode = { onPlayEpisode(it.id) }, - playFocusRequester = playFocusRequester, - firstContentFocusRequester = firstContentFocusRequester, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(12.dp)) - } - } - item(key = "series-overview") { - Column(modifier = it.fillMaxWidth()) { - Spacer(modifier = Modifier.height(16.dp)) - MediaDetailOverviewSection( - synopsis = series.synopsis, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(24.dp)) - } - } - item(key = "series-season-tabs") { - TvSeasonTabs( - seasons = series.seasons, - selectedSeason = selectedSeason, - firstItemFocusRequester = firstContentFocusRequester, - firstItemTestTag = SeriesFirstSeasonTabTag, - onSelect = { selectedSeason = it }, - modifier = it + TvMediaDetailBodyBox( + backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix), + modifier = it + ) { + TvSeriesHeroSection( + series = series, + nextUpEpisode = nextUpEpisode, + onPlayEpisode = { onPlayEpisode(it.id) }, + playFocusRequester = playFocusRequester, + firstContentFocusRequester = firstContentFocusRequester, + modifier = Modifier.fillMaxWidth() ) + Spacer(modifier = Modifier.height(12.dp)) } - item(key = "series-episodes") { - Spacer(modifier = Modifier.height(20.dp)) - TvEpisodeCarousel( - episodes = selectedSeason.episodes, - modifier = it + Column(modifier = it.fillMaxWidth()) { + Spacer(modifier = Modifier.height(16.dp)) + MediaDetailOverviewSection( + synopsis = series.synopsis, + modifier = Modifier.fillMaxWidth() ) + Spacer(modifier = Modifier.height(24.dp)) } + TvSeasonTabs( + seasons = series.seasons, + selectedSeason = selectedSeason, + firstItemFocusRequester = firstContentFocusRequester, + firstItemTestTag = SeriesFirstSeasonTabTag, + onSelect = { selectedSeason = it }, + modifier = it + ) + Spacer(modifier = Modifier.height(20.dp)) + TvEpisodeCarousel( + episodes = selectedSeason.episodes, + modifier = it + ) if (series.cast.isNotEmpty()) { - item(key = "series-cast") { - Column(modifier = it) { - Spacer(modifier = Modifier.height(20.dp)) - MediaDetailSectionTitle(text = "Cast") - Spacer(modifier = Modifier.height(14.dp)) - CastRow(cast = series.cast) - Spacer(modifier = Modifier.height(24.dp)) - } + Column(modifier = it) { + Spacer(modifier = Modifier.height(20.dp)) + MediaDetailSectionTitle(text = "Cast") + Spacer(modifier = Modifier.height(14.dp)) + CastRow(cast = series.cast) + Spacer(modifier = Modifier.height(24.dp)) } } } } + private fun Series.defaultSeason(): Season { for (season in seasons) { if (season.episodes.any { !it.watched }) {