mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-26 22:42:17 +00:00
fix(simkl): refresh hidden progress immediately
This commit is contained in:
parent
94ec538c10
commit
327d49d31d
8 changed files with 78 additions and 11 deletions
|
|
@ -195,10 +195,12 @@ fun HomeScreen(
|
|||
|
||||
val effectiveWatchProgressEntries = remember(
|
||||
watchProgressUiState.entries,
|
||||
watchProgressUiState.hiddenContentIds,
|
||||
continueWatchingCutoffEpochMs,
|
||||
) {
|
||||
val visibleProviderEntries = watchProgressUiState.entries.filterNot { entry ->
|
||||
WatchProgressRepository.isDroppedShow(entry.parentMetaId)
|
||||
entry.parentMetaId in watchProgressUiState.hiddenContentIds ||
|
||||
WatchProgressRepository.isDroppedShow(entry.parentMetaId)
|
||||
}
|
||||
filterEntriesForContinueWatchingWindow(
|
||||
entries = visibleProviderEntries,
|
||||
|
|
@ -208,6 +210,7 @@ fun HomeScreen(
|
|||
|
||||
val allNextUpSeedCandidates = remember(
|
||||
watchProgressUiState.entries,
|
||||
watchProgressUiState.hiddenContentIds,
|
||||
nextUpWatchedItems,
|
||||
progressProviderOwnsCompletedHistory,
|
||||
continueWatchingPreferences.upNextFromFurthestEpisode,
|
||||
|
|
@ -219,7 +222,10 @@ fun HomeScreen(
|
|||
preferFurthestEpisode = continueWatchingPreferences.upNextFromFurthestEpisode,
|
||||
nowEpochMs = WatchProgressClock.nowEpochMs(),
|
||||
shouldUseProgressSeed = WatchProgressRepository::shouldUseAsNextUpSeed,
|
||||
isContentHidden = WatchProgressRepository::isDroppedShow,
|
||||
isContentHidden = { contentId ->
|
||||
contentId in watchProgressUiState.hiddenContentIds ||
|
||||
WatchProgressRepository.isDroppedShow(contentId)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -346,6 +352,7 @@ fun HomeScreen(
|
|||
nextUpItemsBySeries,
|
||||
continueWatchingPreferences.showUnairedNextUp,
|
||||
watchedUiState.isLoaded,
|
||||
watchProgressUiState.hiddenContentIds,
|
||||
) {
|
||||
cachedSnapshots.first.mapNotNull { cached ->
|
||||
if (
|
||||
|
|
@ -382,7 +389,10 @@ fun HomeScreen(
|
|||
if (!cachedNextUpHasAired(cached) && !continueWatchingPreferences.showUnairedNextUp) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
if (WatchProgressRepository.isDroppedShow(cached.contentId)) {
|
||||
if (
|
||||
cached.contentId in watchProgressUiState.hiddenContentIds ||
|
||||
WatchProgressRepository.isDroppedShow(cached.contentId)
|
||||
) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
val item = cached.toContinueWatchingItem() ?: return@mapNotNull null
|
||||
|
|
@ -394,9 +404,16 @@ fun HomeScreen(
|
|||
cached.contentId to (sortTimestamp to item)
|
||||
}.toMap()
|
||||
}
|
||||
val cachedInProgressItems = remember(cachedSnapshots.second, effectiveWatchProgressSource) {
|
||||
val cachedInProgressItems = remember(
|
||||
cachedSnapshots.second,
|
||||
effectiveWatchProgressSource,
|
||||
watchProgressUiState.hiddenContentIds,
|
||||
) {
|
||||
cachedSnapshots.second.mapNotNull { cached ->
|
||||
if (WatchProgressRepository.isDroppedShow(cached.contentId)) {
|
||||
if (
|
||||
cached.contentId in watchProgressUiState.hiddenContentIds ||
|
||||
WatchProgressRepository.isDroppedShow(cached.contentId)
|
||||
) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
cached.resolvedProgressKey() to cached.toContinueWatchingItem()
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ object SimklTrackingProgressProvider : TrackingProgressProvider {
|
|||
val state = SimklProgressRepository.uiState.value
|
||||
return TrackingProgressSnapshot(
|
||||
entries = state.entries,
|
||||
hiddenContentIds = SimklSyncRepository.state.value.snapshot.droppedContentIds(),
|
||||
hasLoadedRemoteProgress = state.hasLoadedRemoteProgress,
|
||||
errorMessage = state.errorMessage,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ internal fun SimklSyncSnapshot.isDroppedContent(contentId: String): Boolean =
|
|||
entry.matchesContent(contentId = contentId, trackingProviderItemId = null)
|
||||
}
|
||||
|
||||
internal fun SimklSyncSnapshot.droppedContentIds(): Set<String> =
|
||||
entries.asSequence()
|
||||
.filter { entry -> entry.status == SimklListStatus.DROPPED }
|
||||
.mapNotNull { entry -> entry.media?.canonicalContentId() }
|
||||
.toSet()
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ interface TrackingWatchedProvider : WatchedSyncAdapter {
|
|||
|
||||
data class TrackingProgressSnapshot(
|
||||
val entries: List<WatchProgressEntry> = emptyList(),
|
||||
val hiddenContentIds: Set<String> = emptySet(),
|
||||
val hasLoadedRemoteProgress: Boolean = false,
|
||||
val errorMessage: String? = null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ data class WatchProgressEntry(
|
|||
data class WatchProgressUiState(
|
||||
val source: WatchProgressSource = WatchProgressSource.NUVIO_SYNC,
|
||||
val entries: List<WatchProgressEntry> = emptyList(),
|
||||
val hiddenContentIds: Set<String> = emptySet(),
|
||||
val hasLoadedRemoteProgress: Boolean = false,
|
||||
) {
|
||||
val byProgressKey: Map<String, WatchProgressEntry>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.nuvio.app.features.details.MetaDetailsRepository
|
|||
import com.nuvio.app.features.player.PlayerPlaybackSnapshot
|
||||
import com.nuvio.app.features.profiles.ProfileRepository
|
||||
import com.nuvio.app.features.tracking.TrackingProgressProvider
|
||||
import com.nuvio.app.features.tracking.TrackingProgressSnapshot
|
||||
import com.nuvio.app.features.tracking.TrackingProviderId
|
||||
import com.nuvio.app.features.tracking.TrackingProviderRegistry
|
||||
import com.nuvio.app.features.tracking.TrackingSettingsRepository
|
||||
|
|
@ -1340,14 +1341,12 @@ object WatchProgressRepository {
|
|||
private fun publish() {
|
||||
val entries = currentEntries()
|
||||
val sortedEntries = entries.sortedByDescending { it.lastUpdatedEpochMs }
|
||||
val hasLoadedRemoteProgress = activeProgressProvider()
|
||||
?.snapshot()
|
||||
?.hasLoadedRemoteProgress
|
||||
?: hasLoadedNuvioRemoteProgress
|
||||
_uiState.value = WatchProgressUiState(
|
||||
val providerSnapshot = activeProgressProvider()?.snapshot()
|
||||
_uiState.value = projectWatchProgressUiState(
|
||||
source = activeSource,
|
||||
entries = sortedEntries,
|
||||
hasLoadedRemoteProgress = hasLoadedRemoteProgress,
|
||||
providerSnapshot = providerSnapshot,
|
||||
hasLoadedNuvioRemoteProgress = hasLoadedNuvioRemoteProgress,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1643,3 +1642,16 @@ object WatchProgressRepository {
|
|||
resources.any { resource -> resource.name == "meta" }
|
||||
|
||||
}
|
||||
|
||||
internal fun projectWatchProgressUiState(
|
||||
source: WatchProgressSource,
|
||||
entries: List<WatchProgressEntry>,
|
||||
providerSnapshot: TrackingProgressSnapshot?,
|
||||
hasLoadedNuvioRemoteProgress: Boolean,
|
||||
): WatchProgressUiState = WatchProgressUiState(
|
||||
source = source,
|
||||
entries = entries,
|
||||
hiddenContentIds = providerSnapshot?.hiddenContentIds.orEmpty(),
|
||||
hasLoadedRemoteProgress =
|
||||
providerSnapshot?.hasLoadedRemoteProgress ?: hasLoadedNuvioRemoteProgress,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ class SimklPlaybackReconciliationTest {
|
|||
|
||||
assertTrue(snapshot.reconcileWatchedPlayback().playback.isEmpty())
|
||||
assertTrue(snapshot.isDroppedContent("tt4574334"))
|
||||
assertEquals(setOf("tt4574334"), snapshot.droppedContentIds())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -279,6 +280,7 @@ class SimklPlaybackReconciliationTest {
|
|||
|
||||
assertEquals(snapshot.playback, snapshot.reconcileWatchedPlayback().playback)
|
||||
assertFalse(snapshot.isDroppedContent("tt4574334"))
|
||||
assertEquals(setOf("tt1111111"), snapshot.droppedContentIds())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,13 +1,40 @@
|
|||
package com.nuvio.app.features.watchprogress
|
||||
|
||||
import com.nuvio.app.features.details.MetaDetails
|
||||
import com.nuvio.app.features.tracking.TrackingProgressSnapshot
|
||||
import com.nuvio.app.features.tracking.WatchProgressSource
|
||||
import com.nuvio.app.features.watching.sync.ProgressSyncRecord
|
||||
import com.nuvio.app.features.watching.sync.ProgressDeltaEvent
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class WatchProgressIdentityTest {
|
||||
@Test
|
||||
fun `provider hidden content changes progress ui state without changing entries`() {
|
||||
val entry = entry(
|
||||
parentMetaId = "show",
|
||||
videoId = "show:1:2",
|
||||
progressKey = "show-episode",
|
||||
lastUpdatedEpochMs = 10L,
|
||||
)
|
||||
val visible = projectWatchProgressUiState(
|
||||
source = WatchProgressSource.SIMKL,
|
||||
entries = listOf(entry),
|
||||
providerSnapshot = TrackingProgressSnapshot(),
|
||||
hasLoadedNuvioRemoteProgress = false,
|
||||
)
|
||||
val hidden = projectWatchProgressUiState(
|
||||
source = WatchProgressSource.SIMKL,
|
||||
entries = listOf(entry),
|
||||
providerSnapshot = TrackingProgressSnapshot(hiddenContentIds = setOf("show")),
|
||||
hasLoadedNuvioRemoteProgress = false,
|
||||
)
|
||||
|
||||
assertEquals(visible.entries, hidden.entries)
|
||||
assertNotEquals(visible, hidden)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `provider change during metadata batch schedules one follow up`() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue