refactor: Use default Column instead of LayyColumn

This commit is contained in:
2026-04-29 22:51:56 +02:00
parent 84a95b0af6
commit 1fc291d2d8
4 changed files with 114 additions and 145 deletions

View File

@@ -15,14 +15,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding 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.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush 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.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.ui.common.image.PurefinAsyncImage
import hu.bbara.purefin.image.ImageUrlBuilder
import hu.bbara.purefin.image.ArtworkKind 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 internal val MediaDetailHorizontalPadding = 48.dp
private val MediaDetailHeaderTopPadding = 104.dp private val MediaDetailHeaderTopPadding = 24.dp
private val MediaDetailHeaderBottomPadding = 36.dp private val MediaDetailHeaderBottomPadding = 24.dp
private const val MediaDetailBodyImageWidthFraction = 0.66f private const val MediaDetailBodyImageWidthFraction = 0.66f
internal val TvMediaDetailBringIntoViewSpec: BringIntoViewSpec = internal val TvMediaDetailBringIntoViewSpec: BringIntoViewSpec =
@@ -61,19 +57,13 @@ internal val TvMediaDetailBringIntoViewSpec: BringIntoViewSpec =
internal fun TvMediaDetailScaffold( internal fun TvMediaDetailScaffold(
resetScrollKey: Any, resetScrollKey: Any,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
bodyContent: LazyListScope.(Modifier) -> Unit = { _ -> } bodyContent: @Composable (Modifier) -> Unit = {}
) { ) {
val scheme = MaterialTheme.colorScheme val scheme = MaterialTheme.colorScheme
val contentPadding = Modifier.padding(horizontal = MediaDetailHorizontalPadding) val contentPadding = Modifier.padding(horizontal = MediaDetailHorizontalPadding)
val listState = rememberLazyListState()
LaunchedEffect(resetScrollKey) {
listState.scrollToItem(0)
}
CompositionLocalProvider(LocalBringIntoViewSpec provides TvMediaDetailBringIntoViewSpec) { CompositionLocalProvider(LocalBringIntoViewSpec provides TvMediaDetailBringIntoViewSpec) {
LazyColumn( Column(
state = listState,
modifier = modifier modifier = modifier
.fillMaxSize() .fillMaxSize()
.background(scheme.background) .background(scheme.background)

View File

@@ -85,50 +85,44 @@ internal fun TvEpisodeScreenContent(
resetScrollKey = episode.id, resetScrollKey = episode.id,
modifier = modifier modifier = modifier
) { ) {
item(key = "episode-hero") { TvMediaDetailBodyBox(
TvMediaDetailBodyBox( backgroundImageUrl = ImageUrlBuilder.finishImageUrl(
backgroundImageUrl = ImageUrlBuilder.finishImageUrl(episode.imageUrlPrefix, ArtworkKind.PRIMARY), episode.imageUrlPrefix,
modifier = it ArtworkKind.PRIMARY
) { ),
TvEpisodeHeroSection( modifier = it
episode = episode, ) {
seriesTitle = seriesTitle, TvEpisodeHeroSection(
onPlay = onPlay, episode = episode,
playFocusRequester = playFocusRequester, seriesTitle = seriesTitle,
modifier = Modifier.fillMaxWidth() onPlay = onPlay,
) playFocusRequester = playFocusRequester,
Spacer(modifier = Modifier.height(12.dp)) modifier = Modifier.fillMaxWidth()
} )
Spacer(modifier = Modifier.height(12.dp))
} }
item(key = "episode-overview") { Column(modifier = it.fillMaxWidth()) {
Column(modifier = it.fillMaxWidth()) { Spacer(modifier = Modifier.height(16.dp))
Spacer(modifier = Modifier.height(16.dp)) MediaDetailOverviewSection(
MediaDetailOverviewSection( synopsis = episode.synopsis,
synopsis = episode.synopsis, modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth() )
) Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(20.dp))
}
} }
item(key = "episode-playback") { Column(modifier = it.fillMaxWidth()) {
Column(modifier = it.fillMaxWidth()) { MediaDetailPlaybackSection(
MediaDetailPlaybackSection( audioTrack = "ENG",
audioTrack = "ENG", subtitles = "ENG",
subtitles = "ENG", modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth() )
) Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(20.dp))
}
} }
if (episode.cast.isNotEmpty()) { Column(modifier = it.fillMaxWidth()) {
item(key = "episode-cast") { MediaDetailSectionTitle(text = "Cast")
Column(modifier = it.fillMaxWidth()) { Spacer(modifier = Modifier.height(14.dp))
MediaDetailSectionTitle(text = "Cast") // MediaCastRow(cast = episode.cast)
Spacer(modifier = Modifier.height(14.dp)) Spacer(modifier = Modifier.height(24.dp))
// MediaCastRow(cast = episode.cast)
Spacer(modifier = Modifier.height(24.dp))
}
}
} }
} }
} }

View File

@@ -27,7 +27,9 @@ import hu.bbara.purefin.ui.screen.waiting.PurefinWaitingScreen
@Composable @Composable
fun TvMovieScreen( fun TvMovieScreen(
movie: MovieDto, viewModel: MovieScreenViewModel = hiltViewModel(), modifier: Modifier = Modifier movie: MovieDto,
viewModel: MovieScreenViewModel = hiltViewModel(),
modifier: Modifier = Modifier
) { ) {
LaunchedEffect(movie.id) { LaunchedEffect(movie.id) {
viewModel.selectMovie(movie.id) viewModel.selectMovie(movie.id)
@@ -63,49 +65,41 @@ internal fun TvMovieScreenContent(
resetScrollKey = movie.id, resetScrollKey = movie.id,
modifier = modifier modifier = modifier
) { ) {
item(key = "movie-hero") { TvMediaDetailBodyBox(
TvMediaDetailBodyBox( backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix),
backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix), modifier = Modifier
modifier = it ) {
) { TvMovieHeroSection(
TvMovieHeroSection( movie = movie,
movie = movie, onPlay = onPlay,
onPlay = onPlay, playFocusRequester = playFocusRequester,
playFocusRequester = playFocusRequester, modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth() )
) Spacer(modifier = Modifier.height(12.dp))
Spacer(modifier = Modifier.height(12.dp))
}
} }
item(key = "movie-overview") { Column(modifier = Modifier.fillMaxWidth()) {
Column(modifier = it.fillMaxWidth()) { Spacer(modifier = Modifier.height(16.dp))
Spacer(modifier = Modifier.height(16.dp)) MediaDetailOverviewSection(
MediaDetailOverviewSection( synopsis = movie.synopsis,
synopsis = movie.synopsis, modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth() )
) Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(20.dp))
}
} }
item(key = "movie-playback") { }
Column(modifier = it.fillMaxWidth()) { Column(modifier = Modifier.fillMaxWidth()) {
MediaDetailPlaybackSection( MediaDetailPlaybackSection(
audioTrack = "ENG", audioTrack = "ENG",
subtitles = "ENG", subtitles = "ENG",
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
} if (movie.cast.isNotEmpty()) {
if (movie.cast.isNotEmpty()) { Column(modifier = Modifier.fillMaxWidth()) {
item(key = "movie-cast") { MediaDetailSectionTitle(text = "Cast")
Column(modifier = it.fillMaxWidth()) { Spacer(modifier = Modifier.height(14.dp))
MediaDetailSectionTitle(text = "Cast")
Spacer(modifier = Modifier.height(14.dp))
// MediaCastRow(cast = movie.cast) // MediaCastRow(cast = movie.cast)
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
}
}
} }
} }
} }

View File

@@ -81,63 +81,54 @@ internal fun TvSeriesScreenContent(
resetScrollKey = series.id, resetScrollKey = series.id,
modifier = modifier modifier = modifier
) { ) {
item(key = "series-hero") { TvMediaDetailBodyBox(
TvMediaDetailBodyBox( backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix),
backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix), modifier = it
modifier = it ) {
) { TvSeriesHeroSection(
TvSeriesHeroSection( series = series,
series = series, nextUpEpisode = nextUpEpisode,
nextUpEpisode = nextUpEpisode, onPlayEpisode = { onPlayEpisode(it.id) },
onPlayEpisode = { onPlayEpisode(it.id) }, playFocusRequester = playFocusRequester,
playFocusRequester = playFocusRequester, firstContentFocusRequester = firstContentFocusRequester,
firstContentFocusRequester = firstContentFocusRequester, modifier = Modifier.fillMaxWidth()
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
) )
Spacer(modifier = Modifier.height(12.dp))
} }
item(key = "series-episodes") { Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(16.dp))
TvEpisodeCarousel( MediaDetailOverviewSection(
episodes = selectedSeason.episodes, synopsis = series.synopsis,
modifier = it 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()) { if (series.cast.isNotEmpty()) {
item(key = "series-cast") { Column(modifier = it) {
Column(modifier = it) { Spacer(modifier = Modifier.height(20.dp))
Spacer(modifier = Modifier.height(20.dp)) MediaDetailSectionTitle(text = "Cast")
MediaDetailSectionTitle(text = "Cast") Spacer(modifier = Modifier.height(14.dp))
Spacer(modifier = Modifier.height(14.dp)) CastRow(cast = series.cast)
CastRow(cast = series.cast) Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(24.dp))
}
} }
} }
} }
} }
private fun Series.defaultSeason(): Season { private fun Series.defaultSeason(): Season {
for (season in seasons) { for (season in seasons) {
if (season.episodes.any { !it.watched }) { if (season.episodes.any { !it.watched }) {