fix(simkl): hide on-hold items from continue watching

This commit is contained in:
tapframe 2026-07-24 18:18:25 +05:30
parent 327d49d31d
commit 085b136e5a
3 changed files with 51 additions and 13 deletions

View file

@ -197,7 +197,8 @@ object SimklTrackingProgressProvider : TrackingProgressProvider {
val state = SimklProgressRepository.uiState.value
return TrackingProgressSnapshot(
entries = state.entries,
hiddenContentIds = SimklSyncRepository.state.value.snapshot.droppedContentIds(),
hiddenContentIds = SimklSyncRepository.state.value.snapshot
.hiddenFromContinueWatchingContentIds(),
hasLoadedRemoteProgress = state.hasLoadedRemoteProgress,
errorMessage = state.errorMessage,
)
@ -207,7 +208,7 @@ object SimklTrackingProgressProvider : TrackingProgressProvider {
SimklProgressRepository.removeProgress(entries)
override fun isHiddenFromProgress(contentId: String): Boolean =
SimklSyncRepository.state.value.snapshot.isDroppedContent(contentId)
SimklSyncRepository.state.value.snapshot.isHiddenFromContinueWatching(contentId)
}
private const val SIMKL_PLAYBACK_PROGRESS_KEY_PREFIX = "simkl-playback:"

View file

@ -15,18 +15,21 @@ internal fun SimklSyncSnapshot.reconcileWatchedPlayback(): SimklSyncSnapshot {
return if (retainedPlayback.size == playback.size) this else copy(playback = retainedPlayback)
}
internal fun SimklSyncSnapshot.isDroppedContent(contentId: String): Boolean =
internal fun SimklSyncSnapshot.isHiddenFromContinueWatching(contentId: String): Boolean =
entries.any { entry ->
entry.status == SimklListStatus.DROPPED &&
entry.status.hidesContinueWatching() &&
entry.matchesContent(contentId = contentId, trackingProviderItemId = null)
}
internal fun SimklSyncSnapshot.droppedContentIds(): Set<String> =
internal fun SimklSyncSnapshot.hiddenFromContinueWatchingContentIds(): Set<String> =
entries.asSequence()
.filter { entry -> entry.status == SimklListStatus.DROPPED }
.filter { entry -> entry.status.hidesContinueWatching() }
.mapNotNull { entry -> entry.media?.canonicalContentId() }
.toSet()
internal fun SimklListStatus?.hidesContinueWatching(): Boolean =
this == SimklListStatus.ON_HOLD || this == SimklListStatus.DROPPED
private fun WatchedItem.supersedes(progress: WatchProgressEntry): Boolean {
if (!type.equals(progress.contentType, ignoreCase = true)) return false
if (season != progress.seasonNumber || episode != progress.episodeNumber) return false
@ -46,9 +49,9 @@ private fun SimklLibraryEntry.hidesPlayback(progress: WatchProgressEntry): Boole
) {
return false
}
return when (status) {
SimklListStatus.DROPPED -> true
SimklListStatus.COMPLETED ->
return when {
status.hidesContinueWatching() -> true
status == SimklListStatus.COMPLETED ->
parseSimklUtcEpochMs(lastWatchedAt)?.let { completedAt ->
completedAt >= progress.lastUpdatedEpochMs
} == true

View file

@ -254,8 +254,39 @@ class SimklPlaybackReconciliationTest {
)
assertTrue(snapshot.reconcileWatchedPlayback().playback.isEmpty())
assertTrue(snapshot.isDroppedContent("tt4574334"))
assertEquals(setOf("tt4574334"), snapshot.droppedContentIds())
assertTrue(snapshot.isHiddenFromContinueWatching("tt4574334"))
assertEquals(
setOf("tt4574334"),
snapshot.hiddenFromContinueWatchingContentIds(),
)
}
@Test
fun `on hold series discards playback using provider identity`() {
val snapshot = SimklSyncSnapshot(
entries = listOf(
SimklLibraryEntry(
mediaType = SimklMediaType.SHOWS,
status = SimklListStatus.ON_HOLD,
show = media(39687, imdb = "tt4574334"),
),
),
playback = listOf(
episodePlayback(
playbackMedia = media(39687, tvdb = "305288"),
season = 1,
episode = 5,
pausedAt = "2024-04-30T22:14:00Z",
),
),
)
assertTrue(snapshot.reconcileWatchedPlayback().playback.isEmpty())
assertTrue(snapshot.isHiddenFromContinueWatching("tt4574334"))
assertEquals(
setOf("tt4574334"),
snapshot.hiddenFromContinueWatchingContentIds(),
)
}
@Test
@ -279,8 +310,11 @@ class SimklPlaybackReconciliationTest {
)
assertEquals(snapshot.playback, snapshot.reconcileWatchedPlayback().playback)
assertFalse(snapshot.isDroppedContent("tt4574334"))
assertEquals(setOf("tt1111111"), snapshot.droppedContentIds())
assertFalse(snapshot.isHiddenFromContinueWatching("tt4574334"))
assertEquals(
setOf("tt1111111"),
snapshot.hiddenFromContinueWatchingContentIds(),
)
}
@Test