Allow exclusion on Delete After Read per category (#5857)
* Added the exclude category from delete after being read * Stopped it from adding a wildcard to the import * Placed the remove after read to the download manager (cherry picked from commit a051079c6a2719e5f7429b289281ea3b3138aace) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt # app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
This commit is contained in:
parent
035a1518ad
commit
d9d94ed321
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import eu.kanade.tachiyomi.R
|
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.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
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 eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +28,10 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
*
|
*
|
||||||
* @param context the application context.
|
* @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 sourceManager: SourceManager by injectLazy()
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
@ -242,7 +248,7 @@ class DownloadManager(private val context: Context) {
|
|||||||
val filteredChapters = if (isCancelling) {
|
val filteredChapters = if (isCancelling) {
|
||||||
chapters
|
chapters
|
||||||
} else {
|
} else {
|
||||||
getChaptersToDelete(chapters)
|
getChaptersToDelete(chapters, manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
launchIO {
|
launchIO {
|
||||||
@ -349,7 +355,7 @@ class DownloadManager(private val context: Context) {
|
|||||||
* @param manga the manga of the chapters.
|
* @param manga the manga of the chapters.
|
||||||
*/
|
*/
|
||||||
fun enqueueDeleteChapters(chapters: List<Chapter>, manga: Manga) {
|
fun enqueueDeleteChapters(chapters: List<Chapter>, 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) {
|
private fun getChaptersToDelete(chapters: List<Chapter>, manga: Manga): List<Chapter> {
|
||||||
val sourceDir = provider.findSourceDir(sourceManager.getOrStub(source)) ?: return
|
// Retrieve the categories that are set to exclude from being deleted on read
|
||||||
val mangaDir = sourceDir.findFile(DiskUtil.buildValidFilename(oldTitle), true) ?: return
|
val categoriesToExclude = preferences.removeExcludeCategories().get().map(String::toInt)
|
||||||
mangaDir.renameTo(DiskUtil.buildValidFilename(newTitle))
|
val categoriesForManga =
|
||||||
}
|
manga.let { it ->
|
||||||
|
db.getCategoriesForManga(it).executeAsBlocking()
|
||||||
|
.mapNotNull { it.id }
|
||||||
|
.takeUnless { it.isEmpty() }
|
||||||
|
} ?: listOf(0)
|
||||||
|
|
||||||
private fun getChaptersToDelete(chapters: List<Chapter>): List<Chapter> {
|
return if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) {
|
||||||
return if (!preferences.removeBookmarkedChapters()) {
|
chapters.filterNot { it.read }
|
||||||
|
} else if (!preferences.removeBookmarkedChapters()) {
|
||||||
chapters.filterNot { it.bookmark }
|
chapters.filterNot { it.bookmark }
|
||||||
} else {
|
} else {
|
||||||
chapters
|
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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,7 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val downloadNewCategories = "download_new_categories"
|
const val downloadNewCategories = "download_new_categories"
|
||||||
const val downloadNewCategoriesExclude = "download_new_categories_exclude"
|
const val downloadNewCategoriesExclude = "download_new_categories_exclude"
|
||||||
|
const val removeExcludeCategories = "remove_exclude_categories"
|
||||||
|
|
||||||
const val libraryDisplayMode = "pref_display_mode_library"
|
const val libraryDisplayMode = "pref_display_mode_library"
|
||||||
|
|
||||||
@ -371,8 +372,6 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
const val sortTagsForLibrary = "sort_tags_for_library"
|
const val sortTagsForLibrary = "sort_tags_for_library"
|
||||||
|
|
||||||
const val dontDeleteFromCategories = "dont_delete_from_categories"
|
|
||||||
|
|
||||||
const val extensionRepos = "extension_repos"
|
const val extensionRepos = "extension_repos"
|
||||||
|
|
||||||
const val cropBordersContinuousVertical = "crop_borders_continues_vertical"
|
const val cropBordersContinuousVertical = "crop_borders_continues_vertical"
|
||||||
|
@ -236,6 +236,8 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun removeBookmarkedChapters() = prefs.getBoolean(Keys.removeBookmarkedChapters, false)
|
fun removeBookmarkedChapters() = prefs.getBoolean(Keys.removeBookmarkedChapters, false)
|
||||||
|
|
||||||
|
fun removeExcludeCategories() = flowPrefs.getStringSet(Keys.removeExcludeCategories, emptySet())
|
||||||
|
|
||||||
fun libraryUpdateInterval() = flowPrefs.getInt(Keys.libraryUpdateInterval, 24)
|
fun libraryUpdateInterval() = flowPrefs.getInt(Keys.libraryUpdateInterval, 24)
|
||||||
|
|
||||||
fun libraryUpdateRestriction() = flowPrefs.getStringSet(Keys.libraryUpdateRestriction, setOf(UNMETERED_NETWORK))
|
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 sortTagsForLibrary() = flowPrefs.getStringSet(Keys.sortTagsForLibrary, mutableSetOf())
|
||||||
|
|
||||||
fun dontDeleteFromCategories() = flowPrefs.getStringSet(Keys.dontDeleteFromCategories, emptySet())
|
|
||||||
|
|
||||||
fun extensionRepos() = flowPrefs.getStringSet(Keys.extensionRepos, emptySet())
|
fun extensionRepos() = flowPrefs.getStringSet(Keys.extensionRepos, emptySet())
|
||||||
|
|
||||||
fun cropBordersContinuousVertical() = flowPrefs.getBoolean(Keys.cropBordersContinuousVertical, false)
|
fun cropBordersContinuousVertical() = flowPrefs.getBoolean(Keys.cropBordersContinuousVertical, false)
|
||||||
|
@ -9,7 +9,6 @@ import android.os.Bundle
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
|
@ -64,7 +64,6 @@ import exh.source.MERGED_SOURCE_ID
|
|||||||
import exh.source.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.source.isEhBasedSource
|
import exh.source.isEhBasedSource
|
||||||
import exh.source.mangaDexSourceIds
|
import exh.source.mangaDexSourceIds
|
||||||
import exh.util.shouldDeleteChapters
|
|
||||||
import exh.util.trimOrNull
|
import exh.util.trimOrNull
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.NonCancellable
|
import kotlinx.coroutines.NonCancellable
|
||||||
@ -972,7 +971,7 @@ class MangaPresenter(
|
|||||||
launchIO {
|
launchIO {
|
||||||
db.updateChaptersProgress(chapters).executeAsBlocking()
|
db.updateChaptersProgress(chapters).executeAsBlocking()
|
||||||
|
|
||||||
if (preferences.removeAfterMarkedAsRead() /* SY --> */ && manga.shouldDeleteChapters(db, preferences) /* SY <-- */) {
|
if (preferences.removeAfterMarkedAsRead()) {
|
||||||
deleteChapters(chapters.filter { it.read })
|
deleteChapters(chapters.filter { it.read })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,6 @@ import exh.source.getMainSource
|
|||||||
import exh.source.isEhBasedManga
|
import exh.source.isEhBasedManga
|
||||||
import exh.util.defaultReaderType
|
import exh.util.defaultReaderType
|
||||||
import exh.util.mangaType
|
import exh.util.mangaType
|
||||||
import exh.util.shouldDeleteChapters
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -500,11 +499,9 @@ class ReaderPresenter(
|
|||||||
val currentChapterPosition = chapterList.indexOf(currentChapter)
|
val currentChapterPosition = chapterList.indexOf(currentChapter)
|
||||||
val removeAfterReadSlots = preferences.removeAfterReadSlots()
|
val removeAfterReadSlots = preferences.removeAfterReadSlots()
|
||||||
val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots)
|
val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots)
|
||||||
|
|
||||||
// Check if deleting option is enabled and chapter exists
|
// Check if deleting option is enabled and chapter exists
|
||||||
// SY -->
|
if (removeAfterReadSlots != -1 && chapterToDelete != null) {
|
||||||
val manga = manga
|
|
||||||
// SY <--
|
|
||||||
if (removeAfterReadSlots != -1 && chapterToDelete != null /* SY --> */ && (manga == null || manga.shouldDeleteChapters(db, preferences)) /* SY <-- */) {
|
|
||||||
enqueueDeleteReadChapters(chapterToDelete)
|
enqueueDeleteReadChapters(chapterToDelete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.defaultValue
|
||||||
import eu.kanade.tachiyomi.util.preference.entriesRes
|
import eu.kanade.tachiyomi.util.preference.entriesRes
|
||||||
import eu.kanade.tachiyomi.util.preference.intListPreference
|
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.onClick
|
||||||
import eu.kanade.tachiyomi.util.preference.preference
|
import eu.kanade.tachiyomi.util.preference.preference
|
||||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||||
@ -44,6 +45,9 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
||||||
titleRes = R.string.pref_category_downloads
|
titleRes = R.string.pref_category_downloads
|
||||||
|
|
||||||
|
val dbCategories = db.getCategories().executeAsBlocking()
|
||||||
|
val categories = listOf(Category.createDefault(context)) + dbCategories
|
||||||
|
|
||||||
preference {
|
preference {
|
||||||
key = Keys.downloadsDirectory
|
key = Keys.downloadsDirectory
|
||||||
titleRes = R.string.pref_download_directory
|
titleRes = R.string.pref_download_directory
|
||||||
@ -113,43 +117,27 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
titleRes = R.string.pref_remove_bookmarked_chapters
|
titleRes = R.string.pref_remove_bookmarked_chapters
|
||||||
defaultValue = false
|
defaultValue = false
|
||||||
}
|
}
|
||||||
// SY -->
|
multiSelectListPreference {
|
||||||
preference {
|
key = Keys.removeExcludeCategories
|
||||||
val dbCategories = db.getCategories().executeAsBlocking()
|
titleRes = R.string.pref_remove_exclude_categories
|
||||||
val categories = listOf(Category.createDefault(context)) + dbCategories
|
entries = categories.map { it.name }.toTypedArray()
|
||||||
|
entryValues = categories.map { it.id.toString() }.toTypedArray()
|
||||||
|
|
||||||
key = Keys.dontDeleteFromCategories
|
preferences.removeExcludeCategories().asFlow()
|
||||||
titleRes = R.string.pref_dont_delete_from_categories
|
.onEach { mutable ->
|
||||||
|
val selected = mutable
|
||||||
onClick {
|
|
||||||
val ctrl = DontDeleteFromCategoriesDialog()
|
|
||||||
ctrl.targetController = this@SettingsDownloadController
|
|
||||||
ctrl.showDialog(router)
|
|
||||||
}
|
|
||||||
|
|
||||||
preferences.dontDeleteFromCategories().asFlow()
|
|
||||||
.onEach { mutableSet ->
|
|
||||||
val selectedCategories = mutableSet
|
|
||||||
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
.mapNotNull { id -> categories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
|
|
||||||
summary = context.getString(
|
summary = if (selected.isEmpty()) {
|
||||||
R.string.pref_dont_delete_from_categories_summary,
|
resources?.getString(R.string.none)
|
||||||
if (selectedCategories.isEmpty()) {
|
} else {
|
||||||
context.getString(R.string.tapping_inverted_none)
|
selected.joinToString { it.name }
|
||||||
} else {
|
}
|
||||||
selectedCategories.joinToString { it.name }
|
}.launchIn(viewScope)
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.launchIn(viewScope)
|
|
||||||
}
|
}
|
||||||
// SY <--
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val dbCategories = db.getCategories().executeAsBlocking()
|
|
||||||
val categories = listOf(Category.createDefault(context)) + dbCategories
|
|
||||||
|
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
titleRes = R.string.pref_category_auto_download
|
titleRes = R.string.pref_category_auto_download
|
||||||
|
|
||||||
@ -321,47 +309,6 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
.create()
|
.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
|
private const val DOWNLOAD_DIR = 104
|
||||||
|
@ -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()
|
|
||||||
}
|
|
@ -190,8 +190,6 @@
|
|||||||
<!-- Download settings -->
|
<!-- Download settings -->
|
||||||
<string name="save_chapter_as_cbz">Enregistrer les chapitres sous CBZ</string>
|
<string name="save_chapter_as_cbz">Enregistrer les chapitres sous CBZ</string>
|
||||||
<string name="save_chapter_as_cbz_level">Niveau de compression CBZ</string>
|
<string name="save_chapter_as_cbz_level">Niveau de compression CBZ</string>
|
||||||
<string name="pref_dont_delete_from_categories">Catégories à exclure de la suppression</string>
|
|
||||||
<string name="pref_dont_delete_from_categories_summary">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</string>
|
|
||||||
|
|
||||||
<!-- Security settings -->
|
<!-- Security settings -->
|
||||||
<string name="biometric_lock_times">Temps de verrouillage biométrique</string>
|
<string name="biometric_lock_times">Temps de verrouillage biométrique</string>
|
||||||
|
@ -206,8 +206,6 @@
|
|||||||
<!-- Download settings -->
|
<!-- Download settings -->
|
||||||
<string name="save_chapter_as_cbz">Salvar Capítulos como CBZ</string>
|
<string name="save_chapter_as_cbz">Salvar Capítulos como CBZ</string>
|
||||||
<string name="save_chapter_as_cbz_level">Nível de Compressão de CBZ</string>
|
<string name="save_chapter_as_cbz_level">Nível de Compressão de CBZ</string>
|
||||||
<string name="pref_dont_delete_from_categories">Categorias a remover da exclusão</string>
|
|
||||||
<string name="pref_dont_delete_from_categories_summary">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</string>
|
|
||||||
|
|
||||||
<!-- Security settings -->
|
<!-- Security settings -->
|
||||||
<string name="biometric_lock_times">Tempos de bloqueio biométrico</string>
|
<string name="biometric_lock_times">Tempos de bloqueio biométrico</string>
|
||||||
|
@ -205,8 +205,6 @@
|
|||||||
<!-- Download settings -->
|
<!-- Download settings -->
|
||||||
<string name="save_chapter_as_cbz">Сохранить главы как CBZ</string>
|
<string name="save_chapter_as_cbz">Сохранить главы как CBZ</string>
|
||||||
<string name="save_chapter_as_cbz_level">CBZ степень сжатия</string>
|
<string name="save_chapter_as_cbz_level">CBZ степень сжатия</string>
|
||||||
<string name="pref_dont_delete_from_categories">Категории, исключаемые из удаления</string>
|
|
||||||
<string name="pref_dont_delete_from_categories_summary">Если манга относится к любой из этих категорий, главы не будут удалены при пометке как прочитанные и при завершении главы.\nКатегории:\n%1$s</string>
|
|
||||||
|
|
||||||
<!-- Security settings -->
|
<!-- Security settings -->
|
||||||
<string name="biometric_lock_times">Время биометрической блокировки</string>
|
<string name="biometric_lock_times">Время биометрической блокировки</string>
|
||||||
|
@ -382,6 +382,7 @@
|
|||||||
<string name="pref_remove_after_marked_as_read">After marked as read</string>
|
<string name="pref_remove_after_marked_as_read">After marked as read</string>
|
||||||
<string name="pref_remove_after_read">Automatically after reading</string>
|
<string name="pref_remove_after_read">Automatically after reading</string>
|
||||||
<string name="pref_remove_bookmarked_chapters">Allow deleting bookmarked chapters</string>
|
<string name="pref_remove_bookmarked_chapters">Allow deleting bookmarked chapters</string>
|
||||||
|
<string name="pref_remove_exclude_categories">Categories to exclude in deleting</string>
|
||||||
<string name="custom_dir">Custom location</string>
|
<string name="custom_dir">Custom location</string>
|
||||||
<string name="disabled">Disabled</string>
|
<string name="disabled">Disabled</string>
|
||||||
<string name="last_read_chapter">Last read chapter</string>
|
<string name="last_read_chapter">Last read chapter</string>
|
||||||
|
@ -210,8 +210,6 @@
|
|||||||
<!-- Download settings -->
|
<!-- Download settings -->
|
||||||
<string name="save_chapter_as_cbz">Save Chapters as CBZ</string>
|
<string name="save_chapter_as_cbz">Save Chapters as CBZ</string>
|
||||||
<string name="save_chapter_as_cbz_level">CBZ Compression level</string>
|
<string name="save_chapter_as_cbz_level">CBZ Compression level</string>
|
||||||
<string name="pref_dont_delete_from_categories">Categories to exclude from deletion</string>
|
|
||||||
<string name="pref_dont_delete_from_categories_summary">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</string>
|
|
||||||
|
|
||||||
<!-- Security settings -->
|
<!-- Security settings -->
|
||||||
<string name="biometric_lock_times">Biometric lock times</string>
|
<string name="biometric_lock_times">Biometric lock times</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user