Check version when parsing

This commit is contained in:
Damontecres 2026-02-10 16:27:01 -05:00
parent 87245732af
commit 3879072c1d
No known key found for this signature in database
3 changed files with 29 additions and 5 deletions

View file

@ -181,10 +181,10 @@ sealed interface HomeRowConfig {
@SerialName("HomePageSettings") @SerialName("HomePageSettings")
data class HomePageSettings( data class HomePageSettings(
val rows: List<HomeRowConfig>, val rows: List<HomeRowConfig>,
val version: Int = SUPPORTED_HOME_PAGE_SETTINGS_VERSION, val version: Int,
) { ) {
companion object { companion object {
val EMPTY = HomePageSettings(listOf()) val EMPTY = HomePageSettings(listOf(), SUPPORTED_HOME_PAGE_SETTINGS_VERSION)
} }
} }

View file

@ -6,6 +6,7 @@ import com.github.damontecres.wholphin.data.NavDrawerItemRepository
import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.HomePageSettings import com.github.damontecres.wholphin.data.model.HomePageSettings
import com.github.damontecres.wholphin.data.model.HomeRowConfig import com.github.damontecres.wholphin.data.model.HomeRowConfig
import com.github.damontecres.wholphin.data.model.SUPPORTED_HOME_PAGE_SETTINGS_VERSION
import com.github.damontecres.wholphin.preferences.DefaultUserConfiguration import com.github.damontecres.wholphin.preferences.DefaultUserConfiguration
import com.github.damontecres.wholphin.preferences.HomePagePreferences import com.github.damontecres.wholphin.preferences.HomePagePreferences
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.DefaultItemFields
@ -30,8 +31,10 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToStream import kotlinx.serialization.json.encodeToStream
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi
import org.jellyfin.sdk.api.client.extensions.liveTvApi import org.jellyfin.sdk.api.client.extensions.liveTvApi
@ -174,6 +177,10 @@ class HomeSettingsService
* This is public only for testing * This is public only for testing
*/ */
fun decode(element: JsonElement): HomePageSettings { fun decode(element: JsonElement): HomePageSettings {
val version = element.jsonObject["version"]?.jsonPrimitive?.intOrNull
if (version == null || version > SUPPORTED_HOME_PAGE_SETTINGS_VERSION) {
throw UnsupportedHomeSettingsVersionException(version)
}
val rowsElement = element.jsonObject["rows"]?.jsonArray val rowsElement = element.jsonObject["rows"]?.jsonArray
val rows = val rows =
rowsElement rowsElement
@ -186,7 +193,7 @@ class HomeSettingsService
null null
} }
}.orEmpty() }.orEmpty()
return HomePageSettings(rows) return HomePageSettings(rows, version)
} }
/** /**
@ -928,3 +935,8 @@ enum class HomeSectionType(
fun fromString(homeKey: String?) = homeKey?.let { entries.firstOrNull { it.serialName == homeKey } } fun fromString(homeKey: String?) = homeKey?.let { entries.firstOrNull { it.serialName == homeKey } }
} }
} }
class UnsupportedHomeSettingsVersionException(
val unsupportedVersion: Int?,
val maxSupportedVersion: Int = SUPPORTED_HOME_PAGE_SETTINGS_VERSION,
) : Exception("Unsupported version $unsupportedVersion, max supported is $maxSupportedVersion")

View file

@ -20,12 +20,14 @@ import com.github.damontecres.wholphin.data.model.HomeRowConfig.RecentlyAdded
import com.github.damontecres.wholphin.data.model.HomeRowConfig.RecentlyReleased import com.github.damontecres.wholphin.data.model.HomeRowConfig.RecentlyReleased
import com.github.damontecres.wholphin.data.model.HomeRowConfig.Suggestions import com.github.damontecres.wholphin.data.model.HomeRowConfig.Suggestions
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
import com.github.damontecres.wholphin.data.model.SUPPORTED_HOME_PAGE_SETTINGS_VERSION
import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.preferences.AppPreferences
import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.BackdropService
import com.github.damontecres.wholphin.services.HomePageResolvedSettings import com.github.damontecres.wholphin.services.HomePageResolvedSettings
import com.github.damontecres.wholphin.services.HomeRowConfigDisplay import com.github.damontecres.wholphin.services.HomeRowConfigDisplay
import com.github.damontecres.wholphin.services.HomeSettingsService import com.github.damontecres.wholphin.services.HomeSettingsService
import com.github.damontecres.wholphin.services.SeerrServerRepository import com.github.damontecres.wholphin.services.SeerrServerRepository
import com.github.damontecres.wholphin.services.UnsupportedHomeSettingsVersionException
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope
import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.launchIO
@ -385,7 +387,8 @@ class HomeSettingsViewModel
serverRepository.currentUser.value?.let { user -> serverRepository.currentUser.value?.let { user ->
Timber.d("Saving home settings to remote") Timber.d("Saving home settings to remote")
val rows = state.value.rows.map { it.config } val rows = state.value.rows.map { it.config }
val settings = HomePageSettings(rows = rows) val settings =
HomePageSettings(rows = rows, SUPPORTED_HOME_PAGE_SETTINGS_VERSION)
try { try {
Timber.d("saveToRemote") Timber.d("saveToRemote")
homeSettingsService.saveToServer(user.id, settings) homeSettingsService.saveToServer(user.id, settings)
@ -418,6 +421,10 @@ class HomeSettingsViewModel
showToast(context, "No server-side settings found") showToast(context, "No server-side settings found")
} }
fetchRowData() fetchRowData()
} catch (ex: UnsupportedHomeSettingsVersionException) {
// TODO
Timber.w(ex)
showToast(context, "Error: ${ex.localizedMessage}")
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.e(ex) Timber.e(ex)
showToast(context, "Error: ${ex.localizedMessage}") showToast(context, "Error: ${ex.localizedMessage}")
@ -456,7 +463,8 @@ class HomeSettingsViewModel
ioScope.launchIO { ioScope.launchIO {
serverRepository.currentUser.value?.let { user -> serverRepository.currentUser.value?.let { user ->
val rows = state.value.rows.map { it.config } val rows = state.value.rows.map { it.config }
val settings = HomePageSettings(rows = rows) val settings =
HomePageSettings(rows = rows, SUPPORTED_HOME_PAGE_SETTINGS_VERSION)
try { try {
Timber.d("saveToLocal") Timber.d("saveToLocal")
val local = homeSettingsService.loadFromLocal(user.id) val local = homeSettingsService.loadFromLocal(user.id)
@ -465,6 +473,10 @@ class HomeSettingsViewModel
homeSettingsService.saveToLocal(user.id, settings) homeSettingsService.saveToLocal(user.id, settings)
showToast(context, context.getString(R.string.save), Toast.LENGTH_SHORT) showToast(context, context.getString(R.string.save), Toast.LENGTH_SHORT)
} }
} catch (ex: UnsupportedHomeSettingsVersionException) {
Timber.w(ex, "Overwriting local settings")
homeSettingsService.saveToLocal(user.id, settings)
showToast(context, context.getString(R.string.save), Toast.LENGTH_SHORT)
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.e(ex) Timber.e(ex)
showToast(context, "Error saving: ${ex.localizedMessage}") showToast(context, "Error saving: ${ex.localizedMessage}")