diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt index 5f5b6aad..111c06d7 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt @@ -845,8 +845,7 @@ private fun MainAppContent( } } val shouldResolveEpisodeVideoId = - route.type == "series" && - route.parentMetaId != null && + route.parentMetaId != null && route.seasonNumber != null && route.episodeNumber != null var effectiveVideoId by rememberSaveable( 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 bae5ba5b..0b24ed0d 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 @@ -459,7 +459,7 @@ fun MetaDetailsScreen( fallbackVideoId = video.id, ) val streamVideoId = video.id.takeIf { it.isNotBlank() } ?: playbackVideoId - val savedProgress = watchProgressUiState.byVideoId[playbackVideoId] + val savedProgress = watchProgressUiState.byVideoId[streamVideoId] ?.takeUnless { it.isCompleted } onPlay?.invoke( meta.type, @@ -488,7 +488,7 @@ fun MetaDetailsScreen( fallbackVideoId = video.id, ) val streamVideoId = video.id.takeIf { it.isNotBlank() } ?: playbackVideoId - val savedProgress = watchProgressUiState.byVideoId[playbackVideoId] + val savedProgress = watchProgressUiState.byVideoId[streamVideoId] ?.takeUnless { it.isCompleted } onPlayManually?.invoke( meta.type, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreen.kt index 7e0bee9b..c0ee1d32 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreen.kt @@ -255,7 +255,7 @@ fun PlayerScreen( contentType = contentType ?: parentMetaType, parentMetaId = parentMetaId, parentMetaType = parentMetaType, - videoId = buildPlaybackVideoId( + videoId = activeVideoId?.takeIf { it.isNotBlank() } ?: buildPlaybackVideoId( parentMetaId = parentMetaId, seasonNumber = activeSeasonNumber, episodeNumber = activeEpisodeNumber, @@ -567,7 +567,9 @@ fun PlayerScreen( episodeNumber = episode.episode, fallbackVideoId = epVideoId, ) - val epEntry = WatchProgressRepository.progressForVideo(epResumeVideoId) + val epEntry = WatchProgressRepository.progressForVideo( + epVideoId.takeIf { it.isNotBlank() } ?: epResumeVideoId, + ) ?.takeIf { !it.isCompleted } val epResumeFraction = epEntry?.progressPercent ?.takeIf { it > 0f } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt index 8361ba89..1c26b927 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsScreen.kt @@ -107,22 +107,10 @@ fun StreamsScreen( }.collectAsStateWithLifecycle() val isEpisode = seasonNumber != null && episodeNumber != null var preferredFilterApplied by remember(videoId) { mutableStateOf(false) } - val legacyEpisodeVideoId = remember(type, parentMetaId, seasonNumber, episodeNumber, videoId) { - if (type == "series" && seasonNumber != null && episodeNumber != null) { - buildPlaybackVideoId( - parentMetaId = parentMetaId, - seasonNumber = seasonNumber, - episodeNumber = episodeNumber, - ).takeIf { it != videoId } - } else { - null - } - } val storedProgress = if (startFromBeginning) { null } else { watchProgressUiState.byVideoId[videoId] - ?: legacyEpisodeVideoId?.let { legacyId -> watchProgressUiState.byVideoId[legacyId] } } val storedProgressFraction = storedProgress?.progressPercent ?.takeIf { it > 0f } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressModels.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressModels.kt index b61a67d7..a25510e0 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressModels.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressModels.kt @@ -244,7 +244,7 @@ internal fun WatchProgressEntry.toUpNextContinueWatchingItem( return ContinueWatchingItem( parentMetaId = parentMetaId, parentMetaType = parentMetaType, - videoId = buildPlaybackVideoId( + videoId = nextEpisode.id.takeIf { it.isNotBlank() } ?: buildPlaybackVideoId( parentMetaId = parentMetaId, seasonNumber = nextEpisode.season, episodeNumber = nextEpisode.episode, diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRepository.kt index a41dd60e..f5b0666f 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRepository.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRepository.kt @@ -288,10 +288,10 @@ object WatchProgressRepository { fun progressForVideo(videoId: String): WatchProgressEntry? { ensureLoaded() return if (shouldUseTraktProgress()) { - TraktProgressRepository.uiState.value.entries.firstOrNull { it.videoId == videoId } + TraktProgressRepository.uiState.value.entries } else { - entriesByVideoId[videoId] - } + entriesByVideoId.values.toList() + }.firstOrNull { it.videoId == videoId } } fun resumeEntryForSeries(metaId: String): WatchProgressEntry? { diff --git a/composeApp/src/commonTest/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRulesTest.kt b/composeApp/src/commonTest/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRulesTest.kt index 4021283b..d07261fd 100644 --- a/composeApp/src/commonTest/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRulesTest.kt +++ b/composeApp/src/commonTest/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRulesTest.kt @@ -1,5 +1,6 @@ package com.nuvio.app.features.watchprogress +import com.nuvio.app.features.details.MetaVideo import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -144,6 +145,25 @@ class WatchProgressRulesTest { assertEquals("movie", buildPlaybackVideoId(parentMetaId = "movie", seasonNumber = null, episodeNumber = null, fallbackVideoId = null)) } + @Test + fun `up next continue watching uses actual episode id when available`() { + val item = entry( + videoId = "kitsu:244:1", + parentMetaId = "kitsu:244", + seasonNumber = 1, + episodeNumber = 1, + ).toUpNextContinueWatchingItem( + MetaVideo( + id = "kitsu:244:2", + title = "Episode 2", + season = 1, + episode = 2, + ), + ) + + assertEquals("kitsu:244:2", item.videoId) + } + private fun entry( videoId: String, parentMetaId: String = videoId.substringBefore(':'),