Move TV detail overview and playback into body

This commit is contained in:
2026-03-29 19:19:12 +02:00
parent c163a714d8
commit cc1e1d7df9
10 changed files with 134 additions and 139 deletions

View File

@@ -40,6 +40,8 @@ class EpisodeScreenContentTest {
composeRule.onNodeWithText("Severance").assertIsDisplayed() composeRule.onNodeWithText("Severance").assertIsDisplayed()
composeRule.onNodeWithText("The You You Are").assertIsDisplayed() composeRule.onNodeWithText("The You You Are").assertIsDisplayed()
composeRule.onNodeWithText("Episode 4").assertIsDisplayed() composeRule.onNodeWithText("Episode 4").assertIsDisplayed()
composeRule.onNodeWithText("Overview").assertIsDisplayed()
composeRule.onAllNodesWithText("Playback").assertCountEquals(1)
composeRule.onNodeWithTag(EpisodePlayButtonTag).assertIsDisplayed().assertIsFocused() composeRule.onNodeWithTag(EpisodePlayButtonTag).assertIsDisplayed().assertIsFocused()
composeRule.onNodeWithText("Series").assertIsDisplayed() composeRule.onNodeWithText("Series").assertIsDisplayed()
} }
@@ -63,6 +65,8 @@ class EpisodeScreenContentTest {
composeRule.waitForIdle() composeRule.waitForIdle()
composeRule.onNodeWithText("Overview").assertIsDisplayed()
composeRule.onAllNodesWithText("Playback").assertCountEquals(1)
composeRule.onNodeWithTag(EpisodePlayButtonTag).assertIsDisplayed() composeRule.onNodeWithTag(EpisodePlayButtonTag).assertIsDisplayed()
composeRule.onAllNodesWithText("Series").assertCountEquals(0) composeRule.onAllNodesWithText("Series").assertCountEquals(0)
} }

View File

@@ -1,9 +1,11 @@
package hu.bbara.purefin.app.content.movie package hu.bbara.purefin.app.content.movie
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsFocused import androidx.compose.ui.test.assertIsFocused
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
@@ -34,7 +36,8 @@ class MovieScreenContentTest {
composeRule.waitForIdle() composeRule.waitForIdle()
composeRule.onNodeWithText("Blade Runner 2049").assertIsDisplayed() composeRule.onNodeWithText("Blade Runner 2049").assertIsDisplayed()
composeRule.onNodeWithText("Playback").assertIsDisplayed() composeRule.onNodeWithText("Overview").assertIsDisplayed()
composeRule.onAllNodesWithText("Playback").assertCountEquals(1)
composeRule.onNodeWithTag(MoviePlayButtonTag).assertIsDisplayed().assertIsFocused() composeRule.onNodeWithTag(MoviePlayButtonTag).assertIsDisplayed().assertIsFocused()
composeRule.onNodeWithContentDescription("Back").assertIsDisplayed() composeRule.onNodeWithContentDescription("Back").assertIsDisplayed()
} }

View File

@@ -35,6 +35,7 @@ class SeriesScreenContentTest {
composeRule.waitForIdle() composeRule.waitForIdle()
composeRule.onNodeWithText("Severance").assertIsDisplayed() composeRule.onNodeWithText("Severance").assertIsDisplayed()
composeRule.onNodeWithText("Overview").assertIsDisplayed()
composeRule.onNodeWithText("Up Next").assertIsDisplayed() composeRule.onNodeWithText("Up Next").assertIsDisplayed()
composeRule.onNodeWithTag(SeriesPlayButtonTag).assertIsDisplayed().assertIsFocused() composeRule.onNodeWithTag(SeriesPlayButtonTag).assertIsDisplayed().assertIsFocused()
composeRule.onNodeWithText("Season 1").assertIsDisplayed() composeRule.onNodeWithText("Season 1").assertIsDisplayed()
@@ -55,6 +56,7 @@ class SeriesScreenContentTest {
composeRule.waitForIdle() composeRule.waitForIdle()
composeRule.onNodeWithText("Overview").assertIsDisplayed()
composeRule.onNodeWithText("Library Status").assertIsDisplayed() composeRule.onNodeWithText("Library Status").assertIsDisplayed()
composeRule.onNodeWithTag(SeriesFirstSeasonTabTag).assertIsDisplayed().assertIsFocused() composeRule.onNodeWithTag(SeriesFirstSeasonTabTag).assertIsDisplayed().assertIsFocused()
} }

View File

