feat: Implement profile-scoped storage keys; update settings storage and repositories to support profile-specific data

This commit is contained in:
tapframe 2026-03-29 13:50:52 +05:30
parent 35d6f65993
commit dce27b3620
14 changed files with 95 additions and 29 deletions

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.home
import android.content.Context
import android.content.SharedPreferences
import com.nuvio.app.core.storage.ProfileScopedKey
actual object HomeCatalogSettingsStorage {
private const val preferencesName = "nuvio_home_catalog_settings"
@ -14,12 +15,12 @@ actual object HomeCatalogSettingsStorage {
}
actual fun loadPayload(): String? =
preferences?.getString(payloadKey, null)
preferences?.getString(ProfileScopedKey.of(payloadKey), null)
actual fun savePayload(payload: String) {
preferences
?.edit()
?.putString(payloadKey, payload)
?.putString(ProfileScopedKey.of(payloadKey), payload)
?.apply()
}
}

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.player
import android.content.Context
import android.content.SharedPreferences
import com.nuvio.app.core.storage.ProfileScopedKey
actual object PlayerSettingsStorage {
private const val preferencesName = "nuvio_player_settings"
@ -15,8 +16,9 @@ actual object PlayerSettingsStorage {
actual fun loadShowLoadingOverlay(): Boolean? =
preferences?.let { sharedPreferences ->
if (sharedPreferences.contains(showLoadingOverlayKey)) {
sharedPreferences.getBoolean(showLoadingOverlayKey, true)
val key = ProfileScopedKey.of(showLoadingOverlayKey)
if (sharedPreferences.contains(key)) {
sharedPreferences.getBoolean(key, true)
} else {
null
}
@ -25,7 +27,7 @@ actual object PlayerSettingsStorage {
actual fun saveShowLoadingOverlay(enabled: Boolean) {
preferences
?.edit()
?.putBoolean(showLoadingOverlayKey, enabled)
?.putBoolean(ProfileScopedKey.of(showLoadingOverlayKey), enabled)
?.apply()
}
}

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.settings
import android.content.Context
import android.content.SharedPreferences
import com.nuvio.app.core.storage.ProfileScopedKey
actual object ThemeSettingsStorage {
private const val preferencesName = "nuvio_theme_settings"
@ -15,24 +16,25 @@ actual object ThemeSettingsStorage {
}
actual fun loadSelectedTheme(): String? =
preferences?.getString(selectedThemeKey, null)
preferences?.getString(ProfileScopedKey.of(selectedThemeKey), null)
actual fun saveSelectedTheme(themeName: String) {
preferences
?.edit()
?.putString(selectedThemeKey, themeName)
?.putString(ProfileScopedKey.of(selectedThemeKey), themeName)
?.apply()
}
actual fun loadAmoledEnabled(): Boolean? =
preferences?.let { prefs ->
if (prefs.contains(amoledEnabledKey)) prefs.getBoolean(amoledEnabledKey, false) else null
val key = ProfileScopedKey.of(amoledEnabledKey)
if (prefs.contains(key)) prefs.getBoolean(key, false) else null
}
actual fun saveAmoledEnabled(enabled: Boolean) {
preferences
?.edit()
?.putBoolean(amoledEnabledKey, enabled)
?.putBoolean(ProfileScopedKey.of(amoledEnabledKey), enabled)
?.apply()
}
}

View file

@ -2,6 +2,7 @@ package com.nuvio.app.features.watchprogress
import android.content.Context
import android.content.SharedPreferences
import com.nuvio.app.core.storage.ProfileScopedKey
actual object ContinueWatchingPreferencesStorage {
private const val preferencesName = "nuvio_continue_watching_preferences"
@ -14,12 +15,12 @@ actual object ContinueWatchingPreferencesStorage {
}
actual fun loadPayload(): String? =
preferences?.getString(payloadKey, null)
preferences?.getString(ProfileScopedKey.of(payloadKey), null)
actual fun savePayload(payload: String) {
preferences
?.edit()
?.putString(payloadKey, payload)
?.putString(ProfileScopedKey.of(payloadKey), payload)
?.apply()
}
}

View file

@ -0,0 +1,8 @@
package com.nuvio.app.core.storage
import com.nuvio.app.features.profiles.ProfileRepository
object ProfileScopedKey {
fun of(baseKey: String): String = "${baseKey}_${ProfileRepository.activeProfileId}"
}

View file

@ -79,6 +79,13 @@ object HomeCatalogSettingsRepository {
private var preferences: MutableMap<String, StoredHomeCatalogPreference> = mutableMapOf()
private var heroEnabled = true
fun onProfileChanged() {
hasLoaded = false
preferences.clear()
heroEnabled = true
_uiState.value = HomeCatalogSettingsUiState()
}
fun syncCatalogs(addons: List<ManagedAddon>) {
ensureLoaded()
definitions = buildHomeCatalogDefinitions(addons)

View file

@ -17,6 +17,14 @@ object PlayerSettingsRepository {
fun ensureLoaded() {
if (hasLoaded) return
loadFromDisk()
}
fun onProfileChanged() {
loadFromDisk()
}
private fun loadFromDisk() {
hasLoaded = true
showLoadingOverlay = PlayerSettingsStorage.loadShowLoadingOverlay() ?: true
publish()

View file

@ -5,8 +5,12 @@ 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.features.addons.AddonRepository
import com.nuvio.app.features.home.HomeCatalogSettingsRepository
import com.nuvio.app.features.library.LibraryRepository
import com.nuvio.app.features.player.PlayerSettingsRepository
import com.nuvio.app.features.settings.ThemeSettingsRepository
import com.nuvio.app.features.watched.WatchedRepository
import com.nuvio.app.features.watchprogress.ContinueWatchingPreferencesRepository
import com.nuvio.app.features.watchprogress.WatchProgressRepository
import io.github.jan.supabase.postgrest.postgrest
import io.github.jan.supabase.postgrest.rpc
@ -114,6 +118,10 @@ object ProfileRepository {
LibraryRepository.onProfileChanged(profileIndex)
WatchProgressRepository.onProfileChanged(profileIndex)
AddonRepository.onProfileChanged(profileIndex)
ThemeSettingsRepository.onProfileChanged()
PlayerSettingsRepository.onProfileChanged()
HomeCatalogSettingsRepository.onProfileChanged()
ContinueWatchingPreferencesRepository.onProfileChanged()
}
suspend fun pushProfiles(profiles: List<ProfilePushPayload>) {

View file

@ -16,6 +16,14 @@ object ThemeSettingsRepository {
fun ensureLoaded() {
if (hasLoaded) return
loadFromDisk()
}
fun onProfileChanged() {
loadFromDisk()
}
private fun loadFromDisk() {
hasLoaded = true
val stored = ThemeSettingsStorage.loadSelectedTheme()
val theme = if (stored != null) {

View file

@ -27,19 +27,34 @@ object ContinueWatchingPreferencesRepository {
fun ensureLoaded() {
if (hasLoaded) return
loadFromDisk()
}
fun onProfileChanged() {
loadFromDisk()
}
private fun loadFromDisk() {
hasLoaded = true
val payload = ContinueWatchingPreferencesStorage.loadPayload().orEmpty().trim()
if (payload.isEmpty()) return
if (payload.isEmpty()) {
_uiState.value = ContinueWatchingPreferencesUiState()
return
}
val stored = runCatching {
json.decodeFromString<StoredContinueWatchingPreferences>(payload)
}.getOrNull() ?: return
}.getOrNull()
_uiState.value = ContinueWatchingPreferencesUiState(
isVisible = stored.isVisible,
style = stored.style,
)
_uiState.value = if (stored != null) {
ContinueWatchingPreferencesUiState(
isVisible = stored.isVisible,
style = stored.style,
)
} else {
ContinueWatchingPreferencesUiState()
}
}
fun setVisible(isVisible: Boolean) {

View file

@ -1,14 +1,15 @@
package com.nuvio.app.features.home
import com.nuvio.app.core.storage.ProfileScopedKey
import platform.Foundation.NSUserDefaults
actual object HomeCatalogSettingsStorage {
private const val payloadKey = "catalog_settings_payload"
actual fun loadPayload(): String? =
NSUserDefaults.standardUserDefaults.stringForKey(payloadKey)
NSUserDefaults.standardUserDefaults.stringForKey(ProfileScopedKey.of(payloadKey))
actual fun savePayload(payload: String) {
NSUserDefaults.standardUserDefaults.setObject(payload, forKey = payloadKey)
NSUserDefaults.standardUserDefaults.setObject(payload, forKey = ProfileScopedKey.of(payloadKey))
}
}

View file

@ -1,5 +1,6 @@
package com.nuvio.app.features.player
import com.nuvio.app.core.storage.ProfileScopedKey
import platform.Foundation.NSUserDefaults
actual object PlayerSettingsStorage {
@ -7,14 +8,15 @@ actual object PlayerSettingsStorage {
actual fun loadShowLoadingOverlay(): Boolean? {
val defaults = NSUserDefaults.standardUserDefaults
return if (defaults.objectForKey(showLoadingOverlayKey) != null) {
defaults.boolForKey(showLoadingOverlayKey)
val key = ProfileScopedKey.of(showLoadingOverlayKey)
return if (defaults.objectForKey(key) != null) {
defaults.boolForKey(key)
} else {
null
}
}
actual fun saveShowLoadingOverlay(enabled: Boolean) {
NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = showLoadingOverlayKey)
NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(showLoadingOverlayKey))
}
}

View file

@ -1,5 +1,6 @@
package com.nuvio.app.features.settings
import com.nuvio.app.core.storage.ProfileScopedKey
import platform.Foundation.NSUserDefaults
actual object ThemeSettingsStorage {
@ -7,22 +8,23 @@ actual object ThemeSettingsStorage {
private const val amoledEnabledKey = "amoled_enabled"
actual fun loadSelectedTheme(): String? =
NSUserDefaults.standardUserDefaults.stringForKey(selectedThemeKey)
NSUserDefaults.standardUserDefaults.stringForKey(ProfileScopedKey.of(selectedThemeKey))
actual fun saveSelectedTheme(themeName: String) {
NSUserDefaults.standardUserDefaults.setObject(themeName, forKey = selectedThemeKey)
NSUserDefaults.standardUserDefaults.setObject(themeName, forKey = ProfileScopedKey.of(selectedThemeKey))
}
actual fun loadAmoledEnabled(): Boolean? {
val defaults = NSUserDefaults.standardUserDefaults
return if (defaults.objectForKey(amoledEnabledKey) != null) {
defaults.boolForKey(amoledEnabledKey)
val key = ProfileScopedKey.of(amoledEnabledKey)
return if (defaults.objectForKey(key) != null) {
defaults.boolForKey(key)
} else {
null
}
}
actual fun saveAmoledEnabled(enabled: Boolean) {
NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = amoledEnabledKey)
NSUserDefaults.standardUserDefaults.setBool(enabled, forKey = ProfileScopedKey.of(amoledEnabledKey))
}
}

View file

@ -1,14 +1,15 @@
package com.nuvio.app.features.watchprogress
import com.nuvio.app.core.storage.ProfileScopedKey
import platform.Foundation.NSUserDefaults
actual object ContinueWatchingPreferencesStorage {
private const val payloadKey = "continue_watching_preferences_payload"
actual fun loadPayload(): String? =
NSUserDefaults.standardUserDefaults.stringForKey(payloadKey)
NSUserDefaults.standardUserDefaults.stringForKey(ProfileScopedKey.of(payloadKey))
actual fun savePayload(payload: String) {
NSUserDefaults.standardUserDefaults.setObject(payload, forKey = payloadKey)
NSUserDefaults.standardUserDefaults.setObject(payload, forKey = ProfileScopedKey.of(payloadKey))
}
}