From 0ca62a4accaf96ced8014daf7228e79a2e3817c1 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 4 Apr 2021 17:15:06 -0400 Subject: [PATCH] Allow excluding categories from auto-download Closes #1412 Supersedes #4121 --- .../data/preference/PreferenceKeys.kt | 1 + .../data/preference/PreferencesHelper.kt | 1 + .../ui/setting/SettingsDownloadController.kt | 76 ++++++++++++++----- .../kanade/tachiyomi/util/MangaExtensions.kt | 3 + 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index ecebf6bc91..9069ab6acc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -165,6 +165,7 @@ object PreferenceKeys { const val downloadNew = "download_new" const val downloadNewCategories = "download_new_categories" + const val downloadNewCategoriesExclude = "download_new_categories_exclude" const val libraryDisplayMode = "pref_display_mode_library" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 9d6c687804..7415f019c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -265,6 +265,7 @@ class PreferencesHelper(val context: Context) { fun downloadNew() = flowPrefs.getBoolean(Keys.downloadNew, false) fun downloadNewCategories() = flowPrefs.getStringSet(Keys.downloadNewCategories, emptySet()) + fun downloadNewCategoriesExclude() = flowPrefs.getStringSet(Keys.downloadNewCategoriesExclude, emptySet()) fun lang() = prefs.getString(Keys.lang, "") diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt index efec6479f7..d714133516 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt @@ -8,9 +8,9 @@ import android.os.Bundle import android.os.Environment import androidx.core.content.ContextCompat import androidx.core.net.toUri +import androidx.core.text.buildSpannedString import androidx.preference.PreferenceScreen import com.afollestad.materialdialogs.MaterialDialog -import com.afollestad.materialdialogs.list.listItemsMultiChoice import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.hippo.unifile.UniFile import eu.kanade.tachiyomi.R @@ -28,6 +28,8 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.toast +import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateCheckBox +import eu.kanade.tachiyomi.widget.materialdialogs.listItemsQuadStateMultiChoice import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import uy.kohesive.injekt.Injekt @@ -115,18 +117,37 @@ class SettingsDownloadController : SettingsController() { preferences.downloadNew().asImmediateFlow { isVisible = it } .launchIn(viewScope) - preferences.downloadNewCategories().asFlow() - .onEach { mutableSet -> - val selectedCategories = mutableSet - .mapNotNull { id -> categories.find { it.id == id.toInt() } } - .sortedBy { it.order } - - summary = if (selectedCategories.isEmpty()) { - resources?.getString(R.string.all) - } else { - selectedCategories.joinToString { it.name } - } + fun updateSummary() { + val selectedCategories = preferences.downloadNewCategories().get() + .mapNotNull { id -> categories.find { it.id == id.toInt() } } + .sortedBy { it.order } + val includedItemsText = if (selectedCategories.isEmpty()) { + context.getString(R.string.all) + } else { + selectedCategories.joinToString { it.name } } + + val excludedCategories = preferences.downloadNewCategoriesExclude().get() + .mapNotNull { id -> categories.find { it.id == id.toInt() } } + .sortedBy { it.order } + val excludedItemsText = if (excludedCategories.isEmpty()) { + context.getString(R.string.none) + } else { + excludedCategories.joinToString { it.name } + } + + summary = buildSpannedString { + append(context.getString(R.string.include, includedItemsText)) + appendLine() + append(context.getString(R.string.exclude, excludedItemsText)) + } + } + + preferences.downloadNewCategories().asFlow() + .onEach { updateSummary() } + .launchIn(viewScope) + preferences.downloadNewCategoriesExclude().asFlow() + .onEach { updateSummary() } .launchIn(viewScope) } } @@ -210,19 +231,34 @@ class SettingsDownloadController : SettingsController() { val items = categories.map { it.name } val preselected = categories - .filter { it.id.toString() in preferences.downloadNewCategories().get() } - .map { categories.indexOf(it) } + .map { + when (it.id.toString()) { + in preferences.downloadNewCategories().get() -> QuadStateCheckBox.State.CHECKED.ordinal + in preferences.downloadNewCategoriesExclude().get() -> QuadStateCheckBox.State.INVERSED.ordinal + else -> QuadStateCheckBox.State.UNCHECKED.ordinal + } + } .toIntArray() return MaterialDialog(activity!!) .title(R.string.pref_download_new_categories) - .listItemsMultiChoice( + .listItemsQuadStateMultiChoice( items = items, - initialSelection = preselected, - allowEmptySelection = true - ) { _, selections, _ -> - val newCategories = selections.map { categories[it] } - preferences.downloadNewCategories().set(newCategories.map { it.id.toString() }.toSet()) + initialSelected = preselected + ) { selections -> + val included = selections + .mapIndexed { index, value -> if (value == QuadStateCheckBox.State.CHECKED.ordinal) index else null } + .filterNotNull() + .map { categories[it].id.toString() } + .toSet() + val excluded = selections + .mapIndexed { index, value -> if (value == QuadStateCheckBox.State.INVERSED.ordinal) index else null } + .filterNotNull() + .map { categories[it].id.toString() } + .toSet() + + preferences.downloadNewCategories().set(included) + preferences.downloadNewCategoriesExclude().set(excluded) } .positiveButton(android.R.string.ok) .negativeButton(android.R.string.cancel) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt index d1d1f80875..f4952d1b06 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt @@ -68,5 +68,8 @@ fun Manga.shouldDownloadNewChapters(db: DatabaseHelper, prefs: PreferencesHelper .mapNotNull { it.id } .takeUnless { it.isEmpty() } ?: listOf(0) + val categoriesToExclude = prefs.downloadNewCategoriesExclude().get().map(String::toInt) + if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) return false + return categoriesForManga.intersect(categoriesToDownload).isNotEmpty() }