@@ -21,10 +21,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import hu.bbara.purefin.common.ui.MediaMetaChip import hu.bbara.purefin.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar
import hu.bbara.purefin.common.ui.components.MediaDetailsTopBarShortcut import hu.bbara.purefin.common.ui.components.MediaDetailsTopBarShortcut
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
import hu.bbara.purefin.common.ui.components.MediaResumeButton import hu.bbara.purefin.common.ui.components.MediaResumeButton
import hu.bbara.purefin.core.data.navigation.Route import hu.bbara.purefin.core.data.navigation.Route
import hu.bbara.purefin.core.model.Episode import hu.bbara.purefin.core.model.Episode
@@ -137,44 +135,6 @@ internal fun EpisodeHeroSection(
} }
} }
@Composable
internal fun EpisodeOverviewPanel(
episode: Episode,
modifier: Modifier = Modifier
) {
val scheme = MaterialTheme.colorScheme
val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.85f)
Column(modifier = modifier) {
MediaSynopsis(
synopsis = episode.synopsis,
title = "Overview",
titleColor = scheme.onSurface,
bodyColor = mutedStrong,
titleFontSize = 20.sp,
bodyFontSize = 16.sp,
bodyLineHeight = 24.sp,
titleSpacing = 10.dp,
collapsedLines = 5,
collapseInitially = false
)
Spacer(modifier = Modifier.height(24.dp))
Text(
text = "Playback",
color = scheme.onSurface,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(14.dp))
MediaPlaybackSettings(
backgroundColor = scheme.surfaceContainerHigh,
foregroundColor = scheme.onSurface,
audioTrack = "ENG",
subtitles = "ENG"
)
}
}
private fun Episode.playButtonText(): String { private fun Episode.playButtonText(): String {
return if ((progress ?: 0.0) > 0.0 && !watched) "Resume" else "Play" return if ((progress ?: 0.0) > 0.0 && !watched) "Resume" else "Play"
} }

View File

@@ -2,6 +2,7 @@ package hu.bbara.purefin.app.content.episode
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -14,7 +15,8 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.MediaCastRow import hu.bbara.purefin.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.PurefinWaitingScreen import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaDetailHeaderRow import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection
import hu.bbara.purefin.common.ui.components.MediaDetailPlaybackSection
import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.core.data.navigation.EpisodeDto import hu.bbara.purefin.core.data.navigation.EpisodeDto
@@ -99,30 +101,39 @@ internal fun EpisodeScreenContent(
) )
}, },
heroContent = { heroContent = {
MediaDetailHeaderRow(
leftContent = { headerModifier ->
EpisodeHeroSection( EpisodeHeroSection(
episode = episode, episode = episode,
seriesTitle = seriesTitle, seriesTitle = seriesTitle,
onPlay = onPlay, onPlay = onPlay,
playFocusRequester = playFocusRequester, playFocusRequester = playFocusRequester,
modifier = headerModifier modifier = Modifier.fillMaxWidth()
)
},
rightContent = { panelModifier ->
EpisodeOverviewPanel(
episode = episode,
modifier = panelModifier
)
}
) )
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
} }
) { ) {
item {
Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp))
MediaDetailOverviewSection(
synopsis = episode.synopsis,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(20.dp))
}
}
item {
Column(modifier = it.fillMaxWidth()) {
MediaDetailPlaybackSection(
audioTrack = "ENG",
subtitles = "ENG",
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(20.dp))
}
}
if (episode.cast.isNotEmpty()) { if (episode.cast.isNotEmpty()) {
item { item {
Column(modifier = it) { Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(8.dp))
MediaDetailSectionTitle(text = "Cast") MediaDetailSectionTitle(text = "Cast")
Spacer(modifier = Modifier.height(14.dp)) Spacer(modifier = Modifier.height(14.dp))
MediaCastRow(cast = episode.cast) MediaCastRow(cast = episode.cast)

View File

@@ -21,9 +21,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import hu.bbara.purefin.common.ui.MediaMetaChip import hu.bbara.purefin.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar
import hu.bbara.purefin.common.ui.components.MediaPlaybackSettings
import hu.bbara.purefin.common.ui.components.MediaResumeButton import hu.bbara.purefin.common.ui.components.MediaResumeButton
import hu.bbara.purefin.core.model.Movie import hu.bbara.purefin.core.model.Movie
@@ -94,44 +92,6 @@ internal fun MovieHeroSection(
} }
} }
@Composable
internal fun MovieOverviewPanel(
movie: Movie,
modifier: Modifier = Modifier
) {
val scheme = MaterialTheme.colorScheme
val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.85f)
Column(modifier = modifier) {
MediaSynopsis(
synopsis = movie.synopsis,
title = "Overview",
titleColor = scheme.onSurface,
bodyColor = mutedStrong,
titleFontSize = 20.sp,
bodyFontSize = 16.sp,
bodyLineHeight = 24.sp,
titleSpacing = 10.dp,
collapsedLines = 5,
collapseInitially = false
)
Spacer(modifier = Modifier.height(24.dp))
Text(
text = "Playback",
color = scheme.onSurface,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(14.dp))
MediaPlaybackSettings(
backgroundColor = scheme.surfaceContainerHigh,
foregroundColor = scheme.onSurface,
audioTrack = movie.audioTrack,
subtitles = movie.subtitles
)
}
}
private fun Movie.playButtonText(): String { private fun Movie.playButtonText(): String {
return if ((progress ?: 0.0) > 0.0 && !watched) "Resume" else "Play" return if ((progress ?: 0.0) > 0.0 && !watched) "Resume" else "Play"
} }

