diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt index 12cbc7b5c..e2f3cb59f 100644 --- a/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt +++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/SetReadStatus.kt @@ -1,6 +1,11 @@ package eu.kanade.domain.chapter.interactor import eu.kanade.domain.download.interactor.DeleteDownload +import eu.kanade.tachiyomi.data.library.LibraryUpdateJob +import eu.kanade.tachiyomi.ui.library.LibraryScreenModel +import eu.kanade.tachiyomi.ui.manga.MangaScreenModel +import eu.kanade.tachiyomi.ui.reader.ReaderViewModel +import eu.kanade.tachiyomi.ui.updates.UpdatesScreenModel import exh.source.MERGED_SOURCE_ID import logcat.LogPriority import tachiyomi.core.common.util.lang.withNonCancellableContext @@ -31,7 +36,26 @@ class SetReadStatus( ) } - suspend fun await(read: Boolean, vararg chapters: Chapter): Result = withNonCancellableContext { + /** + * Mark chapters as read/unread, also delete downloaded chapters if 'After manually marked as read' is set. + * + * Called from: + * - [LibraryScreenModel]: Manually select mangas & mark as read + * - [MangaScreenModel.markChaptersRead]: Manually select chapters & mark as read or swipe chapter as read + * - [UpdatesScreenModel.markUpdatesRead]: Manually select chapters & mark as read + * - [LibraryUpdateJob.updateChapterList]: when a manga is updated and has new chapter but already read, + * it will mark that new **duplicated** chapter as read & delete downloading/downloaded -> should be treat as + * automatically ~ no auto delete + * - [ReaderViewModel.updateChapterProgress]: mark **duplicated** chapter as read after finish reading -> should be + * treated as not manually mark as read so not auto-delete (there are cases where chapter number is mistaken by volume number) + */ + suspend fun await( + read: Boolean, + vararg chapters: Chapter, + // KMK --> + manually: Boolean = true, + // KMK <-- + ): Result = withNonCancellableContext { val chaptersToUpdate = chapters.filter { when (read) { true -> !it.read @@ -51,8 +75,17 @@ class SetReadStatus( return@withNonCancellableContext Result.InternalError(e) } - if (read && downloadPreferences.removeAfterMarkedAsRead().get()) { + if ( + // KMK --> + manually && + // KMK <-- + read && + downloadPreferences.removeAfterMarkedAsRead().get() + ) { chaptersToUpdate + // KMK --> + .map { it.copy(read = true) } // mark as read so it will respect category exclusion + // KMK <-- .groupBy { it.mangaId } .forEach { (mangaId, chapters) -> deleteDownload.awaitAll( 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 e2eee8414..bd12418f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -229,9 +229,23 @@ class DownloadManager( * @param manga the manga of the chapters. * @param source the source of the chapters. */ - fun deleteChapters(chapters: List, manga: Manga, source: Source) { + fun deleteChapters( + chapters: List, + manga: Manga, + source: Source, + // KMK --> + /** Ignore categories exclusion */ + ignoreCategoryExclusion: Boolean = false, + // KMK <-- + ) { launchIO { - val filteredChapters = getChaptersToDelete(chapters, manga) + val filteredChapters = getChaptersToDelete( + chapters, + manga, + // KMK --> + ignoreCategoryExclusion, + // KMK <-- + ) if (filteredChapters.isEmpty()) { return@launchIO } @@ -427,20 +441,38 @@ class DownloadManager( } } - private suspend fun getChaptersToDelete(chapters: List, manga: Manga): List { - // Retrieve the categories that are set to exclude from being deleted on read - val categoriesToExclude = downloadPreferences.removeExcludeCategories().get().map(String::toLong) - - val categoriesForManga = getCategories.await(manga.id) - .map { it.id } - .ifEmpty { listOf(0) } - val filteredCategoryManga = if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) { - chapters.filterNot { it.read } - } else { + private suspend fun getChaptersToDelete( + chapters: List, + manga: Manga, + // KMK --> + /** Ignore categories exclusion */ + ignoreCategoryExclusion: Boolean = false, + // KMK <-- + ): List { + // KMK --> + val filteredCategoryManga = if (ignoreCategoryExclusion) { chapters + } else { + // KMK <-- + // Retrieve the categories that are set to exclude from being deleted on read + val categoriesToExclude = downloadPreferences.removeExcludeCategories().get().map(String::toLong).toSet() + + val categoriesForManga = getCategories.await(manga.id) + .map { it.id } + .ifEmpty { listOf(0) } + if (categoriesForManga.intersect(categoriesToExclude).isNotEmpty()) { + chapters.filterNot { it.read } + } else { + chapters + } } - return if (!downloadPreferences.removeBookmarkedChapters().get()) { + return if (!downloadPreferences.removeBookmarkedChapters().get() && + // KMK --> + // if manually deleting single chapter then will allow deleting bookmark chapter + (chapters.size > 1 || !ignoreCategoryExclusion) + // KMK <-- + ) { filteredCategoryManga.filterNot { it.bookmark } } else { filteredCategoryManga diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index c9bcddf6e..9264eb214 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -438,7 +438,13 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet } if (newReadChapters.isNotEmpty()) { - setReadStatus.await(true, *newReadChapters.toTypedArray()) + setReadStatus.await( + true, + *newReadChapters.toTypedArray(), + // KMK --> + manually = false, + // KMK <-- + ) } this.filterNot { newReadChapters.contains(it) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 04b04bf13..dc290ff62 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -1418,6 +1418,9 @@ class MangaScreenModel( chapters, state.manga, state.source, + // KMK --> + ignoreCategoryExclusion = true, + // KMK <-- ) } } catch (e: Throwable) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index bee06d879..f7818d612 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -709,7 +709,13 @@ class ReaderViewModel @JvmOverloads constructor( } .ifEmpty { null } ?.also { - setReadStatus.await(true, *it.toTypedArray()) + setReadStatus.await( + true, + *it.toTypedArray(), + // KMK --> + manually = false, + // KMK <-- + ) it.forEach { chapter -> deleteChapterIfNeeded(ReaderChapter(chapter)) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt index ea03a19ea..22a2ef9bb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/updates/UpdatesScreenModel.kt @@ -265,7 +265,14 @@ class UpdatesScreenModel( val manga = getManga.await(mangaId) ?: return@forEach val source = sourceManager.get(manga.source) ?: return@forEach val chapters = updates.mapNotNull { getChapter.await(it.update.chapterId) } - downloadManager.deleteChapters(chapters, manga, source) + downloadManager.deleteChapters( + chapters, + manga, + source, + // KMK --> + ignoreCategoryExclusion = true, + // KMK <-- + ) } } toggleAllSelection(false)