From 19edc6de610efd09ea76b58da6365e5808daaf32 Mon Sep 17 00:00:00 2001 From: tapframe <85391825+tapframe@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:33:43 +0530 Subject: [PATCH] feat: horizontal episode cards to autoscroll to recent activity card --- .../app/features/details/MetaDetailsScreen.kt | 3 +++ .../details/components/DetailSeriesContent.kt | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt index 6398649a..31a9614e 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/MetaDetailsScreen.kt @@ -636,6 +636,7 @@ fun MetaDetailsScreen( onSaveClick = toggleSaved, showManualPlayOption = showManualPlayOption, preferredEpisodeSeasonNumber = seriesAction?.seasonNumber, + preferredEpisodeNumber = seriesAction?.episodeNumber, hasProductionSection = hasProductionSection, hasTrailersSection = hasTrailersSection, hasEpisodes = hasEpisodes, @@ -940,6 +941,7 @@ private fun ConfiguredMetaSections( onSaveClick: () -> Unit, showManualPlayOption: Boolean, preferredEpisodeSeasonNumber: Int?, + preferredEpisodeNumber: Int?, hasProductionSection: Boolean, hasTrailersSection: Boolean, hasEpisodes: Boolean, @@ -1042,6 +1044,7 @@ private fun ConfiguredMetaSections( meta = meta, showHeader = showHeader, preferredSeasonNumber = preferredEpisodeSeasonNumber, + preferredEpisodeNumber = preferredEpisodeNumber, episodeCardStyle = settings.episodeCardStyle, progressByVideoId = progressByVideoId, watchedKeys = watchedKeys, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailSeriesContent.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailSeriesContent.kt index efa1857e..ce6f2a2f 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailSeriesContent.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailSeriesContent.kt @@ -80,6 +80,7 @@ fun DetailSeriesContent( modifier: Modifier = Modifier, showHeader: Boolean = true, preferredSeasonNumber: Int? = null, + preferredEpisodeNumber: Int? = null, episodeCardStyle: MetaEpisodeCardStyle = MetaEpisodeCardStyle.Horizontal, progressByVideoId: Map = emptyMap(), watchedKeys: Set = emptySet(), @@ -269,6 +270,7 @@ fun DetailSeriesContent( watchedKeys = watchedKeys, fallbackImage = meta.background ?: meta.poster, progressByVideoId = progressByVideoId, + preferredEpisodeNumber = preferredEpisodeNumber, onEpisodeClick = onEpisodeClick, onEpisodeLongPress = onEpisodeLongPress, ) @@ -541,12 +543,32 @@ private fun EpisodeHorizontalRow( watchedKeys: Set, fallbackImage: String?, progressByVideoId: Map, + preferredEpisodeNumber: Int? = null, onEpisodeClick: ((MetaVideo) -> Unit)?, onEpisodeLongPress: ((MetaVideo) -> Unit)?, ) { val rowMetrics = rememberEpisodeHorizontalCardMetrics(maxWidthDp) + val listState = rememberLazyListState() + var hasPositioned by remember(episodes) { mutableStateOf(false) } + + LaunchedEffect(episodes, preferredEpisodeNumber) { + val targetIndex = if (preferredEpisodeNumber != null) { + episodes.indexOfFirst { it.episode == preferredEpisodeNumber } + } else { + -1 + } + if (targetIndex >= 0) { + if (hasPositioned) { + listState.animateScrollToItem(targetIndex) + } else { + listState.scrollToItem(targetIndex) + hasPositioned = true + } + } + } LazyRow( + state = listState, modifier = Modifier.fillMaxWidth(), contentPadding = PaddingValues(horizontal = rowMetrics.rowHorizontalPadding, vertical = rowMetrics.rowVerticalPadding), horizontalArrangement = Arrangement.spacedBy(rowMetrics.itemSpacing),