diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt index de310627d..a68a0c951 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -4,6 +4,7 @@ import android.content.Context import com.hippo.unifile.UniFile import com.jakewharton.rxrelay.BehaviorRelay import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.download.model.Download @@ -16,6 +17,8 @@ import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.storage.DiskUtil import rx.Observable import timber.log.Timber +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy /** @@ -25,7 +28,10 @@ import uy.kohesive.injekt.injectLazy * * @param context the application context. */ -class DownloadManager(private val context: Context) { +class DownloadManager( + private val context: Context, + private val db: DatabaseHelper = Injekt.get() +) { private val sourceManager: SourceManager by injectLazy() private val preferences: PreferencesHelper by injectLazy() @@ -242,7 +248,7 @@ class DownloadManager(private val context: Context) { val filteredChapters = if (isCancelling) { chapters } else { - getChaptersToDelete(chapters) + getChaptersToDelete(chapters, manga) } launchIO { @@ -349,7 +355,7 @@ class DownloadManager(private val context: Context) { * @param manga the manga of the chapters. */ fun enqueueDeleteChapters(chapters: List, manga: Manga) { - pendingDeleter.addChapters(getChaptersToDelete(chapters), manga) + pendingDeleter.addChapters(getChaptersToDelete(chapters, manga), manga) } /** @@ -389,17 +395,28 @@ class DownloadManager(private val context: Context) { } } - fun renameMangaDir(oldTitle: String, newTitle: String, source: Long) { - val sourceDir = provider.findSourceDir(sourceManager.getOrStub(source)) ?: return - val mangaDir = sourceDir.findFile(DiskUtil.buildValidFilename(oldTitle), true) ?: return - mangaDir.renameTo(DiskUtil.buildValidFilename(newTitle)) - } + private fun getChaptersToDelete(chapters: List, manga: Manga): List { + // Retrieve the categories that are set to exclude from being deleted on read + val categoriesToExclude = preferences.removeExcludeCategories().get().map(String::toInt) + val categoriesForManga = + manga.let { it -> + db.getCategoriesForManga(it).executeAsBlocking() + .mapNotNull { it.id } + .takeUnless { it.isEmpty() } + } ?: listOf(0) - private fun getChaptersToDelete(chapters: List): List { - return if (!preferences.removeBookmarkedChapters()) { + return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) { + chapters.filterNot { it.read } + } else if (!preferences.removeBookmarkedChapters()) { chapters.filterNot { it.bookmark } } else { chapters } } + + fun renameMangaDir(oldTitle: String, newTitle: String, source: Long) { + val sourceDir = provider.findSourceDir(sourceManager.getOrStub(source)) ?: return + val mangaDir = sourceDir.findFile(DiskUtil.buildValidFilename(oldTitle), true) ?: return + mangaDir.renameTo(DiskUtil.buildValidFilename(newTitle)) + } } 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 bf8f127f1..917d03449 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -185,6 +185,7 @@ object PreferenceKeys { const val downloadNewCategories = "download_new_categories" const val downloadNewCategoriesExclude = "download_new_categories_exclude" + const val removeExcludeCategories = "remove_exclude_categories" const val libraryDisplayMode = "pref_display_mode_library" @@ -371,8 +372,6 @@ object PreferenceKeys { const val sortTagsForLibrary = "sort_tags_for_library" - const val dontDeleteFromCategories = "dont_delete_from_categories" - const val extensionRepos = "extension_repos" const val cropBordersContinuousVertical = "crop_borders_continues_vertical" 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 9e2c20936..ef5d9836d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -236,6 +236,8 @@ class PreferencesHelper(val context: Context) { fun removeBookmarkedChapters() = prefs.getBoolean(Keys.removeBookmarkedChapters, false) + fun removeExcludeCategories() = flowPrefs.getStringSet(Keys.removeExcludeCategories, emptySet()) + fun libraryUpdateInterval() = flowPrefs.getInt(Keys.libraryUpdateInterval, 24) fun libraryUpdateRestriction() = flowPrefs.getStringSet(Keys.libraryUpdateRestriction, setOf(UNMETERED_NETWORK)) @@ -492,8 +494,6 @@ class PreferencesHelper(val context: Context) { fun sortTagsForLibrary() = flowPrefs.getStringSet(Keys.sortTagsForLibrary, mutableSetOf()) - fun dontDeleteFromCategories() = flowPrefs.getStringSet(Keys.dontDeleteFromCategories, emptySet()) - fun extensionRepos() = flowPrefs.getStringSet(Keys.extensionRepos, emptySet()) fun cropBordersContinuousVertical() = flowPrefs.getBoolean(Keys.cropBordersContinuousVertical, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 40bc49a66..85a62ce08 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -9,7 +9,6 @@ import android.os.Bundle import android.os.Looper import android.view.Gravity import android.view.Menu -import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.view.ActionMode diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index 913061a3d..bef3724a7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -64,7 +64,6 @@ import exh.source.MERGED_SOURCE_ID import exh.source.getMainSource import exh.source.isEhBasedSource import exh.source.mangaDexSourceIds -import exh.util.shouldDeleteChapters import exh.util.trimOrNull import kotlinx.coroutines.Job import kotlinx.coroutines.NonCancellable @@ -972,7 +971,7 @@ class MangaPresenter( launchIO { db.updateChaptersProgress(chapters).executeAsBlocking() - if (preferences.removeAfterMarkedAsRead() /* SY --> */ && manga.shouldDeleteChapters(db, preferences) /* SY <-- */) { + if (preferences.removeAfterMarkedAsRead()) { deleteChapters(chapters.filter { it.read }) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index ca5d1ff31..64afceb05 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -51,7 +51,6 @@ import exh.source.getMainSource import exh.source.isEhBasedManga import exh.util.defaultReaderType import exh.util.mangaType -import exh.util.shouldDeleteChapters import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import rx.Observable @@ -500,11 +499,9 @@ class ReaderPresenter( val currentChapterPosition = chapterList.indexOf(currentChapter) val removeAfterReadSlots = preferences.removeAfterReadSlots() val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) + // Check if deleting option is enabled and chapter exists - // SY --> - val manga = manga - // SY <-- - if (removeAfterReadSlots != -1 && chapterToDelete != null /* SY --> */ && (manga == null || manga.shouldDeleteChapters(db, preferences)) /* SY <-- */) { + if (removeAfterReadSlots != -1 && chapterToDelete != null) { enqueueDeleteReadChapters(chapterToDelete) } } 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 01a16e1b1..7dda56c44 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 @@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes import eu.kanade.tachiyomi.util.preference.intListPreference +import eu.kanade.tachiyomi.util.preference.multiSelectListPreference import eu.kanade.tachiyomi.util.preference.onClick import eu.kanade.tachiyomi.util.preference.preference import eu.kanade.tachiyomi.util.preference.preferenceCategory @@ -44,6 +45,9 @@ class SettingsDownloadController : SettingsController() { override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { titleRes = R.string.pref_category_downloads + val dbCategories = db.getCategories().executeAsBlocking() + val categories = listOf(Category.createDefault(context)) + dbCategories + preference { key = Keys.downloadsDirectory titleRes = R.string.pref_download_directory @@ -113,43 +117,27 @@ class SettingsDownloadController : SettingsController() { titleRes = R.string.pref_remove_bookmarked_chapters defaultValue = false } - // SY --> - preference { - val dbCategories = db.getCategories().executeAsBlocking() - val categories = listOf(Category.createDefault(context)) + dbCategories + multiSelectListPreference { + key = Keys.removeExcludeCategories + titleRes = R.string.pref_remove_exclude_categories + entries = categories.map { it.name }.toTypedArray() + entryValues = categories.map { it.id.toString() }.toTypedArray() - key = Keys.dontDeleteFromCategories - titleRes = R.string.pref_dont_delete_from_categories - - onClick { - val ctrl = DontDeleteFromCategoriesDialog() - ctrl.targetController = this@SettingsDownloadController - ctrl.showDialog(router) - } - - preferences.dontDeleteFromCategories().asFlow() - .onEach { mutableSet -> - val selectedCategories = mutableSet + preferences.removeExcludeCategories().asFlow() + .onEach { mutable -> + val selected = mutable .mapNotNull { id -> categories.find { it.id == id.toInt() } } .sortedBy { it.order } - summary = context.getString( - R.string.pref_dont_delete_from_categories_summary, - if (selectedCategories.isEmpty()) { - context.getString(R.string.tapping_inverted_none) - } else { - selectedCategories.joinToString { it.name } - } - ) - } - .launchIn(viewScope) + summary = if (selected.isEmpty()) { + resources?.getString(R.string.none) + } else { + selected.joinToString { it.name } + } + }.launchIn(viewScope) } - // SY <-- } - val dbCategories = db.getCategories().executeAsBlocking() - val categories = listOf(Category.createDefault(context)) + dbCategories - preferenceCategory { titleRes = R.string.pref_category_auto_download @@ -321,47 +309,6 @@ class SettingsDownloadController : SettingsController() { .create() } } - - class DontDeleteFromCategoriesDialog : DialogController() { - - private val preferences: PreferencesHelper = Injekt.get() - private val db: DatabaseHelper = Injekt.get() - - override fun onCreateDialog(savedViewState: Bundle?): Dialog { - val dbCategories = db.getCategories().executeAsBlocking() - val categories = listOf(Category.createDefault(activity!!)) + dbCategories - - val items = categories.map { it.name }.toTypedArray() - val selection = categories - .mapNotNull { category -> - category.id in preferences.dontDeleteFromCategories().get().map { it.toInt() } - } - .toBooleanArray() - - return MaterialAlertDialogBuilder(activity!!) - .setTitle(R.string.categories) - .setMultiChoiceItems( - items, - selection - ) { _, which, selected -> - selection[which] = selected - } - .setPositiveButton(android.R.string.ok) { _, _ -> - val included = selection - .mapIndexed { index, selected -> - if (selected) { - categories[index].id.toString() - } else null - } - .filterNotNull() - .toSet() - - preferences.dontDeleteFromCategories().set(included) - } - .setNegativeButton(android.R.string.cancel, null) - .create() - } - } } private const val DOWNLOAD_DIR = 104 diff --git a/app/src/main/java/exh/util/MangaExtensions.kt b/app/src/main/java/exh/util/MangaExtensions.kt deleted file mode 100644 index 3e55a1ae7..000000000 --- a/app/src/main/java/exh/util/MangaExtensions.kt +++ /dev/null @@ -1,24 +0,0 @@ -package exh.util - -import eu.kanade.tachiyomi.data.database.DatabaseHelper -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.preference.PreferencesHelper - -fun Manga.shouldDeleteChapters(db: DatabaseHelper, prefs: PreferencesHelper): Boolean { - if (!favorite) return true - - val categoriesToNotDeleteFrom = prefs.dontDeleteFromCategories().get().map(String::toInt) - if (categoriesToNotDeleteFrom.isEmpty()) return true - - // Get all categories, else default category (0) - val categoriesForManga = - db.getCategoriesForManga(this).executeAsBlocking() - .mapNotNull { it.id } - .ifEmpty { listOf(0) } - - // We want to return false if there is intersects - // so we use isEmpty to return true if its empty - // and false if its not - // this hurt my brain - return categoriesForManga.intersect(categoriesToNotDeleteFrom).isEmpty() -} diff --git a/app/src/main/res/values-fr/strings_sy.xml b/app/src/main/res/values-fr/strings_sy.xml index c739be750..a14996c4f 100644 --- a/app/src/main/res/values-fr/strings_sy.xml +++ b/app/src/main/res/values-fr/strings_sy.xml @@ -190,8 +190,6 @@ Enregistrer les chapitres sous CBZ Niveau de compression CBZ - Catégories à exclure de la suppression - Si un manga appartient à l\'une de ces catégories, les chapitres ne seront pas supprimés lors du marquage comme lu et lors de la fin d\'un chapitre.\nCatégories:\n%1$s Temps de verrouillage biométrique diff --git a/app/src/main/res/values-pt-rBR/strings_sy.xml b/app/src/main/res/values-pt-rBR/strings_sy.xml index 1f544c1f8..6bf04e3ed 100644 --- a/app/src/main/res/values-pt-rBR/strings_sy.xml +++ b/app/src/main/res/values-pt-rBR/strings_sy.xml @@ -206,8 +206,6 @@ Salvar Capítulos como CBZ Nível de Compressão de CBZ - Categorias a remover da exclusão - Se um mangá está numa dessas categorias, os capítulos não serão excluídos ao terminar ou marcar como lido.\nCategorias:\n%1$s Tempos de bloqueio biométrico diff --git a/app/src/main/res/values-ru/strings_sy.xml b/app/src/main/res/values-ru/strings_sy.xml index d74bac43b..b2ef5ddcd 100644 --- a/app/src/main/res/values-ru/strings_sy.xml +++ b/app/src/main/res/values-ru/strings_sy.xml @@ -205,8 +205,6 @@ Сохранить главы как CBZ CBZ степень сжатия - Категории, исключаемые из удаления - Если манга относится к любой из этих категорий, главы не будут удалены при пометке как прочитанные и при завершении главы.\nКатегории:\n%1$s Время биометрической блокировки diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a80f5ee64..f42393a3d 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -382,6 +382,7 @@ After marked as read Automatically after reading Allow deleting bookmarked chapters + Categories to exclude in deleting Custom location Disabled Last read chapter diff --git a/app/src/main/res/values/strings_sy.xml b/app/src/main/res/values/strings_sy.xml index d36ebf21d..4a55b48ec 100644 --- a/app/src/main/res/values/strings_sy.xml +++ b/app/src/main/res/values/strings_sy.xml @@ -210,8 +210,6 @@ Save Chapters as CBZ CBZ Compression level - Categories to exclude from deletion - If a manga is in any of these categories, chapters will not be deleted when marking as read and when finishing a chapter.\nCategories:\n%1$s Biometric lock times