From 1763d947dfff7a6ae3173ddfabec12601203df36 Mon Sep 17 00:00:00 2001 From: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com> Date: Thu, 9 Jul 2026 02:43:00 +0700 Subject: [PATCH] chore(sync): migrate sync preference keys (#1747) --- .../eu/kanade/domain/sync/SyncPreferences.kt | 64 ++++++++--------- .../core/migration/migrations/Migrations.kt | 1 + .../migrations/SyncPrefKeyMigration.kt | 70 +++++++++++++++++++ 3 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/mihon/core/migration/migrations/SyncPrefKeyMigration.kt diff --git a/app/src/main/java/eu/kanade/domain/sync/SyncPreferences.kt b/app/src/main/java/eu/kanade/domain/sync/SyncPreferences.kt index 2537563a5..7d0fbf1f0 100644 --- a/app/src/main/java/eu/kanade/domain/sync/SyncPreferences.kt +++ b/app/src/main/java/eu/kanade/domain/sync/SyncPreferences.kt @@ -10,8 +10,8 @@ import java.util.UUID class SyncPreferences( private val preferenceStore: PreferenceStore, ) { - fun clientHost() = preferenceStore.getString("sync_client_host", "https://sync.tachiyomi.org") - fun clientAPIKey() = preferenceStore.getString("sync_client_api_key", "") + fun clientHost() = preferenceStore.getString("connection_sync_client_host", "https://sync.tachiyomi.org") + fun clientAPIKey() = preferenceStore.getString("connection_sync_client_api_key", "") fun lastSyncTimestamp() = preferenceStore.getLong(Preference.appStateKey("last_sync_timestamp"), 0L) fun lastSyncEtag() = preferenceStore.getString("sync_etag", "") @@ -20,19 +20,19 @@ class SyncPreferences( fun syncService() = preferenceStore.getInt("sync_service", 0) // KMK --> - fun webDavUrl() = preferenceStore.getString("webdav_url", "") - fun webDavUsername() = preferenceStore.getString("webdav_username", "") - fun webDavPassword() = preferenceStore.getString("webdav_password", "") - fun webDavFolder() = preferenceStore.getString("webdav_folder", "komikku") + fun webDavUrl() = preferenceStore.getString("connection_webdav_url", "") + fun webDavUsername() = preferenceStore.getString("connection_webdav_username", "") + fun webDavPassword() = preferenceStore.getString("connection_webdav_password", "") + fun webDavFolder() = preferenceStore.getString("connection_webdav_folder", "komikku") // KMK <-- fun googleDriveAccessToken() = preferenceStore.getString( - Preference.appStateKey("google_drive_access_token"), + Preference.appStateKey("connection_google_drive_access_token"), "", ) fun googleDriveRefreshToken() = preferenceStore.getString( - Preference.appStateKey("google_drive_refresh_token"), + Preference.appStateKey("connection_google_drive_refresh_token"), "", ) @@ -55,39 +55,39 @@ class SyncPreferences( fun getSyncSettings(): SyncSettings { return SyncSettings( - libraryEntries = preferenceStore.getBoolean("library_entries", true).get(), - categories = preferenceStore.getBoolean("categories", true).get(), - chapters = preferenceStore.getBoolean("chapters", true).get(), - tracking = preferenceStore.getBoolean("tracking", true).get(), - history = preferenceStore.getBoolean("history", true).get(), - appSettings = preferenceStore.getBoolean("appSettings", true).get(), - extensionStores = preferenceStore.getBoolean("extensionStores", true).get(), - sourceSettings = preferenceStore.getBoolean("sourceSettings", true).get(), - privateSettings = preferenceStore.getBoolean("privateSettings", true).get(), + libraryEntries = preferenceStore.getBoolean("sync_library_entries", true).get(), + categories = preferenceStore.getBoolean("sync_categories", true).get(), + chapters = preferenceStore.getBoolean("sync_chapters", true).get(), + tracking = preferenceStore.getBoolean("sync_tracking", true).get(), + history = preferenceStore.getBoolean("sync_history", true).get(), + appSettings = preferenceStore.getBoolean("sync_appSettings", true).get(), + extensionStores = preferenceStore.getBoolean("sync_extensionStores", true).get(), + sourceSettings = preferenceStore.getBoolean("sync_sourceSettings", true).get(), + privateSettings = preferenceStore.getBoolean("sync_privateSettings", true).get(), // SY --> - customInfo = preferenceStore.getBoolean("customInfo", true).get(), - readEntries = preferenceStore.getBoolean("readEntries", true).get(), - savedSearchesFeeds = preferenceStore.getBoolean("savedSearchesFeeds", true).get(), + customInfo = preferenceStore.getBoolean("sync_customInfo", true).get(), + readEntries = preferenceStore.getBoolean("sync_readEntries", true).get(), + savedSearchesFeeds = preferenceStore.getBoolean("sync_savedSearchesFeeds", true).get(), // SY <-- ) } fun setSyncSettings(syncSettings: SyncSettings) { - preferenceStore.getBoolean("library_entries", true).set(syncSettings.libraryEntries) - preferenceStore.getBoolean("categories", true).set(syncSettings.categories) - preferenceStore.getBoolean("chapters", true).set(syncSettings.chapters) - preferenceStore.getBoolean("tracking", true).set(syncSettings.tracking) - preferenceStore.getBoolean("history", true).set(syncSettings.history) - preferenceStore.getBoolean("appSettings", true).set(syncSettings.appSettings) - preferenceStore.getBoolean("extensionStores", true).set(syncSettings.extensionStores) - preferenceStore.getBoolean("sourceSettings", true).set(syncSettings.sourceSettings) - preferenceStore.getBoolean("privateSettings", true).set(syncSettings.privateSettings) + preferenceStore.getBoolean("sync_library_entries", true).set(syncSettings.libraryEntries) + preferenceStore.getBoolean("sync_categories", true).set(syncSettings.categories) + preferenceStore.getBoolean("sync_chapters", true).set(syncSettings.chapters) + preferenceStore.getBoolean("sync_tracking", true).set(syncSettings.tracking) + preferenceStore.getBoolean("sync_history", true).set(syncSettings.history) + preferenceStore.getBoolean("sync_appSettings", true).set(syncSettings.appSettings) + preferenceStore.getBoolean("sync_extensionStores", true).set(syncSettings.extensionStores) + preferenceStore.getBoolean("sync_sourceSettings", true).set(syncSettings.sourceSettings) + preferenceStore.getBoolean("sync_privateSettings", true).set(syncSettings.privateSettings) // SY --> - preferenceStore.getBoolean("customInfo", true).set(syncSettings.customInfo) - preferenceStore.getBoolean("readEntries", true).set(syncSettings.readEntries) - preferenceStore.getBoolean("savedSearchesFeeds", true).set(syncSettings.savedSearchesFeeds) + preferenceStore.getBoolean("sync_customInfo", true).set(syncSettings.customInfo) + preferenceStore.getBoolean("sync_readEntries", true).set(syncSettings.readEntries) + preferenceStore.getBoolean("sync_savedSearchesFeeds", true).set(syncSettings.savedSearchesFeeds) // SY <-- } diff --git a/app/src/main/java/mihon/core/migration/migrations/Migrations.kt b/app/src/main/java/mihon/core/migration/migrations/Migrations.kt index 0499e441b..ccb642fca 100644 --- a/app/src/main/java/mihon/core/migration/migrations/Migrations.kt +++ b/app/src/main/java/mihon/core/migration/migrations/Migrations.kt @@ -54,5 +54,6 @@ val migrations: List RemoveDuplicateReaderPreferenceMigration(), // KMK --> DisabledRepoMigration(), + SyncPrefKeyMigration(), // KMK <-- ) diff --git a/app/src/main/java/mihon/core/migration/migrations/SyncPrefKeyMigration.kt b/app/src/main/java/mihon/core/migration/migrations/SyncPrefKeyMigration.kt new file mode 100644 index 000000000..1cdfc7b26 --- /dev/null +++ b/app/src/main/java/mihon/core/migration/migrations/SyncPrefKeyMigration.kt @@ -0,0 +1,70 @@ +package mihon.core.migration.migrations + +import android.app.Application +import androidx.core.content.edit +import androidx.preference.PreferenceManager +import mihon.core.migration.Migration +import mihon.core.migration.MigrationContext +import tachiyomi.core.common.preference.Preference + +/** + * Migrates sync preference storage keys to namespaced forms so that + * connection keys ("connection_*") and sync-toggle keys ("sync_*") no longer + * collide with unrelated preferences. + */ +class SyncPrefKeyMigration : Migration { + override val version: Float = 80f + + override suspend fun invoke(migrationContext: MigrationContext): Boolean { + val context = migrationContext.get() ?: return false + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + val stringRenames = listOf( + // Sync service connection + "sync_client_host" to "connection_sync_client_host", + "sync_client_api_key" to "connection_sync_client_api_key", + // WebDAV connection (KMK) + "webdav_url" to "connection_webdav_url", + "webdav_username" to "connection_webdav_username", + "webdav_password" to "connection_webdav_password", + "webdav_folder" to "connection_webdav_folder", + // Google Drive tokens — appStateKey() prepends "__APP_STATE_" + Preference.appStateKey("google_drive_access_token") to Preference.appStateKey("connection_google_drive_access_token"), + Preference.appStateKey("google_drive_refresh_token") to Preference.appStateKey("connection_google_drive_refresh_token"), + ) + + val booleanRenames = listOf( + // Core sync toggles + "library_entries" to "sync_library_entries", + "categories" to "sync_categories", + "chapters" to "sync_chapters", + "tracking" to "sync_tracking", + "history" to "sync_history", + "appSettings" to "sync_appSettings", + "extensionRepoSettings" to "sync_extensionStores", + "sourceSettings" to "sync_sourceSettings", + "privateSettings" to "sync_privateSettings", + // SY sync toggles + "customInfo" to "sync_customInfo", + "readEntries" to "sync_readEntries", + "savedSearchesFeeds" to "sync_savedSearchesFeeds", + ) + + prefs.edit { + stringRenames.forEach { (oldKey, newKey) -> + if (prefs.contains(oldKey)) { + putString(newKey, prefs.getString(oldKey, null)) + remove(oldKey) + } + } + booleanRenames.forEach { (oldKey, newKey) -> + if (prefs.contains(oldKey)) { + putBoolean(newKey, prefs.getBoolean(oldKey, true)) + remove(oldKey) + } + } + } + + return true + } +}