diff --git a/app/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailScaffold.kt b/app/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailScaffold.kt index 8b646338..70bca9c9 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailScaffold.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/common/media/MediaDetailScaffold.kt @@ -30,68 +30,60 @@ fun MediaDetailScaffold( contentOverlap: Dp = 24.dp, contentSpacing: Dp = 16.dp, topBar: @Composable () -> Unit = {}, - heroContent: @Composable ColumnScope.() -> Unit, - content: @Composable ColumnScope.() -> Unit + heroContent: @Composable ColumnScope.(Modifier) -> Unit, + content: @Composable ColumnScope.(Modifier) -> Unit ) { val scheme = MaterialTheme.colorScheme val isHomeMediaTransitionActive = isHomeMediaSharedBoundsTransitionActive() - Box( - modifier = modifier - .fillMaxSize() - .background(scheme.background) - ) { - Box( + Scaffold( + modifier = Modifier.fillMaxSize(), + containerColor = scheme.background, + topBar = { + if (!isHomeMediaTransitionActive) { + topBar() + } + } + ) { innerPadding -> + Column( modifier = Modifier - .homeMediaSharedBoundsDestination() - .fillMaxWidth() - .height(imageHeight) + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(bottom = innerPadding.calculateBottomPadding()), + verticalArrangement = Arrangement.spacedBy(contentSpacing) ) { - PurefinAsyncImage( - model = imageUrl, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) Box( modifier = Modifier - .matchParentSize() - .background( - Brush.verticalGradient( - colors = listOf( - Color.Transparent, - Color.Transparent, - scheme.background.copy(alpha = 0.5f), - scheme.background + .homeMediaSharedBoundsDestination() + .fillMaxWidth() + .height(imageHeight) + ) { + PurefinAsyncImage( + model = imageUrl, + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + Box( + modifier = Modifier + .matchParentSize() + .background( + Brush.verticalGradient( + colors = listOf( + Color.Transparent, + Color.Transparent, + scheme.background.copy(alpha = 0.5f), + scheme.background + ) ) ) - ) - ) - } - - Scaffold( - modifier = Modifier.fillMaxSize(), - containerColor = Color.Transparent, - topBar = { - if (!isHomeMediaTransitionActive) { - topBar() - } + ) } - ) { innerPadding -> - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .padding(bottom = innerPadding.calculateBottomPadding()) - .padding(horizontal = 16.dp) - .padding(top = imageHeight - contentOverlap), - verticalArrangement = Arrangement.spacedBy(contentSpacing) - ) { - if (!isHomeMediaTransitionActive) { - heroContent() - content() - } + if (!isHomeMediaTransitionActive) { + heroContent(Modifier.padding(horizontal = 16.dp)) + content(Modifier.padding(horizontal = 16.dp)) } } } } + diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/episode/EpisodeScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/episode/EpisodeScreen.kt index 0a886854..cd39a2c6 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/episode/EpisodeScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/episode/EpisodeScreen.kt @@ -95,14 +95,18 @@ private fun EpisodeScreenInternal( onBack = onBack, ) }, - heroContent = { - EpisodeHeroContent(episode = episode) + heroContent = { _modifier -> + EpisodeHeroContent( + episode = episode, + modifier = _modifier + ) } - ) { + ) { _modifier -> EpisodeDetails( episode = episode, downloadState = downloadState, onDownloadClick = onDownloadClick, + modifier = _modifier ) } } @@ -119,22 +123,31 @@ private fun EpisodeHeroContent( color = scheme.onBackground, fontSize = 32.sp, fontWeight = FontWeight.Bold, - lineHeight = 38.sp + lineHeight = 38.sp, + modifier = modifier ) Text( text = "Episode ${episode.index}", color = scheme.onBackground, fontSize = 14.sp, - fontWeight = FontWeight.Medium + fontWeight = FontWeight.Medium, + modifier = modifier + ) + EpisodeMetaChips( + episode = episode, + modifier = modifier ) - EpisodeMetaChips(episode = episode) } @Composable -private fun EpisodeMetaChips(episode: Episode) { +private fun EpisodeMetaChips( + episode: Episode, + modifier: Modifier +) { MediaMetadataFlowRow( items = listOf(episode.releaseDate, episode.rating, episode.runtime, episode.format), - highlightedItem = episode.format + highlightedItem = episode.format, + modifier = modifier ) } diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/episode/components/EpisodeComponents.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/episode/components/EpisodeComponents.kt index da4573db..4cd1af22 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/episode/components/EpisodeComponents.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/episode/components/EpisodeComponents.kt @@ -102,6 +102,7 @@ internal fun EpisodeDetails( episode: Episode, downloadState: DownloadState, onDownloadClick: () -> Unit, + modifier: Modifier ) { val scheme = MaterialTheme.colorScheme @@ -115,9 +116,10 @@ internal fun EpisodeDetails( } MediaSynopsis( - synopsis = episode.synopsis + synopsis = episode.synopsis, + modifier = modifier ) - Row() { + Row(modifier = modifier) { MediaResumeButton( text = mediaPlayButtonText(episode.progress, episode.watched), progress = mediaPlaybackProgress(episode.progress), @@ -146,16 +148,18 @@ internal fun EpisodeDetails( foregroundColor = MaterialTheme.colorScheme.onSurface, //TODO fix it audioTrack = "ENG", - subtitles = "ENG" + subtitles = "ENG", + modifier = modifier ) if (episode.cast.isNotEmpty()) { Text( text = "Cast", color = scheme.onBackground, fontSize = 18.sp, - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, + modifier = modifier ) - Spacer(modifier = Modifier.height(12.dp)) + Spacer(modifier = modifier.height(12.dp)) //TODO use it // MediaCastRow( // cast = episode.cast diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/movie/MovieScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/movie/MovieScreen.kt index 119f17dc..c18e5d49 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/movie/MovieScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/movie/MovieScreen.kt @@ -77,14 +77,18 @@ private fun MovieScreenInternal( topBar = { MovieTopBar(onBack = onBack) }, - heroContent = { - MovieHeroContent(movie = movie) + heroContent = { _modifier -> + MovieHeroContent( + movie = movie, + modifier = _modifier + ) } - ) { + ) { _modifier -> MovieDetails( movie = movie, downloadState = downloadState, onDownloadClick = onDownloadClick, + modifier = _modifier ) } } @@ -101,12 +105,14 @@ private fun MovieHeroContent( color = scheme.onBackground, fontSize = 32.sp, fontWeight = FontWeight.Bold, - lineHeight = 38.sp + lineHeight = 38.sp, + modifier = modifier ) // Spacer(modifier = Modifier.height(8.dp)) MediaMetadataFlowRow( items = listOf(movie.year, movie.rating, movie.runtime, movie.format), - highlightedItem = movie.format + highlightedItem = movie.format, + modifier = modifier ) } diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/movie/components/MovieComponents.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/movie/components/MovieComponents.kt index e85ede35..e5e16537 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/movie/components/MovieComponents.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/movie/components/MovieComponents.kt @@ -63,6 +63,7 @@ internal fun MovieDetails( movie: Movie, downloadState: DownloadState, onDownloadClick: () -> Unit, + modifier: Modifier ) { val scheme = MaterialTheme.colorScheme @@ -76,9 +77,10 @@ internal fun MovieDetails( } MediaSynopsis( - synopsis = movie.synopsis + synopsis = movie.synopsis, + modifier = modifier ) - Row() { + Row(modifier = modifier) { MediaResumeButton( text = mediaPlayButtonText(movie.progress, movie.watched), progress = mediaPlaybackProgress(movie.progress), @@ -106,7 +108,8 @@ internal fun MovieDetails( backgroundColor = MaterialTheme.colorScheme.surface, foregroundColor = MaterialTheme.colorScheme.onSurface, audioTrack = "ENG", - subtitles = "ENG" + subtitles = "ENG", + modifier = modifier ) if (movie.cast.isNotEmpty()) { Spacer(modifier = Modifier.height(24.dp)) @@ -114,9 +117,10 @@ internal fun MovieDetails( text = "Cast", color = scheme.onBackground, fontSize = 18.sp, - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, + modifier = modifier ) - Spacer(modifier = Modifier.height(12.dp)) + Spacer(modifier = modifier.height(12.dp)) //TODO fix // MediaCastRow( // cast = movie.cast, diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/series/SeriesScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/series/SeriesScreen.kt index f02e47f9..ebabe8e8 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/series/SeriesScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/series/SeriesScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -17,6 +16,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import hu.bbara.purefin.core.download.DownloadState import hu.bbara.purefin.core.feature.content.series.SeriesViewModel import hu.bbara.purefin.core.image.ArtworkKind @@ -151,10 +151,13 @@ private fun SeriesScreenInternal( topBar = { SeriesTopBar(onBack = onBack) }, - heroContent = { - SeriesHeroContent(series = series) + heroContent = { _modifier -> + SeriesHeroContent( + series = series, + modifier = _modifier + ) } - ) { + ) { _modifier -> if (selectedSeason != null) { SeriesActionButtons( nextUpEpisode = nextUpEpisode, @@ -165,7 +168,8 @@ private fun SeriesScreenInternal( offline = offline, onDownloadOptionSelected = { option -> onDownloadOptionSelected(option, selectedSeason) - } + }, + modifier = _modifier ) } MediaSynopsis( @@ -173,22 +177,26 @@ private fun SeriesScreenInternal( bodyColor = scheme.onSurface, bodyFontSize = 13.sp, bodyLineHeight = null, - titleSpacing = 8.dp + titleSpacing = 8.dp, + modifier = _modifier ) if (selectedSeason != null) { SeasonTabs( seasons = series.seasons, selectedSeason = selectedSeason, - onSelect = { selectedSeasonId = it.id } + onSelect = { selectedSeasonId = it.id }, + modifier = _modifier ) EpisodeCarousel( episodes = selectedSeason.episodes, + modifier = _modifier ) } else { Text( text = "Loading seasons...", color = scheme.onSurfaceVariant, - fontSize = 13.sp + fontSize = 13.sp, + modifier = _modifier ) } if (series.cast.isNotEmpty()) { @@ -196,9 +204,10 @@ private fun SeriesScreenInternal( text = "Cast", color = scheme.onBackground, fontSize = 18.sp, - fontWeight = FontWeight.Bold + fontWeight = FontWeight.Bold, + modifier = _modifier ) - Spacer(modifier = Modifier.height(12.dp)) + Spacer(modifier = _modifier.height(12.dp)) CastRow(cast = series.cast) } } @@ -216,9 +225,13 @@ private fun SeriesHeroContent( color = scheme.onBackground, fontSize = 30.sp, fontWeight = FontWeight.Bold, - lineHeight = 36.sp + lineHeight = 36.sp, + modifier = modifier + ) + SeriesMetaChips( + series = series, + modifier = modifier ) - SeriesMetaChips(series = series) } private fun SeriesDownloadOption.canPerform( diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/series/components/SeriesComponents.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/series/components/SeriesComponents.kt index 76235792..c75ea3c2 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/series/components/SeriesComponents.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/series/components/SeriesComponents.kt @@ -103,9 +103,13 @@ internal fun SeriesTopBar( } @Composable -internal fun SeriesMetaChips(series: Series) { +internal fun SeriesMetaChips( + series: Series, + modifier: Modifier = Modifier +) { MediaMetadataFlowRow( - items = listOf(series.year, "${series.seasonCount} Seasons") + items = listOf(series.year, "${series.seasonCount} Seasons"), + modifier = modifier ) } @@ -142,7 +146,10 @@ internal fun SeriesActionButtons( } } } - Row(verticalAlignment = Alignment.CenterVertically) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = modifier + ) { MediaResumeButton( text = mediaPlayButtonText(nextUpEpisode?.progress, nextUpEpisode?.watched), progress = mediaPlaybackProgress(nextUpEpisode?.progress), diff --git a/core-ui/src/main/java/hu/bbara/purefin/ui/common/media/MediaMetadataFlowRow.kt b/core-ui/src/main/java/hu/bbara/purefin/ui/common/media/MediaMetadataFlowRow.kt index 93625f3a..b8d7aa3a 100644 --- a/core-ui/src/main/java/hu/bbara/purefin/ui/common/media/MediaMetadataFlowRow.kt +++ b/core-ui/src/main/java/hu/bbara/purefin/ui/common/media/MediaMetadataFlowRow.kt @@ -3,21 +3,21 @@ package hu.bbara.purefin.ui.common.media import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import androidx.compose.material3.MaterialTheme @OptIn(ExperimentalLayoutApi::class) @Composable fun MediaMetadataFlowRow( items: List, - modifier: Modifier = Modifier, highlightedItem: String? = null, highlightedBackground: Color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f), highlightedBorder: Color = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f), - highlightedTextColor: Color = MaterialTheme.colorScheme.primary + highlightedTextColor: Color = MaterialTheme.colorScheme.primary, + modifier: Modifier = Modifier ) { FlowRow( modifier = modifier,