Add keys to lazy Compose entries

This commit is contained in:
2026-04-17 18:02:22 +02:00
parent 858f599dbd
commit 5a377fc428
11 changed files with 31 additions and 28 deletions

View File

@@ -86,7 +86,7 @@ internal fun TvEpisodeScreenContent(
resetScrollKey = episode.id, resetScrollKey = episode.id,
modifier = modifier modifier = modifier
) { ) {
item { item(key = "episode-hero") {
TvMediaDetailBodyBox( TvMediaDetailBodyBox(
backgroundImageUrl = ImageUrlBuilder.finishImageUrl(episode.imageUrlPrefix, ArtworkKind.PRIMARY), backgroundImageUrl = ImageUrlBuilder.finishImageUrl(episode.imageUrlPrefix, ArtworkKind.PRIMARY),
modifier = it modifier = it
@@ -101,7 +101,7 @@ internal fun TvEpisodeScreenContent(
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
} }
} }
item { 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(
@@ -111,7 +111,7 @@ internal fun TvEpisodeScreenContent(
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
} }
item { item(key = "episode-playback") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
MediaDetailPlaybackSection( MediaDetailPlaybackSection(
audioTrack = "ENG", audioTrack = "ENG",
@@ -122,7 +122,7 @@ internal fun TvEpisodeScreenContent(
} }
} }
if (episode.cast.isNotEmpty()) { if (episode.cast.isNotEmpty()) {
item { item(key = "episode-cast") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
MediaDetailSectionTitle(text = "Cast") MediaDetailSectionTitle(text = "Cast")
Spacer(modifier = Modifier.height(14.dp)) Spacer(modifier = Modifier.height(14.dp))

View File

@@ -84,11 +84,11 @@ fun TvHomeContent(
.testTag(TvHomeContentViewportTag), .testTag(TvHomeContentViewportTag),
contentPadding = contentPadding contentPadding = contentPadding
) { ) {
item { item(key = "tv-home-top-spacer") {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
if (hasContinueWatching) { if (hasContinueWatching) {
item { item(key = "tv-home-continue-watching") {
TvContinueWatchingSection( TvContinueWatchingSection(
items = continueWatching, items = continueWatching,
onFocusedItem = onMediaFocused, onFocusedItem = onMediaFocused,
@@ -102,13 +102,13 @@ fun TvHomeContent(
} }
if (hasContinueWatching && (hasNextUp || hasLibraries)) { if (hasContinueWatching && (hasNextUp || hasLibraries)) {
item { item(key = "tv-home-post-continue-gap") {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
} }
if (hasNextUp) { if (hasNextUp) {
item { item(key = "tv-home-next-up") {
TvNextUpSection( TvNextUpSection(
items = nextUp, items = nextUp,
onFocusedItem = onMediaFocused, onFocusedItem = onMediaFocused,
@@ -121,7 +121,7 @@ fun TvHomeContent(
} }
if (hasLibraries && (hasContinueWatching || hasNextUp)) { if (hasLibraries && (hasContinueWatching || hasNextUp)) {
item { item(key = "tv-home-post-next-up-gap") {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
} }
@@ -156,7 +156,7 @@ fun TvHomeContent(
} }
if (hasVisibleContent) { if (hasVisibleContent) {
item { item(key = "tv-home-trailing-space") {
Spacer(modifier = Modifier.height(TvHomeBringIntoViewTrailingSpace)) Spacer(modifier = Modifier.height(TvHomeBringIntoViewTrailingSpace))
} }
} }

View File

@@ -105,7 +105,7 @@ fun TvLibraryContent(
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.background(MaterialTheme.colorScheme.background) modifier = Modifier.background(MaterialTheme.colorScheme.background)
) { ) {
items(libraryItems) { item -> items(libraryItems, key = { item -> item.id }) { item ->
PosterCard( PosterCard(
item = item, item = item,
onMovieSelected = onMovieSelected, onMovieSelected = onMovieSelected,

View File

@@ -64,7 +64,7 @@ internal fun TvMovieScreenContent(
resetScrollKey = movie.id, resetScrollKey = movie.id,
modifier = modifier modifier = modifier
) { ) {
item { item(key = "movie-hero") {
TvMediaDetailBodyBox( TvMediaDetailBodyBox(
backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix), backgroundImageUrl = tvMediaDetailBackgroundImageUrl(movie.imageUrlPrefix),
modifier = it modifier = it
@@ -78,7 +78,7 @@ internal fun TvMovieScreenContent(
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
} }
} }
item { item(key = "movie-overview") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MediaDetailOverviewSection( MediaDetailOverviewSection(
@@ -88,7 +88,7 @@ internal fun TvMovieScreenContent(
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
} }
item { item(key = "movie-playback") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
MediaDetailPlaybackSection( MediaDetailPlaybackSection(
audioTrack = movie.audioTrack, audioTrack = movie.audioTrack,
@@ -99,7 +99,7 @@ internal fun TvMovieScreenContent(
} }
} }
if (movie.cast.isNotEmpty()) { if (movie.cast.isNotEmpty()) {
item { item(key = "movie-cast") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
MediaDetailSectionTitle(text = "Cast") MediaDetailSectionTitle(text = "Cast")
Spacer(modifier = Modifier.height(14.dp)) Spacer(modifier = Modifier.height(14.dp))

View File

@@ -81,7 +81,7 @@ internal fun TvSeriesScreenContent(
resetScrollKey = series.id, resetScrollKey = series.id,
modifier = modifier modifier = modifier
) { ) {
item { item(key = "series-hero") {
TvMediaDetailBodyBox( TvMediaDetailBodyBox(
backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix), backgroundImageUrl = tvMediaDetailBackgroundImageUrl(series.imageUrlPrefix),
modifier = it modifier = it
@@ -97,7 +97,7 @@ internal fun TvSeriesScreenContent(
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
} }
} }
item { item(key = "series-overview") {
Column(modifier = it.fillMaxWidth()) { Column(modifier = it.fillMaxWidth()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MediaDetailOverviewSection( MediaDetailOverviewSection(
@@ -107,7 +107,7 @@ internal fun TvSeriesScreenContent(
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
} }
} }
item { item(key = "series-season-tabs") {
TvSeasonTabs( TvSeasonTabs(
seasons = series.seasons, seasons = series.seasons,
selectedSeason = selectedSeason, selectedSeason = selectedSeason,
@@ -117,7 +117,7 @@ internal fun TvSeriesScreenContent(
modifier = it modifier = it
) )
} }
item { item(key = "series-episodes") {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
TvEpisodeCarousel( TvEpisodeCarousel(
episodes = selectedSeason.episodes, episodes = selectedSeason.episodes,
@@ -125,7 +125,7 @@ internal fun TvSeriesScreenContent(
) )
} }
if (series.cast.isNotEmpty()) { if (series.cast.isNotEmpty()) {
item { 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")

View File

@@ -171,7 +171,7 @@ internal fun TvEpisodeCarousel(episodes: List<Episode>, modifier: Modifier = Mod
modifier = modifier, modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(16.dp) horizontalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
items(episodes) { episode -> items(episodes, key = { episode -> episode.id }) { episode ->
TvEpisodeCard(episode = episode) TvEpisodeCard(episode = episode)
} }
} }

View File

@@ -65,7 +65,7 @@ fun DownloadsContent(
modifier = modifier.background(MaterialTheme.colorScheme.background) modifier = modifier.background(MaterialTheme.colorScheme.background)
) { ) {
if (activeDownloads.value.isNotEmpty()) { if (activeDownloads.value.isNotEmpty()) {
item(span = { GridItemSpan(maxLineSpan) }) { item(key = "downloading-header", span = { GridItemSpan(maxLineSpan) }) {
Text( Text(
text = "Downloading", text = "Downloading",
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
@@ -84,7 +84,7 @@ fun DownloadsContent(
) )
} }
if (downloads.value.isNotEmpty()) { if (downloads.value.isNotEmpty()) {
item(span = { GridItemSpan(maxLineSpan) }) { item(key = "downloaded-header", span = { GridItemSpan(maxLineSpan) }) {
Text( Text(
text = "Downloaded", text = "Downloaded",
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
@@ -95,7 +95,7 @@ fun DownloadsContent(
} }
} }
} }
items(downloads.value) { item -> items(downloads.value, key = { item -> item.id }) { item ->
PosterCard( PosterCard(
item = item, item = item,
onMovieSelected = viewModel::onMovieSelected, onMovieSelected = viewModel::onMovieSelected,

View File

@@ -83,7 +83,7 @@ internal fun LibraryPosterGrid(
verticalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier.background(MaterialTheme.colorScheme.background) modifier = modifier.background(MaterialTheme.colorScheme.background)
) { ) {
items(libraryItems) { item -> items(libraryItems, key = { item -> item.id }) { item ->
PosterCard( PosterCard(
item = item, item = item,
onMovieSelected = viewModel::onMovieSelected, onMovieSelected = viewModel::onMovieSelected,

View File

@@ -80,7 +80,7 @@ fun PlayerQueuePanel(
exit = fadeOut() exit = fadeOut()
) { ) {
LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) { LazyColumn(verticalArrangement = Arrangement.spacedBy(10.dp)) {
items(uiState.queue) { item -> items(uiState.queue, key = { item -> item.id }) { item ->
QueueRow( QueueRow(
title = item.title, title = item.title,
subtitle = item.subtitle, subtitle = item.subtitle,

View File

@@ -304,7 +304,7 @@ internal fun EpisodeCarousel(episodes: List<Episode>, modifier: Modifier = Modif
modifier = modifier, modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(16.dp) horizontalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
items(episodes) { episode -> items(episodes, key = { episode -> episode.id }) { episode ->
EpisodeCard(episode = episode) EpisodeCard(episode = episode)
} }
} }

View File

@@ -79,7 +79,10 @@ fun MediaCastRow(
contentPadding = PaddingValues(horizontal = 4.dp), contentPadding = PaddingValues(horizontal = 4.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp) horizontalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
items(cast) { member -> items(
items = cast,
key = { member -> "${member.name}:${member.role}:${member.imageUrl.orEmpty()}" }
) { member ->
Column(modifier = Modifier.width(cardWidth)) { Column(modifier = Modifier.width(cardWidth)) {
Box( Box(
modifier = Modifier modifier = Modifier