From 1d5fe4f775237f757b072a1d4561ee3f1d208070 Mon Sep 17 00:00:00 2001 From: Carlos <2092019+CarlosEsco@users.noreply.github.com> Date: Sat, 23 May 2020 19:27:21 -0400 Subject: [PATCH] Clean up the reader filter logic (#444) * move chapter filtering to its own class and injekt it. Clean up the logic around the filter to prevent unneeded filtering and to make it more understandable * switch to .not --- .../java/eu/kanade/tachiyomi/AppModule.kt | 3 + .../ui/reader/ReaderChapterFilter.kt | 66 ++++++++++++++++ .../tachiyomi/ui/reader/ReaderPresenter.kt | 77 +++++-------------- 3 files changed, 89 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderChapterFilter.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt index 652cf6e214..f1662d6066 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/AppModule.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.source.SourceManager +import eu.kanade.tachiyomi.ui.reader.ReaderChapterFilter import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import uy.kohesive.injekt.api.InjektModule @@ -48,6 +49,8 @@ class AppModule(val app: Application) : InjektModule { addSingletonFactory { Gson() } + addSingletonFactory { ReaderChapterFilter() } + // Asynchronously init expensive components for a faster cold start GlobalScope.launch { get() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderChapterFilter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderChapterFilter.kt new file mode 100644 index 0000000000..5f9b127c15 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderChapterFilter.kt @@ -0,0 +1,66 @@ +package eu.kanade.tachiyomi.ui.reader + +import eu.kanade.tachiyomi.data.database.models.Chapter +import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.download.DownloadManager +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +/** + * This class filters chapters for the reader based on the user enabled preferences and filters + */ +class ReaderChapterFilter( + private val downloadManager: DownloadManager = Injekt.get(), + private val preferences: PreferencesHelper = Injekt.get() +) { + + fun filterChapter( + dbChapters: List, + manga: Manga, + chapterId: Long, + selectedChapter: Chapter? + ): List { + + // if neither preference is enabled dont even filter + if (!preferences.skipRead() && !preferences.skipFiltered()) { + return dbChapters + } + + var filteredChapters = dbChapters + if (preferences.skipRead()) { + filteredChapters = filteredChapters.filter { !it.read } + // add the selected chapter to the list in case it was read and user clicked it + if (chapterId != -1L) { + val find = filteredChapters.find { it.id == chapterId } + if (find == null) { + val mutableList = filteredChapters.toMutableList() + selectedChapter?.let { mutableList.add(it) } + filteredChapters = mutableList.toList() + } + } + } + if (preferences.skipFiltered()) { + val readEnabled = manga.readFilter == Manga.SHOW_READ + val unreadEnabled = manga.readFilter == Manga.SHOW_UNREAD + val downloadEnabled = manga.downloadedFilter == Manga.SHOW_DOWNLOADED + val bookmarkEnabled = manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED + + // if none of the filters are enabled skip the filtering of them + if (readEnabled || unreadEnabled || downloadEnabled || bookmarkEnabled) { + + filteredChapters = filteredChapters.filter { + if (readEnabled && it.read.not() || + (unreadEnabled && it.read) || + (bookmarkEnabled && it.bookmark.not()) || + (downloadEnabled && downloadManager.isChapterDownloaded(it, manga).not()) + ) { + return@filter false + } + return@filter true + } + } + } + return filteredChapters + } +} 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 ab51de383f..712301aabf 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 @@ -27,7 +27,6 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.system.ImageUtil -import eu.kanade.tachiyomi.util.system.executeOnIO import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -52,7 +51,8 @@ class ReaderPresenter( private val sourceManager: SourceManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(), private val coverCache: CoverCache = Injekt.get(), - private val preferences: PreferencesHelper = Injekt.get() + private val preferences: PreferencesHelper = Injekt.get(), + private val readerChapterFilter: ReaderChapterFilter = Injekt.get() ) : BasePresenter() { /** @@ -97,38 +97,8 @@ class ReaderPresenter( val selectedChapter = dbChapters.find { it.id == chapterId } ?: error("Requested chapter of id $chapterId not found in chapter list") - val chaptersForReader = - if (preferences.skipRead() || preferences.skipFiltered()) { - val list = dbChapters - .filter { - if (preferences.skipRead() && it.read) { - return@filter false - } else if (preferences.skipFiltered()) { - if ( - (manga.readFilter == Manga.SHOW_READ && !it.read) || - (manga.readFilter == Manga.SHOW_UNREAD && it.read) || - ( - manga.downloadedFilter == Manga.SHOW_DOWNLOADED && - !downloadManager.isChapterDownloaded(it, manga) - ) || - (manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED && !it.bookmark) - ) { - return@filter false - } - } - - true - } - .toMutableList() - - val find = list.find { it.id == chapterId } - if (find == null) { - list.add(selectedChapter) - } - list - } else { - dbChapters - } + val chaptersForReader = readerChapterFilter + .filterChapter(dbChapters, manga, chapterId, selectedChapter) when (manga.sorting) { Manga.SORTING_SOURCE -> ChapterLoadBySource().get(chaptersForReader) @@ -212,33 +182,26 @@ class ReaderPresenter( suspend fun getChapters(): List { val manga = manga ?: return emptyList() chapterItems = withContext(Dispatchers.IO) { - val list = db.getChapters(manga).executeOnIO().filter { - if (preferences.skipFiltered()) { - if ((manga.readFilter == Manga.SHOW_READ && !it.read) || - (manga.readFilter == Manga.SHOW_UNREAD && it.read) || - (manga.downloadedFilter == Manga.SHOW_DOWNLOADED && - !downloadManager.isChapterDownloaded(it, manga)) || - (manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED && !it.bookmark)) { - return@filter false + val dbChapters = db.getChapters(manga).executeAsBlocking() + val list = readerChapterFilter + .filterChapter(dbChapters, manga, -1L, null) + .sortedBy { + when (manga.sorting) { + Manga.SORTING_NUMBER -> it.chapter_number + else -> it.source_order.toFloat() } - true - } else { - true + }.map { + ReaderChapterItem( + it, manga, it.id == getCurrentChapter()?.chapter?.id ?: chapterId + ) } - }.sortedBy { - when (manga.sorting) { - Manga.SORTING_NUMBER -> it.chapter_number - else -> it.source_order.toFloat() - } - }.map { - ReaderChapterItem( - it, manga, it.id == getCurrentChapter()?.chapter?.id ?: chapterId - ) - } - if (!manga.sortDescending(preferences.chaptersDescAsDefault().getOrDefault())) + if (!manga.sortDescending(preferences.chaptersDescAsDefault().getOrDefault())) { list.reversed() - else list + } else { + list + } } + return chapterItems }