View File

@@ -2,6 +2,7 @@ package hu.bbara.purefin.app.content.movie
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -14,7 +15,8 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.MediaCastRow import hu.bbara.purefin.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.PurefinWaitingScreen import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaDetailHeaderRow import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection
import hu.bbara.purefin.common.ui.components.MediaDetailPlaybackSection
import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.core.data.navigation.MovieDto import hu.bbara.purefin.core.data.navigation.MovieDto
@@ -67,29 +69,38 @@ internal fun MovieScreenContent(
) )
}, },
heroContent = { heroContent = {
MediaDetailHeaderRow(
leftContent = { headerModifier ->
MovieHeroSection( MovieHeroSection(
movie = movie, movie = movie,
onPlay = onPlay, onPlay = onPlay,
playFocusRequester = playFocusRequester, playFocusRequester = playFocusRequester,
modifier = headerModifier modifier = Modifier.fillMaxWidth()
)
},
rightContent = { panelModifier ->
MovieOverviewPanel(
movie = movie,
modifier = panelModifier
)
}
) )
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
} }
) { ) {
item {
Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp))
MediaDetailOverviewSection(
synopsis = movie.synopsis,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(20.dp))
}
}
item {
Column(modifier = it.fillMaxWidth()) {
MediaDetailPlaybackSection(
audioTrack = movie.audioTrack,
subtitles = movie.subtitles,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(20.dp))
}
}
if (movie.cast.isNotEmpty()) { if (movie.cast.isNotEmpty()) {
item { item {
Column(modifier = it) { Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(8.dp))
MediaDetailSectionTitle(text = "Cast") MediaDetailSectionTitle(text = "Cast")
Spacer(modifier = Modifier.height(14.dp)) Spacer(modifier = Modifier.height(14.dp))
MediaCastRow(cast = movie.cast) MediaCastRow(cast = movie.cast)

View File

@@ -55,7 +55,6 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.MediaCastRow import hu.bbara.purefin.common.ui.MediaCastRow
import hu.bbara.purefin.common.ui.MediaMetaChip import hu.bbara.purefin.common.ui.MediaMetaChip
import hu.bbara.purefin.common.ui.MediaSynopsis
import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar import hu.bbara.purefin.common.ui.components.MediaDetailsTopBar
import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.MediaProgressBar import hu.bbara.purefin.common.ui.components.MediaProgressBar
@@ -249,28 +248,16 @@ internal fun SeriesHeroSection(
} }
@Composable @Composable
internal fun SeriesOverviewPanel( internal fun SeriesStatusPanel(
series: Series,
nextUpEpisode: Episode?, nextUpEpisode: Episode?,
seasonCount: Int,
unwatchedEpisodeCount: Int,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val scheme = MaterialTheme.colorScheme val scheme = MaterialTheme.colorScheme
val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.85f) val mutedStrong = scheme.onSurfaceVariant.copy(alpha = 0.85f)
Column(modifier = modifier) { Column(modifier = modifier) {
MediaSynopsis(
synopsis = series.synopsis,
title = "Overview",
titleColor = scheme.onSurface,
bodyColor = mutedStrong,
titleFontSize = 20.sp,
bodyFontSize = 16.sp,
bodyLineHeight = 24.sp,
titleSpacing = 10.dp,
collapsedLines = 5,
collapseInitially = false
)
Spacer(modifier = Modifier.height(24.dp))
MediaDetailSectionTitle( MediaDetailSectionTitle(
text = if (nextUpEpisode != null) "Up Next" else "Library Status", text = if (nextUpEpisode != null) "Up Next" else "Library Status",
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
@@ -280,7 +267,7 @@ internal fun SeriesOverviewPanel(
text = if (nextUpEpisode != null) { text = if (nextUpEpisode != null) {
nextUpEpisode.title nextUpEpisode.title
} else { } else {
"${series.seasonCount} seasons ready to browse" "$seasonCount seasons ready to browse"
}, },
color = scheme.onSurface, color = scheme.onSurface,
fontSize = 18.sp, fontSize = 18.sp,
@@ -293,7 +280,7 @@ internal fun SeriesOverviewPanel(
text = if (nextUpEpisode != null) { text = if (nextUpEpisode != null) {
"Episode ${nextUpEpisode.index}${nextUpEpisode.runtime}" "Episode ${nextUpEpisode.index}${nextUpEpisode.runtime}"
} else { } else {
"${series.unwatchedEpisodeCount} unwatched episodes" "$unwatchedEpisodeCount unwatched episodes"
}, },
color = mutedStrong, color = mutedStrong,
fontSize = 14.sp, fontSize = 14.sp,

View File

@@ -2,6 +2,7 @@ package hu.bbara.purefin.app.content.series
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -15,6 +16,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import hu.bbara.purefin.common.ui.PurefinWaitingScreen import hu.bbara.purefin.common.ui.PurefinWaitingScreen
import hu.bbara.purefin.common.ui.components.MediaDetailHeaderRow import hu.bbara.purefin.common.ui.components.MediaDetailHeaderRow
import hu.bbara.purefin.common.ui.components.MediaDetailOverviewSection
import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle import hu.bbara.purefin.common.ui.components.MediaDetailSectionTitle
import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold import hu.bbara.purefin.common.ui.components.TvMediaDetailScaffold
import hu.bbara.purefin.core.data.navigation.SeriesDto import hu.bbara.purefin.core.data.navigation.SeriesDto
@@ -103,9 +105,10 @@ internal fun SeriesScreenContent(
) )
}, },
rightContent = { panelModifier -> rightContent = { panelModifier ->
SeriesOverviewPanel( SeriesStatusPanel(
series = series,
nextUpEpisode = nextUpEpisode, nextUpEpisode = nextUpEpisode,
seasonCount = series.seasonCount,
unwatchedEpisodeCount = series.unwatchedEpisodeCount,
modifier = panelModifier modifier = panelModifier
) )
} }
@@ -114,7 +117,16 @@ internal fun SeriesScreenContent(
} }
) { ) {
item { item {
Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MediaDetailOverviewSection(
synopsis = series.synopsis,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(24.dp))
}
}
item {
SeasonTabs( SeasonTabs(
seasons = series.seasons, seasons = series.seasons,
selectedSeason = selectedSeason.value, selectedSeason = selectedSeason.value,

View File

@@ -7,8 +7,10 @@ import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
@@ -22,6 +24,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import hu.bbara.purefin.common.ui.MediaSynopsis
internal val MediaDetailHorizontalPadding = 48.dp internal val MediaDetailHorizontalPadding = 48.dp
private val MediaDetailPanelShape = RoundedCornerShape(28.dp) private val MediaDetailPanelShape = RoundedCornerShape(28.dp)
@@ -114,6 +117,48 @@ internal fun MediaDetailSectionTitle(
) )
} }
@Composable
internal fun MediaDetailOverviewSection(
synopsis: String,
modifier: Modifier = Modifier
) {
val scheme = MaterialTheme.colorScheme
MediaSynopsis(
synopsis = synopsis,
modifier = modifier,
title = "Overview",
titleColor = scheme.onBackground,
bodyColor = scheme.onSurfaceVariant.copy(alpha = 0.85f),
titleFontSize = 22.sp,
bodyFontSize = 16.sp,
bodyLineHeight = 24.sp,
titleSpacing = 14.dp,
collapsedLines = 5,
collapseInitially = false
)
}
@Composable
internal fun MediaDetailPlaybackSection(
audioTrack: String,
subtitles: String,
modifier: Modifier = Modifier
) {
val scheme = MaterialTheme.colorScheme
Column(modifier = modifier) {
MediaDetailSectionTitle(text = "Playback")
Spacer(modifier = Modifier.height(14.dp))
MediaPlaybackSettings(
backgroundColor = scheme.surfaceContainerHigh,
foregroundColor = scheme.onBackground,
audioTrack = audioTrack,
subtitles = subtitles
)
}
}
@Composable @Composable
private fun MediaDetailHeroGradientOverlay() { private fun MediaDetailHeroGradientOverlay() {
val background = MaterialTheme.colorScheme.background val background = MaterialTheme.colorScheme.background