mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-23 18:22:05 +00:00
ref(sync): pull method to support optional parameters for last watched and limit
This commit is contained in:
parent
9818458b9f
commit
de68ce2c30
3 changed files with 60 additions and 32 deletions
|
|
@ -14,7 +14,11 @@ data class ProgressSyncRecord(
|
||||||
)
|
)
|
||||||
|
|
||||||
interface ProgressSyncAdapter {
|
interface ProgressSyncAdapter {
|
||||||
suspend fun pull(profileId: Int): List<ProgressSyncRecord>
|
suspend fun pull(
|
||||||
|
profileId: Int,
|
||||||
|
sinceLastWatched: Long? = null,
|
||||||
|
limit: Int? = null,
|
||||||
|
): List<ProgressSyncRecord>
|
||||||
|
|
||||||
suspend fun push(
|
suspend fun push(
|
||||||
profileId: Int,
|
profileId: Int,
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,20 @@ object SupabaseProgressSyncAdapter : ProgressSyncAdapter {
|
||||||
encodeDefaults = true
|
encodeDefaults = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun pull(profileId: Int): List<ProgressSyncRecord> {
|
override suspend fun pull(
|
||||||
val params = buildJsonObject { put("p_profile_id", profileId) }
|
profileId: Int,
|
||||||
|
sinceLastWatched: Long?,
|
||||||
|
limit: Int?,
|
||||||
|
): List<ProgressSyncRecord> {
|
||||||
|
val params = buildJsonObject {
|
||||||
|
put("p_profile_id", profileId)
|
||||||
|
if (sinceLastWatched != null) {
|
||||||
|
put("p_since_last_watched", sinceLastWatched)
|
||||||
|
}
|
||||||
|
if (limit != null) {
|
||||||
|
put("p_limit", limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
val result = SupabaseProvider.client.postgrest.rpc("sync_pull_watch_progress", params)
|
val result = SupabaseProvider.client.postgrest.rpc("sync_pull_watch_progress", params)
|
||||||
val serverEntries = result.decodeList<WatchProgressSyncEntry>()
|
val serverEntries = result.decodeList<WatchProgressSyncEntry>()
|
||||||
return serverEntries.map { entry ->
|
return serverEntries.map { entry ->
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.nuvio.app.features.trakt.TraktProgressRepository
|
||||||
import com.nuvio.app.features.trakt.TraktSettingsRepository
|
import com.nuvio.app.features.trakt.TraktSettingsRepository
|
||||||
import com.nuvio.app.features.trakt.shouldUseTraktProgress as shouldUseTraktProgressSource
|
import com.nuvio.app.features.trakt.shouldUseTraktProgress as shouldUseTraktProgressSource
|
||||||
import com.nuvio.app.features.watching.application.WatchingActions
|
import com.nuvio.app.features.watching.application.WatchingActions
|
||||||
|
import com.nuvio.app.features.watching.sync.ProgressSyncRecord
|
||||||
import com.nuvio.app.features.watching.sync.ProgressSyncAdapter
|
import com.nuvio.app.features.watching.sync.ProgressSyncAdapter
|
||||||
import com.nuvio.app.features.watching.sync.SupabaseProgressSyncAdapter
|
import com.nuvio.app.features.watching.sync.SupabaseProgressSyncAdapter
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
|
|
@ -180,38 +181,23 @@ object WatchProgressRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
runCatching {
|
runCatching {
|
||||||
val serverEntries = syncAdapter.pull(profileId = profileId)
|
val sinceLastWatched = entriesByVideoId.values
|
||||||
|
.maxOfOrNull { entry -> entry.lastUpdatedEpochMs }
|
||||||
|
?.takeIf { hasCompletedInitialNuvioSyncPull }
|
||||||
|
val serverEntries = syncAdapter.pull(
|
||||||
|
profileId = profileId,
|
||||||
|
sinceLastWatched = sinceLastWatched,
|
||||||
|
)
|
||||||
|
val isIncrementalPull = sinceLastWatched != null
|
||||||
val oldLocal = entriesByVideoId.toMap()
|
val oldLocal = entriesByVideoId.toMap()
|
||||||
val newMap = mutableMapOf<String, WatchProgressEntry>()
|
val newMap = if (isIncrementalPull) {
|
||||||
|
entriesByVideoId.toMutableMap()
|
||||||
|
} else {
|
||||||
|
mutableMapOf()
|
||||||
|
}
|
||||||
|
|
||||||
serverEntries.forEach { entry ->
|
serverEntries.forEach { entry ->
|
||||||
val videoId = entry.videoId
|
newMap[entry.videoId] = entry.toWatchProgressEntry(cached = oldLocal[entry.videoId])
|
||||||
val cached = oldLocal[videoId]
|
|
||||||
newMap[videoId] = WatchProgressEntry(
|
|
||||||
contentType = entry.contentType,
|
|
||||||
parentMetaId = entry.contentId,
|
|
||||||
parentMetaType = cached?.parentMetaType ?: entry.contentType,
|
|
||||||
videoId = videoId,
|
|
||||||
title = cached?.title?.takeIf { it.isNotBlank() } ?: entry.contentId,
|
|
||||||
logo = cached?.logo,
|
|
||||||
poster = cached?.poster,
|
|
||||||
background = cached?.background,
|
|
||||||
seasonNumber = entry.season,
|
|
||||||
episodeNumber = entry.episode,
|
|
||||||
episodeTitle = cached?.episodeTitle,
|
|
||||||
episodeThumbnail = cached?.episodeThumbnail,
|
|
||||||
lastPositionMs = entry.position,
|
|
||||||
durationMs = entry.duration,
|
|
||||||
lastUpdatedEpochMs = entry.lastWatched,
|
|
||||||
providerName = cached?.providerName,
|
|
||||||
providerAddonId = cached?.providerAddonId,
|
|
||||||
lastStreamTitle = cached?.lastStreamTitle,
|
|
||||||
lastStreamSubtitle = cached?.lastStreamSubtitle,
|
|
||||||
pauseDescription = cached?.pauseDescription,
|
|
||||||
lastSourceUrl = cached?.lastSourceUrl,
|
|
||||||
isCompleted = isWatchProgressComplete(entry.position, entry.duration, false),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entriesByVideoId = newMap
|
entriesByVideoId = newMap
|
||||||
|
|
@ -232,6 +218,32 @@ object WatchProgressRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ProgressSyncRecord.toWatchProgressEntry(cached: WatchProgressEntry?): WatchProgressEntry =
|
||||||
|
WatchProgressEntry(
|
||||||
|
contentType = contentType,
|
||||||
|
parentMetaId = contentId,
|
||||||
|
parentMetaType = cached?.parentMetaType ?: contentType,
|
||||||
|
videoId = videoId,
|
||||||
|
title = cached?.title?.takeIf { it.isNotBlank() } ?: contentId,
|
||||||
|
logo = cached?.logo,
|
||||||
|
poster = cached?.poster,
|
||||||
|
background = cached?.background,
|
||||||
|
seasonNumber = season,
|
||||||
|
episodeNumber = episode,
|
||||||
|
episodeTitle = cached?.episodeTitle,
|
||||||
|
episodeThumbnail = cached?.episodeThumbnail,
|
||||||
|
lastPositionMs = position,
|
||||||
|
durationMs = duration,
|
||||||
|
lastUpdatedEpochMs = lastWatched,
|
||||||
|
providerName = cached?.providerName,
|
||||||
|
providerAddonId = cached?.providerAddonId,
|
||||||
|
lastStreamTitle = cached?.lastStreamTitle,
|
||||||
|
lastStreamSubtitle = cached?.lastStreamSubtitle,
|
||||||
|
pauseDescription = cached?.pauseDescription,
|
||||||
|
lastSourceUrl = cached?.lastSourceUrl,
|
||||||
|
isCompleted = isWatchProgressComplete(position, duration, false),
|
||||||
|
)
|
||||||
|
|
||||||
private fun resolveRemoteMetadata() {
|
private fun resolveRemoteMetadata() {
|
||||||
val needsResolution = entriesByVideoId.values
|
val needsResolution = entriesByVideoId.values
|
||||||
.filter { it.poster.isNullOrBlank() || it.background.isNullOrBlank() }
|
.filter { it.poster.isNullOrBlank() || it.background.isNullOrBlank() }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue