Add source preferences to backups
Closes #1857 Co-authored-by: jmir1 <jmir1@users.noreply.github.com>
Cette révision appartient à :
Parent
730f3a6e52
révision
0f42b9f154
9 fichiers modifiés avec 63 ajouts et 16 suppressions
|
@ -148,6 +148,7 @@ object SettingsBackupScreen : SearchableSettings {
|
|||
BackupConst.BACKUP_TRACK to R.string.track,
|
||||
BackupConst.BACKUP_HISTORY to R.string.history,
|
||||
BackupConst.BACKUP_APP_PREFS to R.string.app_settings,
|
||||
BackupConst.BACKUP_SOURCE_PREFS to R.string.source_settings,
|
||||
)
|
||||
}
|
||||
val flags = remember { choices.keys.toMutableStateList() }
|
||||
|
|
|
@ -17,5 +17,8 @@ internal object BackupConst {
|
|||
const val BACKUP_APP_PREFS = 0x10
|
||||
const val BACKUP_APP_PREFS_MASK = 0x10
|
||||
|
||||
const val BACKUP_ALL = 0x1F
|
||||
const val BACKUP_SOURCE_PREFS = 0x20
|
||||
const val BACKUP_SOURCE_PREFS_MASK = 0x20
|
||||
|
||||
const val BACKUP_ALL = 0x3F
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@ import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY
|
|||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CHAPTER_MASK
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_SOURCE_PREFS
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_SOURCE_PREFS_MASK
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_HISTORY_MASK
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK
|
||||
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_TRACK_MASK
|
||||
import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupPreference
|
||||
|
@ -32,7 +35,10 @@ import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
|||
import eu.kanade.tachiyomi.data.backup.models.backupCategoryMapper
|
||||
import eu.kanade.tachiyomi.data.backup.models.backupChapterMapper
|
||||
import eu.kanade.tachiyomi.data.backup.models.backupTrackMapper
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.copyFrom
|
||||
import eu.kanade.tachiyomi.source.preferenceKey
|
||||
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||
import eu.kanade.tachiyomi.util.system.hasPermission
|
||||
import kotlinx.serialization.protobuf.ProtoBuf
|
||||
import logcat.LogPriority
|
||||
|
@ -94,6 +100,7 @@ class BackupManager(
|
|||
emptyList(),
|
||||
prepExtensionInfoForSync(databaseManga),
|
||||
backupAppPreferences(flags),
|
||||
backupSourcePreferences(flags),
|
||||
)
|
||||
|
||||
var file: UniFile? = null
|
||||
|
@ -232,12 +239,28 @@ class BackupManager(
|
|||
return mangaObject
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun backupAppPreferences(flags: Int): List<BackupPreference> {
|
||||
if (flags and BACKUP_APP_PREFS_MASK != BACKUP_APP_PREFS) return emptyList()
|
||||
|
||||
return preferenceStore.getAll()
|
||||
.filterKeys { !Preference.isPrivate(it) }
|
||||
return preferenceStore.getAll().toBackupPreferences()
|
||||
}
|
||||
|
||||
private fun backupSourcePreferences(flags: Int): List<BackupSourcePreferences> {
|
||||
if (flags and BACKUP_SOURCE_PREFS_MASK != BACKUP_SOURCE_PREFS) return emptyList()
|
||||
|
||||
return sourceManager.getOnlineSources()
|
||||
.filterIsInstance<ConfigurableSource>()
|
||||
.map {
|
||||
BackupSourcePreferences(
|
||||
it.preferenceKey(),
|
||||
it.sourcePreferences().all.toBackupPreferences()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun Map<String, *>.toBackupPreferences(): List<BackupPreference> {
|
||||
return this.filterKeys { !Preference.isPrivate(it) }
|
||||
.mapNotNull { (key, value) ->
|
||||
when (value) {
|
||||
is Int -> BackupPreference(key, IntPreferenceValue(value))
|
||||
|
|
|
@ -9,16 +9,19 @@ import eu.kanade.tachiyomi.data.backup.models.BackupHistory
|
|||
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupPreference
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupSource
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupSourcePreferences
|
||||
import eu.kanade.tachiyomi.data.backup.models.BooleanPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.models.FloatPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.models.IntPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.models.LongPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.models.StringPreferenceValue
|
||||
import eu.kanade.tachiyomi.data.backup.models.StringSetPreferenceValue
|
||||
import eu.kanade.tachiyomi.source.sourcePreferences
|
||||
import eu.kanade.tachiyomi.util.BackupUtil
|
||||
import eu.kanade.tachiyomi.util.system.createFileInCacheDir
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.isActive
|
||||
import tachiyomi.core.preference.AndroidPreferenceStore
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
import tachiyomi.domain.manga.interactor.FetchInterval
|
||||
|
@ -114,6 +117,7 @@ class BackupRestorer(
|
|||
|
||||
return coroutineScope {
|
||||
restoreAppPreferences(backup.backupPreferences)
|
||||
restoreSourcePreferences(backup.backupSourcePreferences)
|
||||
|
||||
// Restore individual manga
|
||||
backup.backupManga.forEach {
|
||||
|
@ -211,9 +215,22 @@ class BackupRestorer(
|
|||
}
|
||||
|
||||
private fun restoreAppPreferences(preferences: List<BackupPreference>) {
|
||||
val prefs = preferenceStore.getAll()
|
||||
restorePreferences(preferences, preferenceStore)
|
||||
}
|
||||
|
||||
preferences.forEach { (key, value) ->
|
||||
private fun restoreSourcePreferences(preferences: List<BackupSourcePreferences>) {
|
||||
preferences.forEach {
|
||||
val sourcePrefs = AndroidPreferenceStore(context, sourcePreferences(it.sourceKey))
|
||||
restorePreferences(it.prefs, sourcePrefs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun restorePreferences(
|
||||
toRestore: List<BackupPreference>,
|
||||
preferenceStore: PreferenceStore,
|
||||
) {
|
||||
val prefs = preferenceStore.getAll()
|
||||
toRestore.forEach { (key, value) ->
|
||||
when (value) {
|
||||
is IntPreferenceValue -> {
|
||||
if (prefs[key] is Int?) {
|
||||
|
@ -249,13 +266,6 @@ class BackupRestorer(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update dialog in [BackupConst]
|
||||
*
|
||||
* @param progress restore progress
|
||||
* @param amount total restoreAmount of manga
|
||||
* @param title title of restored manga
|
||||
*/
|
||||
private fun showRestoreProgress(progress: Int, amount: Int, title: String, contentTitle: String) {
|
||||
notifier.showRestoreProgress(title, contentTitle, progress, amount)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ data class Backup(
|
|||
@ProtoNumber(100) var backupBrokenSources: List<BrokenBackupSource> = emptyList(),
|
||||
@ProtoNumber(101) var backupSources: List<BackupSource> = emptyList(),
|
||||
@ProtoNumber(104) var backupPreferences: List<BackupPreference> = emptyList(),
|
||||
@ProtoNumber(105) var backupSourcePreferences: List<BackupSourcePreferences> = emptyList(),
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -9,6 +9,12 @@ data class BackupPreference(
|
|||
@ProtoNumber(2) val value: PreferenceValue,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class BackupSourcePreferences(
|
||||
@ProtoNumber(1) val sourceKey: String,
|
||||
@ProtoNumber(2) val prefs: List<BackupPreference>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
sealed class PreferenceValue
|
||||
|
||||
|
|
|
@ -15,10 +15,9 @@ import tachiyomi.core.preference.AndroidPreference.StringSetPrimitive
|
|||
|
||||
class AndroidPreferenceStore(
|
||||
context: Context,
|
||||
private val sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context),
|
||||
) : PreferenceStore {
|
||||
|
||||
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
private val keyFlow = sharedPreferences.keyFlow
|
||||
|
||||
override fun getString(key: String, defaultValue: String): Preference<String> {
|
||||
|
|
|
@ -494,6 +494,7 @@
|
|||
<string name="backup_in_progress">Backup is already in progress</string>
|
||||
<string name="backup_choice">What do you want to backup?</string>
|
||||
<string name="app_settings">App settings</string>
|
||||
<string name="source_settings">Source settings</string>
|
||||
<string name="creating_backup">Creating backup</string>
|
||||
<string name="creating_backup_error">Backup failed</string>
|
||||
<string name="missing_storage_permission">Storage permissions not granted</string>
|
||||
|
|
|
@ -19,8 +19,11 @@ interface ConfigurableSource : Source {
|
|||
fun setupPreferenceScreen(screen: PreferenceScreen)
|
||||
}
|
||||
|
||||
private fun ConfigurableSource.preferenceKey(): String = "source_$id"
|
||||
fun ConfigurableSource.preferenceKey(): String = "source_$id"
|
||||
|
||||
// TODO: use getSourcePreferences once all extensions are on ext-lib 1.5
|
||||
fun ConfigurableSource.sourcePreferences(): SharedPreferences =
|
||||
Injekt.get<Application>().getSharedPreferences(preferenceKey(), Context.MODE_PRIVATE)
|
||||
|
||||
fun sourcePreferences(key: String): SharedPreferences =
|
||||
Injekt.get<Application>().getSharedPreferences(key, Context.MODE_PRIVATE)
|
||||
|
|
Référencer dans un nouveau ticket