mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-07-26 22:42:17 +00:00
fix: trakt local porgress pushing multiple watched markers
This commit is contained in:
parent
e0ca149b09
commit
9b5ea6e3b6
4 changed files with 81 additions and 8 deletions
|
|
@ -269,6 +269,12 @@ fun PlayerScreen(
|
|||
activeSeasonNumber,
|
||||
activeEpisodeNumber,
|
||||
) { mutableStateOf(false) }
|
||||
var scrobbleStartRequestGeneration by remember(
|
||||
activeSourceUrl,
|
||||
activeVideoId,
|
||||
activeSeasonNumber,
|
||||
activeEpisodeNumber,
|
||||
) { mutableStateOf(0L) }
|
||||
var hasSentCompletionScrobbleForCurrentItem by remember(
|
||||
activeVideoId,
|
||||
activeSeasonNumber,
|
||||
|
|
@ -422,6 +428,8 @@ fun PlayerScreen(
|
|||
fun emitTraktScrobbleStart() {
|
||||
if (hasRequestedScrobbleStartForCurrentItem) return
|
||||
hasRequestedScrobbleStartForCurrentItem = true
|
||||
val requestGeneration = scrobbleStartRequestGeneration + 1L
|
||||
scrobbleStartRequestGeneration = requestGeneration
|
||||
|
||||
scope.launch {
|
||||
val item = currentTraktScrobbleItem()
|
||||
|
|
@ -429,6 +437,9 @@ fun PlayerScreen(
|
|||
hasRequestedScrobbleStartForCurrentItem = false
|
||||
return@launch
|
||||
}
|
||||
if (requestGeneration != scrobbleStartRequestGeneration || !hasRequestedScrobbleStartForCurrentItem) {
|
||||
return@launch
|
||||
}
|
||||
currentTraktScrobbleItem = item
|
||||
TraktScrobbleRepository.scrobbleStart(
|
||||
item = item,
|
||||
|
|
@ -452,6 +463,7 @@ fun PlayerScreen(
|
|||
}
|
||||
currentTraktScrobbleItem = null
|
||||
hasRequestedScrobbleStartForCurrentItem = false
|
||||
scrobbleStartRequestGeneration += 1L
|
||||
}
|
||||
|
||||
fun emitStopScrobbleForCurrentProgress() {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@ private data class StoredWatchedPayload(
|
|||
val lastSuccessfulPushEpochMs: Long = 0L,
|
||||
)
|
||||
|
||||
internal enum class WatchedTraktHistorySync {
|
||||
Mirror,
|
||||
Skip,
|
||||
}
|
||||
|
||||
internal fun shouldMirrorWatchedMarkToTraktHistory(
|
||||
sync: WatchedTraktHistorySync,
|
||||
isTraktAuthenticated: Boolean,
|
||||
): Boolean = sync == WatchedTraktHistorySync.Mirror && isTraktAuthenticated
|
||||
|
||||
object WatchedRepository {
|
||||
private const val watchedItemsPageSize = 900
|
||||
|
||||
|
|
@ -134,6 +144,17 @@ object WatchedRepository {
|
|||
}
|
||||
|
||||
fun markWatched(items: Collection<WatchedItem>) {
|
||||
markWatched(items = items, traktHistorySync = WatchedTraktHistorySync.Mirror)
|
||||
}
|
||||
|
||||
internal fun markWatchedFromPlaybackCompletion(item: WatchedItem) {
|
||||
markWatched(items = listOf(item), traktHistorySync = WatchedTraktHistorySync.Skip)
|
||||
}
|
||||
|
||||
private fun markWatched(
|
||||
items: Collection<WatchedItem>,
|
||||
traktHistorySync: WatchedTraktHistorySync,
|
||||
) {
|
||||
ensureLoaded()
|
||||
if (items.isEmpty()) return
|
||||
val markedAt = WatchedClock.nowEpochMs()
|
||||
|
|
@ -146,7 +167,7 @@ object WatchedRepository {
|
|||
}
|
||||
publish()
|
||||
persist()
|
||||
pushMarksToServer(timestampedItems)
|
||||
pushMarksToServer(timestampedItems, traktHistorySync)
|
||||
}
|
||||
|
||||
fun unmarkWatched(item: WatchedItem) {
|
||||
|
|
@ -223,13 +244,22 @@ object WatchedRepository {
|
|||
}
|
||||
}
|
||||
|
||||
private fun pushMarksToServer(items: Collection<WatchedItem>) {
|
||||
private fun pushMarksToServer(
|
||||
items: Collection<WatchedItem>,
|
||||
traktHistorySync: WatchedTraktHistorySync,
|
||||
) {
|
||||
syncScope.launch {
|
||||
runCatching {
|
||||
if (items.isEmpty()) return@runCatching
|
||||
val profileId = ProfileRepository.activeProfileId
|
||||
pushToActiveTargets(profileId = profileId, items = items)
|
||||
recordSuccessfulPush(profileId = profileId, items = items)
|
||||
val pushed = pushToActiveTargets(
|
||||
profileId = profileId,
|
||||
items = items,
|
||||
traktHistorySync = traktHistorySync,
|
||||
)
|
||||
if (pushed) {
|
||||
recordSuccessfulPush(profileId = profileId, items = items)
|
||||
}
|
||||
}.onFailure { e ->
|
||||
log.e(e) { "Failed to push watched items" }
|
||||
}
|
||||
|
|
@ -296,16 +326,24 @@ object WatchedRepository {
|
|||
private suspend fun pushToActiveTargets(
|
||||
profileId: Int,
|
||||
items: Collection<WatchedItem>,
|
||||
) {
|
||||
traktHistorySync: WatchedTraktHistorySync,
|
||||
): Boolean {
|
||||
val shouldMirrorToTrakt = shouldMirrorWatchedMarkToTraktHistory(
|
||||
sync = traktHistorySync,
|
||||
isTraktAuthenticated = TraktAuthRepository.isAuthenticated.value,
|
||||
)
|
||||
|
||||
if (shouldUseTraktWatchedSync()) {
|
||||
if (!shouldMirrorToTrakt) return false
|
||||
TraktWatchedSyncAdapter.push(profileId = profileId, items = items)
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
syncAdapter.push(profileId = profileId, items = items)
|
||||
if (TraktAuthRepository.isAuthenticated.value) {
|
||||
if (shouldMirrorToTrakt) {
|
||||
TraktWatchedSyncAdapter.push(profileId = profileId, items = items)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private suspend fun deleteFromActiveTargets(
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ object WatchingActions {
|
|||
episode = entry.episodeNumber,
|
||||
markedAtEpochMs = entry.lastUpdatedEpochMs,
|
||||
)
|
||||
WatchedRepository.markWatched(watchedItem)
|
||||
WatchedRepository.markWatchedFromPlaybackCompletion(watchedItem)
|
||||
|
||||
if (!entry.isEpisode) return
|
||||
actionScope.launch {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.nuvio.app.features.details.MetaDetails
|
|||
import com.nuvio.app.features.details.MetaVideo
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class WatchedRepositoryTest {
|
||||
|
|
@ -97,4 +98,26 @@ class WatchedRepositoryTest {
|
|||
|
||||
assertTrue(merged.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun playbackCompletionWatchedMarks_doNotMirrorToTraktHistory() {
|
||||
assertFalse(
|
||||
shouldMirrorWatchedMarkToTraktHistory(
|
||||
sync = WatchedTraktHistorySync.Skip,
|
||||
isTraktAuthenticated = true,
|
||||
),
|
||||
)
|
||||
assertTrue(
|
||||
shouldMirrorWatchedMarkToTraktHistory(
|
||||
sync = WatchedTraktHistorySync.Mirror,
|
||||
isTraktAuthenticated = true,
|
||||
),
|
||||
)
|
||||
assertFalse(
|
||||
shouldMirrorWatchedMarkToTraktHistory(
|
||||
sync = WatchedTraktHistorySync.Mirror,
|
||||
isTraktAuthenticated = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue