Change backup proto & improve code of backup/restore category related preferences (mihonapp/mihon#1726)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> (cherry picked from commit e1724d1aa0e3340e1404cfd80bd264831d86a879)
This commit is contained in:
parent
e062b97f5f
commit
707d9854ec
8 changed files with 91 additions and 173 deletions
|
|
@ -25,6 +25,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Fix Bangumi and MAL tracking 401 errors due to Mihon sending expired credentials ([@MajorTanya](https://github.com/MajorTanya)) ([#1681](https://github.com/mihonapp/mihon/pull/1681), [#1682](https://github.com/mihonapp/mihon/pull/1682))
|
||||
- Fix certain Infinix devices being unable to use any "Open link in browser" actions, including tracker setup ([@MajorTanya](https://github.com/MajorTanya)) ([#1684](https://github.com/mihonapp/mihon/pull/1684))
|
||||
- Fix App's preferences referencing deleted categories ([@cuong-tran](https://github.com/cuong-tran)) ([#1734](https://github.com/mihonapp/mihon/pull/1734))
|
||||
- Fix backup/restore of category related preferences ([@cuong-tran](https://github.com/cuong-tran)) ([#1726](https://github.com/mihonapp/mihon/pull/1726))
|
||||
|
||||
### Other
|
||||
- Add zoned "Current time" to debug info and include year & timezone in logcat output ([@MajorTanya](https://github.com/MajorTanya)) ([#1672](https://github.com/mihonapp/mihon/pull/1672))
|
||||
|
|
|
|||
|
|
@ -13,14 +13,6 @@ import eu.kanade.tachiyomi.source.preferenceKey
|
|||
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||
import tachiyomi.core.common.preference.Preference
|
||||
import tachiyomi.core.common.preference.PreferenceStore
|
||||
import tachiyomi.domain.category.interactor.GetCategories
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.DOWNLOAD_NEW_CATEGORIES_PREF_KEY
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.REMOVE_EXCLUDE_CATEGORIES_PREF_KEY
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEFAULT_CATEGORY_PREF_KEY
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.LIBRARY_UPDATE_CATEGORIES_PREF_KEY
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
|
@ -29,48 +21,9 @@ class PreferenceBackupCreator(
|
|||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val preferenceStore: PreferenceStore = Injekt.get(),
|
||||
) {
|
||||
// KMK -->
|
||||
private val getCategories by lazy { Injekt.get<GetCategories>() }
|
||||
private val libraryPreferences by lazy { Injekt.get<LibraryPreferences>() }
|
||||
// <--
|
||||
|
||||
/* KMK --> */ suspend /* KMK <-- */ fun createApp(includePrivatePreferences: Boolean): List<BackupPreference> {
|
||||
// KMK -->
|
||||
val allCategories = getCategories.await()
|
||||
// KMK <--
|
||||
|
||||
fun createApp(includePrivatePreferences: Boolean): List<BackupPreference> {
|
||||
return preferenceStore.getAll().toBackupPreferences()
|
||||
// KMK -->
|
||||
.map { backupPreference ->
|
||||
when (backupPreference.key) {
|
||||
// Convert CategoryId to CategoryOrder
|
||||
DEFAULT_CATEGORY_PREF_KEY -> {
|
||||
val id = (backupPreference.value as IntPreferenceValue).value.toLong()
|
||||
val value = allCategories.find { it.id == id }?.order?.toInt()
|
||||
?: libraryPreferences.defaultCategory().defaultValue()
|
||||
BackupPreference(
|
||||
backupPreference.key,
|
||||
IntPreferenceValue(value),
|
||||
)
|
||||
}
|
||||
// Convert CategoryId to CategoryOrder
|
||||
LIBRARY_UPDATE_CATEGORIES_PREF_KEY, LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
DOWNLOAD_NEW_CATEGORIES_PREF_KEY, DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
REMOVE_EXCLUDE_CATEGORIES_PREF_KEY,
|
||||
-> {
|
||||
val categoryIds = (backupPreference.value as StringSetPreferenceValue).value
|
||||
val categories = allCategories.associateBy({ it.id.toString() }, { it.order.toString() })
|
||||
BackupPreference(
|
||||
backupPreference.key,
|
||||
StringSetPreferenceValue(
|
||||
categoryIds.mapNotNull { categories[it] }.toSet(),
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> backupPreference
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
.withPrivatePreferences(includePrivatePreferences)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import tachiyomi.domain.category.model.Category
|
|||
class BackupCategory(
|
||||
@ProtoNumber(1) var name: String,
|
||||
@ProtoNumber(2) var order: Long = 0,
|
||||
@ProtoNumber(3) var id: Long = 0,
|
||||
// @ProtoNumber(3) val updateInterval: Int = 0, 1.x value not used in 0.x
|
||||
@ProtoNumber(100) var flags: Long = 0,
|
||||
// KMK -->
|
||||
|
|
@ -30,6 +31,7 @@ class BackupCategory(
|
|||
|
||||
val backupCategoryMapper = { category: Category ->
|
||||
BackupCategory(
|
||||
id = category.id,
|
||||
name = category.name,
|
||||
order = category.order,
|
||||
flags = category.flags,
|
||||
|
|
|
|||
|
|
@ -117,12 +117,7 @@ class BackupRestorer(
|
|||
}
|
||||
// SY <--
|
||||
if (options.appSettings) {
|
||||
restoreAppPreferences(
|
||||
backup.backupPreferences,
|
||||
// KMK ->
|
||||
if (options.categories) backup.backupCategories else emptyList(),
|
||||
// KMK <--
|
||||
)
|
||||
restoreAppPreferences(backup.backupPreferences, backup.backupCategories.takeIf { options.categories })
|
||||
}
|
||||
if (options.sourceSettings) {
|
||||
restoreSourcePreferences(backup.backupSourcePreferences)
|
||||
|
|
@ -197,16 +192,12 @@ class BackupRestorer(
|
|||
|
||||
private fun CoroutineScope.restoreAppPreferences(
|
||||
preferences: List<BackupPreference>,
|
||||
// KMK -->
|
||||
backupCategories: List<BackupCategory>,
|
||||
// KMK <--
|
||||
categories: List<BackupCategory>?,
|
||||
) = launch {
|
||||
ensureActive()
|
||||
preferenceRestorer.restoreApp(
|
||||
preferences,
|
||||
// KMK -->
|
||||
backupCategories,
|
||||
// KMK <--
|
||||
categories,
|
||||
)
|
||||
|
||||
restoreProgress += 1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.data.backup.restore.restorers
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.domain.source.service.SourcePreferences.Companion.PINNED_SOURCES_PREF_KEY
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.data.backup.create.BackupCreateJob
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupPreference
|
||||
|
|
@ -19,38 +19,27 @@ import exh.EXHMigrations
|
|||
import exh.log.xLogE
|
||||
import tachiyomi.core.common.preference.AndroidPreferenceStore
|
||||
import tachiyomi.core.common.preference.PreferenceStore
|
||||
import tachiyomi.core.common.preference.plusAssign
|
||||
import tachiyomi.domain.category.interactor.GetCategories
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.DOWNLOAD_NEW_CATEGORIES_PREF_KEY
|
||||
import tachiyomi.domain.download.service.DownloadPreferences.Companion.REMOVE_EXCLUDE_CATEGORIES_PREF_KEY
|
||||
import tachiyomi.domain.category.model.Category
|
||||
import tachiyomi.domain.download.service.DownloadPreferences
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEFAULT_CATEGORY_PREF_KEY
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.LIBRARY_UPDATE_CATEGORIES_PREF_KEY
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class PreferenceRestorer(
|
||||
private val context: Context,
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val preferenceStore: PreferenceStore = Injekt.get(),
|
||||
) {
|
||||
// KMK -->
|
||||
private val getCategories by lazy { Injekt.get<GetCategories>() }
|
||||
private val libraryPreferences by lazy { Injekt.get<LibraryPreferences>() }
|
||||
// <--
|
||||
|
||||
/* KMK --> */ suspend /* KMK <-- */ fun restoreApp(
|
||||
suspend fun restoreApp(
|
||||
preferences: List<BackupPreference>,
|
||||
// KMK -->
|
||||
backupCategories: List<BackupCategory>,
|
||||
// KMK <--
|
||||
backupCategories: List<BackupCategory>?,
|
||||
) {
|
||||
restorePreferences(
|
||||
preferences,
|
||||
preferenceStore,
|
||||
// KMK -->
|
||||
backupCategories,
|
||||
// KMK <--
|
||||
)
|
||||
|
||||
LibraryUpdateJob.setupTask(context)
|
||||
|
|
@ -60,52 +49,35 @@ class PreferenceRestorer(
|
|||
// KMK <--
|
||||
}
|
||||
|
||||
/* KMK --> */ suspend /* KMK <-- */ fun restoreSource(preferences: List<BackupSourcePreferences>) {
|
||||
suspend fun restoreSource(preferences: List<BackupSourcePreferences>) {
|
||||
preferences.forEach {
|
||||
val sourcePrefs = AndroidPreferenceStore(context, sourcePreferences(it.sourceKey))
|
||||
restorePreferences(it.prefs, sourcePrefs)
|
||||
}
|
||||
}
|
||||
|
||||
private /* KMK --> */ suspend /* KMK <-- */ fun restorePreferences(
|
||||
private suspend fun restorePreferences(
|
||||
toRestore: List<BackupPreference>,
|
||||
preferenceStore: PreferenceStore,
|
||||
// KMK -->
|
||||
backupCategories: List<BackupCategory> = emptyList(),
|
||||
// KMK <--
|
||||
backupCategories: List<BackupCategory>? = null,
|
||||
) {
|
||||
// KMK -->
|
||||
val allCategories = getCategories.await()
|
||||
val allCategories = if (backupCategories != null) getCategories.await() else emptyList()
|
||||
val categoriesByName = allCategories.associateBy { it.name }
|
||||
val backupCategoriesByOrder = backupCategories.associateBy { it.order.toString() }
|
||||
// KMK <--
|
||||
val backupCategoriesById = backupCategories?.associateBy { it.id.toString() }.orEmpty()
|
||||
val prefs = preferenceStore.getAll()
|
||||
toRestore.forEach { (key, value) ->
|
||||
// KMK -->
|
||||
try {
|
||||
// KMK <--
|
||||
when (value) {
|
||||
is IntPreferenceValue -> {
|
||||
if (prefs[key] is Int?) {
|
||||
// KMK -->
|
||||
when (key) {
|
||||
// Convert CategoryOrder to CategoryId
|
||||
DEFAULT_CATEGORY_PREF_KEY -> {
|
||||
if (backupCategories.isNotEmpty()) {
|
||||
val order = value.value.toLong()
|
||||
val newValue = backupCategories.find { it.order == order }
|
||||
?.let {
|
||||
categoriesByName[it.name]?.id?.toInt()
|
||||
val newValue = if (key == LibraryPreferences.DEFAULT_CATEGORY_PREF_KEY) {
|
||||
backupCategoriesById[value.value.toString()]
|
||||
?.let { categoriesByName[it.name]?.id?.toInt() }
|
||||
} else {
|
||||
value.value
|
||||
}
|
||||
?: libraryPreferences.defaultCategory().defaultValue()
|
||||
|
||||
preferenceStore.getInt(key).set(newValue)
|
||||
}
|
||||
}
|
||||
else ->
|
||||
// KMK <--
|
||||
preferenceStore.getInt(key).set(value.value)
|
||||
}
|
||||
newValue?.let { preferenceStore.getInt(key).set(it) }
|
||||
}
|
||||
}
|
||||
is LongPreferenceValue -> {
|
||||
|
|
@ -130,25 +102,18 @@ class PreferenceRestorer(
|
|||
}
|
||||
is StringSetPreferenceValue -> {
|
||||
if (prefs[key] is Set<*>?) {
|
||||
val restored = restoreCategoriesPreference(
|
||||
key,
|
||||
value.value,
|
||||
preferenceStore,
|
||||
backupCategoriesById,
|
||||
categoriesByName,
|
||||
)
|
||||
if (!restored) {
|
||||
// KMK -->
|
||||
when (key) {
|
||||
PINNED_SOURCES_PREF_KEY -> {
|
||||
SourcePreferences.PINNED_SOURCES_PREF_KEY ->
|
||||
EXHMigrations.migratePinnedSources(value.value)
|
||||
}
|
||||
// Convert CategoryOrder to CategoryId
|
||||
LIBRARY_UPDATE_CATEGORIES_PREF_KEY, LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
DOWNLOAD_NEW_CATEGORIES_PREF_KEY, DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
REMOVE_EXCLUDE_CATEGORIES_PREF_KEY,
|
||||
-> {
|
||||
val newValue = value.value.mapNotNull { order ->
|
||||
backupCategoriesByOrder[order]?.let { backupCategory ->
|
||||
categoriesByName[backupCategory.name]?.id?.toString()
|
||||
}
|
||||
}.toSet()
|
||||
if (newValue.isNotEmpty()) {
|
||||
preferenceStore.getStringSet(key).set(newValue)
|
||||
}
|
||||
}
|
||||
else ->
|
||||
// KMK <--
|
||||
preferenceStore.getStringSet(key).set(value.value)
|
||||
|
|
@ -156,11 +121,34 @@ class PreferenceRestorer(
|
|||
}
|
||||
}
|
||||
}
|
||||
// KMK -->
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// KMK -->
|
||||
xLogE("Failed to restore preference <$key>", e)
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreCategoriesPreference(
|
||||
key: String,
|
||||
value: Set<String>,
|
||||
preferenceStore: PreferenceStore,
|
||||
backupCategoriesById: Map<String, BackupCategory>,
|
||||
categoriesByName: Map<String, Category>,
|
||||
): Boolean {
|
||||
val categoryPreferences = LibraryPreferences.categoryPreferenceKeys + DownloadPreferences.categoryPreferenceKeys
|
||||
if (key !in categoryPreferences) return false
|
||||
|
||||
val ids = value.mapNotNull {
|
||||
backupCategoriesById[it]?.name?.let { name ->
|
||||
categoriesByName[name]?.id?.toString()
|
||||
}
|
||||
}
|
||||
|
||||
if (ids.isNotEmpty()) {
|
||||
preferenceStore.getStringSet(key) += ids
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
|
|||
set(get() + item)
|
||||
}
|
||||
|
||||
operator fun <T> Preference<Set<T>>.plusAssign(items: Iterable<T>) {
|
||||
set(get() + items)
|
||||
}
|
||||
|
||||
operator fun <T> Preference<Set<T>>.minusAssign(item: T) {
|
||||
set(get() - item)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,38 +26,29 @@ class DownloadPreferences(
|
|||
|
||||
fun removeBookmarkedChapters() = preferenceStore.getBoolean("pref_remove_bookmarked", false)
|
||||
|
||||
fun removeExcludeCategories() = preferenceStore.getStringSet(
|
||||
// KMK -->
|
||||
REMOVE_EXCLUDE_CATEGORIES_PREF_KEY,
|
||||
// KMK <--
|
||||
emptySet(),
|
||||
)
|
||||
fun removeExcludeCategories() = preferenceStore.getStringSet(REMOVE_EXCLUDE_CATEGORIES_PREF_KEY, emptySet())
|
||||
|
||||
fun downloadNewChapters() = preferenceStore.getBoolean("download_new", false)
|
||||
|
||||
fun downloadNewChapterCategories() = preferenceStore.getStringSet(
|
||||
// KMK -->
|
||||
DOWNLOAD_NEW_CATEGORIES_PREF_KEY,
|
||||
// KMK <--
|
||||
emptySet(),
|
||||
)
|
||||
fun downloadNewChapterCategories() = preferenceStore.getStringSet(DOWNLOAD_NEW_CATEGORIES_PREF_KEY, emptySet())
|
||||
|
||||
fun downloadNewChapterCategoriesExclude() = preferenceStore.getStringSet(
|
||||
// KMK -->
|
||||
DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
// KMK <--
|
||||
emptySet(),
|
||||
)
|
||||
fun downloadNewChapterCategoriesExclude() =
|
||||
preferenceStore.getStringSet(DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY, emptySet())
|
||||
|
||||
fun downloadNewUnreadChaptersOnly() = preferenceStore.getBoolean("download_new_unread_chapters_only", false)
|
||||
|
||||
// KMK -->
|
||||
fun downloadCacheRenewInterval() = preferenceStore.getInt("download_cache_renew_interval", 1)
|
||||
// KMK <--
|
||||
|
||||
companion object {
|
||||
const val REMOVE_EXCLUDE_CATEGORIES_PREF_KEY = "remove_exclude_categories"
|
||||
const val DOWNLOAD_NEW_CATEGORIES_PREF_KEY = "download_new_categories"
|
||||
const val DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY = "download_new_categories_exclude"
|
||||
private const val REMOVE_EXCLUDE_CATEGORIES_PREF_KEY = "remove_exclude_categories"
|
||||
private const val DOWNLOAD_NEW_CATEGORIES_PREF_KEY = "download_new_categories"
|
||||
private const val DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY = "download_new_categories_exclude"
|
||||
val categoryPreferenceKeys = setOf(
|
||||
REMOVE_EXCLUDE_CATEGORIES_PREF_KEY,
|
||||
DOWNLOAD_NEW_CATEGORIES_PREF_KEY,
|
||||
DOWNLOAD_NEW_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
)
|
||||
}
|
||||
// KMK <--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,12 +144,7 @@ class LibraryPreferences(
|
|||
|
||||
// region Category
|
||||
|
||||
fun defaultCategory() = preferenceStore.getInt(
|
||||
// KMK -->
|
||||
DEFAULT_CATEGORY_PREF_KEY,
|
||||
// KMK <--
|
||||
-1,
|
||||
)
|
||||
fun defaultCategory() = preferenceStore.getInt(DEFAULT_CATEGORY_PREF_KEY, -1)
|
||||
|
||||
fun lastUsedCategory() = preferenceStore.getInt(Preference.appStateKey("last_used_category"), 0)
|
||||
|
||||
|
|
@ -163,19 +158,9 @@ class LibraryPreferences(
|
|||
fun showHiddenCategories() = preferenceStore.getBoolean("hide_hidden_categories", false)
|
||||
// KMK <--
|
||||
|
||||
fun updateCategories() = preferenceStore.getStringSet(
|
||||
// KMK -->
|
||||
LIBRARY_UPDATE_CATEGORIES_PREF_KEY,
|
||||
// KMK <--
|
||||
emptySet(),
|
||||
)
|
||||
fun updateCategories() = preferenceStore.getStringSet(LIBRARY_UPDATE_CATEGORIES_PREF_KEY, emptySet())
|
||||
|
||||
fun updateCategoriesExclude() = preferenceStore.getStringSet(
|
||||
// KMK -->
|
||||
LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
// KMK <--
|
||||
emptySet(),
|
||||
)
|
||||
fun updateCategoriesExclude() = preferenceStore.getStringSet(LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY, emptySet())
|
||||
|
||||
// endregion
|
||||
|
||||
|
|
@ -268,10 +253,13 @@ class LibraryPreferences(
|
|||
const val MANGA_NON_READ = "manga_started"
|
||||
const val MANGA_OUTSIDE_RELEASE_PERIOD = "manga_outside_release_period"
|
||||
|
||||
// KMK -->
|
||||
const val DEFAULT_CATEGORY_PREF_KEY = "default_category"
|
||||
const val LIBRARY_UPDATE_CATEGORIES_PREF_KEY = "library_update_categories"
|
||||
const val LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY = "library_update_categories_exclude"
|
||||
// KMK <--
|
||||
private const val LIBRARY_UPDATE_CATEGORIES_PREF_KEY = "library_update_categories"
|
||||
private const val LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY = "library_update_categories_exclude"
|
||||
val categoryPreferenceKeys = setOf(
|
||||
DEFAULT_CATEGORY_PREF_KEY,
|
||||
LIBRARY_UPDATE_CATEGORIES_PREF_KEY,
|
||||
LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue