From e1afceb769736aa12c24d0a3c9593b86f1f14ed8 Mon Sep 17 00:00:00 2001 From: arkon Date: Thu, 28 Dec 2023 16:44:46 -0500 Subject: [PATCH] Refactor backup option flags to normal data class of booleans (cherry picked from commit 8735836498f46f7b6dc35ff62ffb595e097d568e) # Conflicts: # app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt # app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateFlags.kt # app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt # app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt --- .../screen/data/CreateBackupScreen.kt | 58 +++------ .../data/backup/create/BackupCreateFlags.kt | 25 ---- .../data/backup/create/BackupCreateJob.kt | 12 +- .../data/backup/create/BackupCreator.kt | 32 +++-- .../data/backup/create/BackupOptions.kt | 115 ++++++++++++++++++ .../create/creators/MangaBackupCreator.kt | 23 ++-- .../creators/PreferenceBackupCreator.kt | 2 +- 7 files changed, 166 insertions(+), 101 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateFlags.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt index b28cb025a..0be2ad46d 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/data/CreateBackupScreen.kt @@ -29,16 +29,11 @@ import cafe.adriel.voyager.navigator.currentOrThrow import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.WarningBanner import eu.kanade.presentation.util.Screen -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags import eu.kanade.tachiyomi.data.backup.create.BackupCreateJob import eu.kanade.tachiyomi.data.backup.create.BackupCreator +import eu.kanade.tachiyomi.data.backup.create.BackupOptions import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.toast -import kotlinx.collections.immutable.PersistentSet -import kotlinx.collections.immutable.minus -import kotlinx.collections.immutable.persistentMapOf -import kotlinx.collections.immutable.persistentSetOf -import kotlinx.collections.immutable.plus import kotlinx.coroutines.flow.update import tachiyomi.i18n.MR import tachiyomi.i18n.sy.SYMR @@ -102,13 +97,13 @@ class CreateBackupScreen : Screen() { modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium), ) } - BackupChoices.forEach { (k, v) -> + BackupOptions.entries.forEach { option -> item { LabeledCheckbox( - label = stringResource(v), - checked = state.flags.contains(k), + label = stringResource(option.label), + checked = option.getter(state.options), onCheckedChange = { - model.toggleFlag(k) + model.toggle(option.setter, it) }, modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium), ) @@ -146,45 +141,32 @@ class CreateBackupScreen : Screen() { private class CreateBackupScreenModel : StateScreenModel(State()) { - fun toggleFlag(flag: Int) { + fun toggle(setter: (BackupOptions, Boolean) -> BackupOptions, enabled: Boolean) { mutableState.update { - if (it.flags.contains(flag)) { - it.copy(flags = it.flags - flag) - } else { - it.copy(flags = it.flags + flag) - } + it.copy( + options = setter(it.options, enabled), + ) } } fun createBackup(context: Context, uri: Uri) { - val flags = state.value.flags.fold(initial = 0, operation = { a, b -> a or b }) - BackupCreateJob.startNow(context, uri, flags) + BackupCreateJob.startNow(context, uri, state.value.options) } @Immutable data class State( - val flags: PersistentSet = persistentSetOf( - BackupCreateFlags.BACKUP_CATEGORY, - BackupCreateFlags.BACKUP_CHAPTER, - BackupCreateFlags.BACKUP_TRACK, - BackupCreateFlags.BACKUP_HISTORY, + val options: BackupOptions = BackupOptions( + libraryEntries = true, + categories = true, + chapters = true, + tracking = true, + history = true, + appSettings = false, + sourceSettings = false, // SY --> - BackupCreateFlags.BACKUP_CUSTOM_INFO, - BackupCreateFlags.BACKUP_READ_MANGA, + customInfo = true, + readEntries = true, // SY <-- ), ) } - -private val BackupChoices = persistentMapOf( - BackupCreateFlags.BACKUP_CATEGORY to MR.strings.categories, - BackupCreateFlags.BACKUP_CHAPTER to MR.strings.chapters, - BackupCreateFlags.BACKUP_TRACK to MR.strings.track, - BackupCreateFlags.BACKUP_HISTORY to MR.strings.history, - BackupCreateFlags.BACKUP_APP_PREFS to MR.strings.app_settings, - BackupCreateFlags.BACKUP_SOURCE_PREFS to MR.strings.source_settings, - // SY --> - BackupCreateFlags.BACKUP_CUSTOM_INFO to SYMR.strings.custom_entry_info, - BackupCreateFlags.BACKUP_READ_MANGA to SYMR.strings.all_read_entries, - // SY <-- -) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateFlags.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateFlags.kt deleted file mode 100644 index 07e5158be..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateFlags.kt +++ /dev/null @@ -1,25 +0,0 @@ -package eu.kanade.tachiyomi.data.backup.create - -internal object BackupCreateFlags { - const val BACKUP_CATEGORY = 0x1 - const val BACKUP_CHAPTER = 0x2 - const val BACKUP_HISTORY = 0x4 - const val BACKUP_TRACK = 0x8 - const val BACKUP_APP_PREFS = 0x10 - const val BACKUP_SOURCE_PREFS = 0x20 - - // SY --> - const val BACKUP_CUSTOM_INFO = 0x40 - const val BACKUP_READ_MANGA = 0x80 - // SY <-- - - const val AutomaticDefaults = BACKUP_CATEGORY or - BACKUP_CHAPTER or - BACKUP_HISTORY or - BACKUP_TRACK or - BACKUP_APP_PREFS or - BACKUP_SOURCE_PREFS /* SY --> */ or - BACKUP_CUSTOM_INFO or - BACKUP_READ_MANGA - // SY <-- -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateJob.kt index c2f1e5ded..303e6d3db 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreateJob.kt @@ -47,10 +47,12 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete setForegroundSafely() - val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupCreateFlags.AutomaticDefaults) + val options = inputData.getBooleanArray(OPTIONS_KEY) + ?.let { BackupOptions.fromBooleanArray(it) } + ?: BackupOptions.AutomaticDefaults return try { - val location = BackupCreator(context, isAutoBackup).backup(uri, flags) + val location = BackupCreator(context, isAutoBackup).backup(uri, options) if (!isAutoBackup) { notifier.showBackupComplete(UniFile.fromUri(context, location.toUri())!!) } @@ -112,11 +114,11 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete } } - fun startNow(context: Context, uri: Uri, flags: Int) { + fun startNow(context: Context, uri: Uri, options: BackupOptions) { val inputData = workDataOf( IS_AUTO_BACKUP_KEY to false, LOCATION_URI_KEY to uri.toString(), - BACKUP_FLAGS_KEY to flags, + OPTIONS_KEY to options.toBooleanArray(), ) val request = OneTimeWorkRequestBuilder() .addTag(TAG_MANUAL) @@ -132,4 +134,4 @@ private const val TAG_MANUAL = "$TAG_AUTO:manual" private const val IS_AUTO_BACKUP_KEY = "is_auto_backup" // Boolean private const val LOCATION_URI_KEY = "location_uri" // String -private const val BACKUP_FLAGS_KEY = "backup_flags" // Int +private const val OPTIONS_KEY = "options" // BooleanArray diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt index e50a8b982..515e2c686 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt @@ -5,10 +5,6 @@ import android.net.Uri import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.data.backup.BackupFileValidator -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_APP_PREFS -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_CATEGORY -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_READ_MANGA -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_SOURCE_PREFS import eu.kanade.tachiyomi.data.backup.create.creators.CategoriesBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.MangaBackupCreator import eu.kanade.tachiyomi.data.backup.create.creators.PreferenceBackupCreator @@ -63,7 +59,7 @@ class BackupCreator( // SY <-- ) { - suspend fun backup(uri: Uri, flags: Int): String { + suspend fun backup(uri: Uri, options: BackupOptions): String { var file: UniFile? = null try { file = ( @@ -90,17 +86,17 @@ class BackupCreator( } val databaseManga = getFavorites.await() /* SY --> */ + - if (flags and BACKUP_READ_MANGA == BACKUP_READ_MANGA) { + if (options.readEntries) { handler.awaitList { mangasQueries.getReadMangaNotInLibrary(MangaMapper::mapManga) } } else { emptyList() } + getMergedManga.await() // SY <-- val backup = Backup( - backupManga = backupMangas(databaseManga, flags), - backupCategories = backupCategories(flags), + backupManga = backupMangas(databaseManga, options), + backupCategories = backupCategories(options), backupSources = backupSources(databaseManga), - backupPreferences = backupAppPreferences(flags), - backupSourcePreferences = backupSourcePreferences(flags), + backupPreferences = backupAppPreferences(options), + backupSourcePreferences = backupSourcePreferences(options), // SY --> backupSavedSearches = backupSavedSearches(), // SY <-- @@ -136,28 +132,28 @@ class BackupCreator( } } - private suspend fun backupCategories(options: Int): List { - if (options and BACKUP_CATEGORY != BACKUP_CATEGORY) return emptyList() + private suspend fun backupCategories(options: BackupOptions): List { + if (!options.categories) return emptyList() return categoriesBackupCreator.backupCategories() } - private suspend fun backupMangas(mangas: List, flags: Int): List { - return mangaBackupCreator.backupMangas(mangas, flags) + private suspend fun backupMangas(mangas: List, options: BackupOptions): List { + return mangaBackupCreator.backupMangas(mangas, options) } private fun backupSources(mangas: List): List { return sourcesBackupCreator.backupSources(mangas) } - private fun backupAppPreferences(flags: Int): List { - if (flags and BACKUP_APP_PREFS != BACKUP_APP_PREFS) return emptyList() + private fun backupAppPreferences(options: BackupOptions): List { + if (!options.appSettings) return emptyList() return preferenceBackupCreator.backupAppPreferences() } - private fun backupSourcePreferences(flags: Int): List { - if (flags and BACKUP_SOURCE_PREFS != BACKUP_SOURCE_PREFS) return emptyList() + private fun backupSourcePreferences(options: BackupOptions): List { + if (!options.sourceSettings) return emptyList() return preferenceBackupCreator.backupSourcePreferences() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt new file mode 100644 index 000000000..5b6011b56 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt @@ -0,0 +1,115 @@ +package eu.kanade.tachiyomi.data.backup.create + +import dev.icerock.moko.resources.StringResource +import kotlinx.collections.immutable.persistentListOf +import tachiyomi.i18n.MR +import tachiyomi.i18n.sy.SYMR + +data class BackupOptions( + val libraryEntries: Boolean = true, + val categories: Boolean = true, + val chapters: Boolean = true, + val tracking: Boolean = true, + val history: Boolean = true, + val appSettings: Boolean = true, + val sourceSettings: Boolean = true, + // SY --> + val customInfo: Boolean = true, + val readEntries: Boolean = true, + // SY <-- +) { + fun toBooleanArray() = booleanArrayOf( + libraryEntries, + categories, + chapters, + tracking, + history, + appSettings, + sourceSettings, + // SY --> + customInfo, + readEntries, + // SY <-- + ) + + companion object { + val AutomaticDefaults = BackupOptions( + libraryEntries = true, + categories = true, + chapters = true, + tracking = true, + history = true, + appSettings = true, + sourceSettings = true, + // SY --> + customInfo = true, + readEntries = true, + // SY <-- + ) + + fun fromBooleanArray(booleanArray: BooleanArray) = BackupOptions( + libraryEntries = booleanArray[0], + categories = booleanArray[1], + chapters = booleanArray[2], + tracking = booleanArray[3], + history = booleanArray[4], + appSettings = booleanArray[5], + sourceSettings = booleanArray[6], + // SY --> + customInfo = booleanArray[7], + readEntries = booleanArray[8], + // SY <-- + ) + + val entries = persistentListOf( + BackupOptionEntry( + label = MR.strings.categories, + getter = BackupOptions::categories, + setter = { options, enabled -> options.copy(categories = enabled) }, + ), + BackupOptionEntry( + label = MR.strings.chapters, + getter = BackupOptions::chapters, + setter = { options, enabled -> options.copy(chapters = enabled) }, + ), + BackupOptionEntry( + label = MR.strings.track, + getter = BackupOptions::tracking, + setter = { options, enabled -> options.copy(tracking = enabled) }, + ), + BackupOptionEntry( + label = MR.strings.history, + getter = BackupOptions::history, + setter = { options, enabled -> options.copy(history = enabled) }, + ), + BackupOptionEntry( + label = MR.strings.app_settings, + getter = BackupOptions::appSettings, + setter = { options, enabled -> options.copy(appSettings = enabled) }, + ), + BackupOptionEntry( + label = MR.strings.source_settings, + getter = BackupOptions::sourceSettings, + setter = { options, enabled -> options.copy(sourceSettings = enabled) }, + ), + // SY --> + BackupOptionEntry( + label = SYMR.strings.custom_entry_info, + getter = BackupOptions::customInfo, + setter = { options, enabled -> options.copy(customInfo = enabled) }, + ), + BackupOptionEntry( + label = SYMR.strings.all_read_entries, + getter = BackupOptions::readEntries, + setter = { options, enabled -> options.copy(readEntries = enabled) }, + ), + // SY <-- + ) + } +} + +data class BackupOptionEntry( + val label: StringResource, + val getter: (BackupOptions) -> Boolean, + val setter: (BackupOptions, Boolean) -> BackupOptions, +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt index 3bb700787..10d8d3f84 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.data.backup.create.creators -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags -import eu.kanade.tachiyomi.data.backup.create.BackupCreateFlags.BACKUP_CUSTOM_INFO +import eu.kanade.tachiyomi.data.backup.create.BackupOptions import eu.kanade.tachiyomi.data.backup.models.BackupChapter import eu.kanade.tachiyomi.data.backup.models.BackupFlatMetadata import eu.kanade.tachiyomi.data.backup.models.BackupHistory @@ -35,17 +34,17 @@ class MangaBackupCreator( // SY <-- ) { - suspend fun backupMangas(mangas: List, flags: Int): List { + suspend fun backupMangas(mangas: List, options: BackupOptions): List { return mangas.map { - backupManga(it, flags) + backupManga(it, options) } } - private suspend fun backupManga(manga: Manga, options: Int): BackupManga { + private suspend fun backupManga(manga: Manga, options: BackupOptions): BackupManga { // Entry for this manga val mangaObject = manga.toBackupManga( // SY --> - if (options and BACKUP_CUSTOM_INFO == BACKUP_CUSTOM_INFO) { + if (options.customInfo) { getCustomMangaInfo.get(manga.id) } else { null @@ -67,8 +66,7 @@ class MangaBackupCreator( } // SY <-- - // Check if user wants chapter information in backup - if (options and BackupCreateFlags.BACKUP_CHAPTER == BackupCreateFlags.BACKUP_CHAPTER) { + if (options.chapters) { // Backup all the chapters handler.awaitList { chaptersQueries.getChaptersByMangaId( @@ -81,8 +79,7 @@ class MangaBackupCreator( ?.let { mangaObject.chapters = it } } - // Check if user wants category information in backup - if (options and BackupCreateFlags.BACKUP_CATEGORY == BackupCreateFlags.BACKUP_CATEGORY) { + if (options.categories) { // Backup categories for this manga val categoriesForManga = getCategories.await(manga.id) if (categoriesForManga.isNotEmpty()) { @@ -90,16 +87,14 @@ class MangaBackupCreator( } } - // Check if user wants track information in backup - if (options and BackupCreateFlags.BACKUP_TRACK == BackupCreateFlags.BACKUP_TRACK) { + if (options.tracking) { val tracks = handler.awaitList { manga_syncQueries.getTracksByMangaId(manga.id, backupTrackMapper) } if (tracks.isNotEmpty()) { mangaObject.tracking = tracks } } - // Check if user wants history information in backup - if (options and BackupCreateFlags.BACKUP_HISTORY == BackupCreateFlags.BACKUP_HISTORY) { + if (options.history) { val historyByMangaId = getHistory.await(manga.id) if (historyByMangaId.isNotEmpty()) { val history = historyByMangaId.map { history -> diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/PreferenceBackupCreator.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/PreferenceBackupCreator.kt index c75612de9..304f909ad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/PreferenceBackupCreator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/PreferenceBackupCreator.kt @@ -40,7 +40,7 @@ class PreferenceBackupCreator( @Suppress("UNCHECKED_CAST") private fun Map.toBackupPreferences(): List { return this.filterKeys { - !Preference.isPrivate(it) && !Preference.isAppState(it) + !Preference.isAppState(it) && !Preference.isPrivate(it) } .mapNotNull { (key, value) -> when (value) {