diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRules.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRules.kt index 096feb64..6fd0841a 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRules.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/watchprogress/WatchProgressRules.kt @@ -63,7 +63,13 @@ internal fun List.resumeEntryForSeries(metaId: String): Watc internal fun List.continueWatchingEntries( limit: Int = ContinueWatchingLimit, -): List = - filterNot { it.isCompleted } +): List { + val inProgress = filterNot { it.isCompleted } + val (episodes, nonEpisodes) = inProgress.partition { it.isEpisode } + val latestPerSeries = episodes + .sortedByDescending { it.lastUpdatedEpochMs } + .distinctBy { it.parentMetaId } + return (nonEpisodes + latestPerSeries) .sortedByDescending { it.lastUpdatedEpochMs } .take(limit) +} 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 873044b2..c1b8e409 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 @@ -71,6 +71,29 @@ class WatchProgressRulesTest { assertEquals("video-6", result.last().videoId) } + @Test + fun `continue watching deduplicates series keeping latest episode per show`() { + val ep1 = entry(videoId = "show:1:1", parentMetaId = "show", seasonNumber = 1, episodeNumber = 1, lastUpdatedEpochMs = 10L) + val ep2 = entry(videoId = "show:1:2", parentMetaId = "show", seasonNumber = 1, episodeNumber = 2, lastUpdatedEpochMs = 20L) + val movie = entry(videoId = "movie-1", parentMetaId = "movie-1", lastUpdatedEpochMs = 15L) + + val result = listOf(ep1, ep2, movie).continueWatchingEntries() + + assertEquals(2, result.size) + assertEquals("show:1:2", result.first().videoId) + assertEquals("movie-1", result.last().videoId) + } + + @Test + fun `continue watching keeps multiple movies without deduplication`() { + val m1 = entry(videoId = "movie-a", parentMetaId = "movie-a", lastUpdatedEpochMs = 10L) + val m2 = entry(videoId = "movie-b", parentMetaId = "movie-b", lastUpdatedEpochMs = 20L) + + val result = listOf(m1, m2).continueWatchingEntries() + + assertEquals(2, result.size) + } + @Test fun `build playback video id uses season and episode when present`() { assertEquals("show:1:2", buildPlaybackVideoId(parentMetaId = "show", seasonNumber = 1, episodeNumber = 2, fallbackVideoId = "fallback"))