mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-08-04 18:42:34 +00:00
ref: remove startup observer causing stale catalog setting push
This commit is contained in:
parent
9d32d238f4
commit
87670e7cb0
3 changed files with 16 additions and 77 deletions
|
|
@ -182,7 +182,6 @@ import com.nuvio.app.features.collection.CollectionManagementScreen
|
|||
import com.nuvio.app.features.collection.CollectionEditorScreen
|
||||
import com.nuvio.app.features.collection.CollectionEditorRepository
|
||||
import com.nuvio.app.features.collection.CollectionSyncService
|
||||
import com.nuvio.app.features.home.HomeCatalogSettingsSyncService
|
||||
import com.nuvio.app.features.collection.FolderDetailScreen
|
||||
import com.nuvio.app.features.collection.FolderDetailRepository
|
||||
import com.nuvio.app.features.streams.StreamAutoPlayPolicy
|
||||
|
|
@ -687,9 +686,6 @@ private fun MainAppContent(
|
|||
remember {
|
||||
CollectionSyncService.startObserving()
|
||||
}
|
||||
remember {
|
||||
HomeCatalogSettingsSyncService.startObserving()
|
||||
}
|
||||
remember {
|
||||
ProfileSettingsSync.startObserving()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ object HomeCatalogSettingsRepository {
|
|||
publish()
|
||||
persist()
|
||||
HomeRepository.applyCurrentSettings()
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
|
||||
fun setHideCatalogUnderline(enabled: Boolean) {
|
||||
|
|
@ -188,10 +189,11 @@ object HomeCatalogSettingsRepository {
|
|||
hideCatalogUnderline = enabled
|
||||
publish()
|
||||
persist()
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
|
||||
fun setHeroSourceEnabled(key: String, enabled: Boolean) {
|
||||
updatePreference(key) { preference ->
|
||||
updatePreference(key, pushRemote = false) { preference ->
|
||||
if (!enabled) {
|
||||
preference.copy(heroSourceEnabled = false)
|
||||
} else if (selectedHeroSourceCount(excludingKey = key) >= HERO_SOURCE_SELECTION_LIMIT) {
|
||||
|
|
@ -224,6 +226,7 @@ object HomeCatalogSettingsRepository {
|
|||
publish()
|
||||
persist()
|
||||
HomeRepository.applyCurrentSettings()
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
|
||||
fun moveUp(key: String) {
|
||||
|
|
@ -249,6 +252,7 @@ object HomeCatalogSettingsRepository {
|
|||
publish()
|
||||
persist()
|
||||
HomeRepository.applyCurrentSettings()
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
|
||||
private fun ensureLoaded() {
|
||||
|
|
@ -385,14 +389,20 @@ object HomeCatalogSettingsRepository {
|
|||
|
||||
private fun updatePreference(
|
||||
key: String,
|
||||
pushRemote: Boolean = true,
|
||||
transform: (StoredHomeCatalogPreference) -> StoredHomeCatalogPreference,
|
||||
) {
|
||||
ensureLoaded()
|
||||
val current = preferences[key] ?: return
|
||||
preferences[key] = transform(current)
|
||||
val updated = transform(current)
|
||||
if (updated == current) return
|
||||
preferences[key] = updated
|
||||
publish()
|
||||
persist()
|
||||
HomeRepository.applyCurrentSettings()
|
||||
if (pushRemote) {
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectedHeroSourceCount(excludingKey: String? = null): Int {
|
||||
|
|
@ -427,6 +437,7 @@ object HomeCatalogSettingsRepository {
|
|||
publish()
|
||||
persist()
|
||||
HomeRepository.applyCurrentSettings()
|
||||
HomeCatalogSettingsSyncService.triggerPush()
|
||||
}
|
||||
|
||||
fun exportToSyncPayload(): SyncHomeCatalogPayload {
|
||||
|
|
|
|||
|
|
@ -3,23 +3,18 @@ package com.nuvio.app.features.home
|
|||
import co.touchlab.kermit.Logger
|
||||
import com.nuvio.app.core.auth.AuthRepository
|
||||
import com.nuvio.app.core.auth.AuthState
|
||||
import com.nuvio.app.core.network.SupabaseProvider
|
||||
import com.nuvio.app.core.sync.HOME_CATALOG_LEGACY_SYNC_PLATFORMS
|
||||
import com.nuvio.app.core.sync.HOME_CATALOG_SHARED_SYNC_PLATFORM
|
||||
import com.nuvio.app.core.network.SupabaseProvider
|
||||
import com.nuvio.app.features.profiles.ProfileRepository
|
||||
import io.github.jan.supabase.postgrest.postgrest
|
||||
import io.github.jan.supabase.postgrest.rpc
|
||||
import kotlin.concurrent.Volatile
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
|
@ -68,17 +63,6 @@ private data class PullToken(
|
|||
val profileId: Int,
|
||||
)
|
||||
|
||||
private data class ObservedHomeCatalogChange(
|
||||
val signature: String,
|
||||
val token: PullToken?,
|
||||
val initialPullCompleteAtEmission: Boolean,
|
||||
)
|
||||
|
||||
private data class HomeCatalogChangeSignature(
|
||||
val signature: String,
|
||||
val token: PullToken,
|
||||
)
|
||||
|
||||
object HomeCatalogSettingsSyncService {
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
private val log = Logger.withTag("HomeCatalogSettingsSyncService")
|
||||
|
|
@ -87,7 +71,6 @@ object HomeCatalogSettingsSyncService {
|
|||
encodeDefaults = true
|
||||
}
|
||||
|
||||
private const val PUSH_DEBOUNCE_MS = 1500L
|
||||
private const val HIDE_UNRELEASED_CONTENT_KEY = "hide_unreleased_content"
|
||||
private const val HIDE_CATALOG_UNDERLINE_KEY = "hide_catalog_underline"
|
||||
|
||||
|
|
@ -95,19 +78,10 @@ object HomeCatalogSettingsSyncService {
|
|||
var isSyncingFromRemote: Boolean = false
|
||||
|
||||
private var pushJob: Job? = null
|
||||
private var observeJob: Job? = null
|
||||
|
||||
@Volatile
|
||||
private var completedInitialPull: PullToken? = null
|
||||
|
||||
@Volatile
|
||||
private var remoteAppliedSignature: HomeCatalogChangeSignature? = null
|
||||
|
||||
fun startObserving() {
|
||||
if (observeJob?.isActive == true) return
|
||||
observeLocalChangesAndPush()
|
||||
}
|
||||
|
||||
suspend fun pullFromServer(profileId: Int) {
|
||||
runCatching {
|
||||
val pullToken = currentPullToken(profileId) ?: return
|
||||
|
|
@ -124,12 +98,12 @@ object HomeCatalogSettingsSyncService {
|
|||
|
||||
if (remotePayload.items.isEmpty()) {
|
||||
log.i { "pullFromServer — remote has empty items, preserving local catalog order" }
|
||||
applyRemotePayload(remotePayload, pullToken)
|
||||
applyRemotePayload(remotePayload)
|
||||
markInitialPullComplete(pullToken)
|
||||
return
|
||||
}
|
||||
|
||||
applyRemotePayload(remotePayload, pullToken)
|
||||
applyRemotePayload(remotePayload)
|
||||
log.i { "pullFromServer — applied ${remotePayload.items.size} items from remote" }
|
||||
markInitialPullComplete(pullToken)
|
||||
}.onFailure { e ->
|
||||
|
|
@ -170,43 +144,6 @@ object HomeCatalogSettingsSyncService {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
private fun observeLocalChangesAndPush() {
|
||||
observeJob = scope.launch {
|
||||
HomeCatalogSettingsRepository.uiState
|
||||
.map { state ->
|
||||
val token = currentPullToken()
|
||||
ObservedHomeCatalogChange(
|
||||
signature = state.signature,
|
||||
token = token,
|
||||
initialPullCompleteAtEmission = token?.let(::hasCompletedInitialPull) == true,
|
||||
)
|
||||
}
|
||||
.drop(1)
|
||||
.distinctUntilChanged()
|
||||
.debounce(PUSH_DEBOUNCE_MS)
|
||||
.collect { change ->
|
||||
val token = change.token ?: return@collect
|
||||
val changeSignature = HomeCatalogChangeSignature(change.signature, token)
|
||||
if (!change.initialPullCompleteAtEmission) {
|
||||
if (changeSignature == remoteAppliedSignature) {
|
||||
remoteAppliedSignature = null
|
||||
}
|
||||
log.d { "observeLocalChangesAndPush — skipped before initial home catalog pull completed" }
|
||||
return@collect
|
||||
}
|
||||
if (changeSignature == remoteAppliedSignature) {
|
||||
remoteAppliedSignature = null
|
||||
log.d { "observeLocalChangesAndPush — skipped remote-applied catalog change" }
|
||||
return@collect
|
||||
}
|
||||
if (isSyncingFromRemote) return@collect
|
||||
if (currentPullToken() != token) return@collect
|
||||
pushToRemote(token.profileId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun currentPullToken(profileId: Int = ProfileRepository.activeProfileId): PullToken? {
|
||||
val authState = AuthRepository.state.value
|
||||
if (authState !is AuthState.Authenticated || authState.isAnonymous) return null
|
||||
|
|
@ -225,15 +162,10 @@ object HomeCatalogSettingsSyncService {
|
|||
|
||||
private fun applyRemotePayload(
|
||||
payload: SyncHomeCatalogPayload,
|
||||
token: PullToken,
|
||||
) {
|
||||
isSyncingFromRemote = true
|
||||
try {
|
||||
HomeCatalogSettingsRepository.applyFromRemote(payload)
|
||||
remoteAppliedSignature = HomeCatalogChangeSignature(
|
||||
signature = HomeCatalogSettingsRepository.uiState.value.signature,
|
||||
token = token,
|
||||
)
|
||||
} finally {
|
||||
isSyncingFromRemote = false
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue