Browse Source

Simplify filter logic (#9141)

* Remove unnecessary else branch

* Add TriStateFilter applyFilter

* Simplify filterFnTracking filter logic
Two-Ai 2 years ago
parent
commit
ed6809fa28

+ 9 - 46
app/src/main/java/eu/kanade/domain/chapter/model/ChapterFilter.kt

@@ -3,12 +3,11 @@ package eu.kanade.domain.chapter.model
 import eu.kanade.domain.manga.model.downloadedFilter
 import eu.kanade.domain.manga.model.isLocal
 import eu.kanade.tachiyomi.data.download.DownloadManager
-import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.ui.manga.ChapterItem
 import tachiyomi.domain.chapter.model.Chapter
 import tachiyomi.domain.chapter.service.getChapterSort
 import tachiyomi.domain.manga.model.Manga
-import tachiyomi.domain.manga.model.TriStateFilter
+import tachiyomi.domain.manga.model.applyFilter
 
 /**
  * Applies the view filters to the list of chapters obtained from the database.
@@ -20,30 +19,12 @@ fun List<Chapter>.applyFilters(manga: Manga, downloadManager: DownloadManager):
     val downloadedFilter = manga.downloadedFilter
     val bookmarkedFilter = manga.bookmarkedFilter
 
-    return filter { chapter ->
-        when (unreadFilter) {
-            TriStateFilter.DISABLED -> true
-            TriStateFilter.ENABLED_IS -> !chapter.read
-            TriStateFilter.ENABLED_NOT -> chapter.read
-        }
-    }
-        .filter { chapter ->
-            when (bookmarkedFilter) {
-                TriStateFilter.DISABLED -> true
-                TriStateFilter.ENABLED_IS -> chapter.bookmark
-                TriStateFilter.ENABLED_NOT -> !chapter.bookmark
-            }
-        }
+    return filter { chapter -> applyFilter(unreadFilter) { !chapter.read } }
+        .filter { chapter -> applyFilter(bookmarkedFilter) { chapter.bookmark } }
         .filter { chapter ->
-            val downloaded = downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)
-            val downloadState = when {
-                downloaded -> Download.State.DOWNLOADED
-                else -> Download.State.NOT_DOWNLOADED
-            }
-            when (downloadedFilter) {
-                TriStateFilter.DISABLED -> true
-                TriStateFilter.ENABLED_IS -> downloadState == Download.State.DOWNLOADED || isLocalManga
-                TriStateFilter.ENABLED_NOT -> downloadState != Download.State.DOWNLOADED && !isLocalManga
+            applyFilter(downloadedFilter) {
+                val downloaded = downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)
+                downloaded || isLocalManga
             }
         }
         .sortedWith(getChapterSort(manga))
@@ -59,26 +40,8 @@ fun List<ChapterItem>.applyFilters(manga: Manga): Sequence<ChapterItem> {
     val downloadedFilter = manga.downloadedFilter
     val bookmarkedFilter = manga.bookmarkedFilter
     return asSequence()
-        .filter { (chapter) ->
-            when (unreadFilter) {
-                TriStateFilter.DISABLED -> true
-                TriStateFilter.ENABLED_IS -> !chapter.read
-                TriStateFilter.ENABLED_NOT -> chapter.read
-            }
-        }
-        .filter { (chapter) ->
-            when (bookmarkedFilter) {
-                TriStateFilter.DISABLED -> true
-                TriStateFilter.ENABLED_IS -> chapter.bookmark
-                TriStateFilter.ENABLED_NOT -> !chapter.bookmark
-            }
-        }
-        .filter {
-            when (downloadedFilter) {
-                TriStateFilter.DISABLED -> true
-                TriStateFilter.ENABLED_IS -> it.isDownloaded || isLocalManga
-                TriStateFilter.ENABLED_NOT -> !it.isDownloaded && !isLocalManga
-            }
-        }
+        .filter { (chapter) -> applyFilter(unreadFilter) { !chapter.read } }
+        .filter { (chapter) -> applyFilter(bookmarkedFilter) { chapter.bookmark } }
+        .filter { applyFilter(downloadedFilter) { it.isDownloaded || isLocalManga } }
         .sortedWith { (chapter1), (chapter2) -> getChapterSort(manga).invoke(chapter1, chapter2) }
 }

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceFilterDialog.kt

@@ -177,6 +177,5 @@ private fun TriStateFilter.toTriStateInt(): Int {
         TriStateFilter.DISABLED -> Filter.TriState.STATE_IGNORE
         TriStateFilter.ENABLED_IS -> Filter.TriState.STATE_INCLUDE
         TriStateFilter.ENABLED_NOT -> Filter.TriState.STATE_EXCLUDE
-        else -> throw IllegalStateException("Unknown TriStateFilter state: $this")
     }
 }

+ 26 - 68
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt

@@ -59,6 +59,7 @@ import tachiyomi.domain.manga.interactor.GetLibraryManga
 import tachiyomi.domain.manga.model.Manga
 import tachiyomi.domain.manga.model.MangaUpdate
 import tachiyomi.domain.manga.model.TriStateFilter
+import tachiyomi.domain.manga.model.applyFilter
 import tachiyomi.domain.track.interactor.GetTracksPerManga
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
@@ -171,7 +172,8 @@ class LibraryScreenModel(
     ): LibraryMap {
         val prefs = getLibraryItemPreferencesFlow().first()
         val downloadedOnly = prefs.globalFilterDownloaded
-        val filterDownloaded = prefs.filterDownloaded
+        val filterDownloaded =
+            if (downloadedOnly) TriStateFilter.ENABLED_IS else prefs.filterDownloaded
         val filterUnread = prefs.filterUnread
         val filterStarted = prefs.filterStarted
         val filterBookmarked = prefs.filterBookmarked
@@ -183,61 +185,28 @@ class LibraryScreenModel(
         val includedTracks = loggedInTrackServices.mapNotNull { if (it.value == TriStateFilter.ENABLED_IS) it.key else null }
         val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
 
-        val filterFnDownloaded: (LibraryItem) -> Boolean = downloaded@{
-            if (!downloadedOnly && filterDownloaded == TriStateFilter.DISABLED) return@downloaded true
-
-            val isDownloaded = it.libraryManga.manga.isLocal() ||
-                it.downloadCount > 0 ||
-                downloadManager.getDownloadCount(it.libraryManga.manga) > 0
-            return@downloaded if (downloadedOnly || filterDownloaded == TriStateFilter.ENABLED_IS) {
-                isDownloaded
-            } else {
-                !isDownloaded
+        val filterFnDownloaded: (LibraryItem) -> Boolean = {
+            applyFilter(filterDownloaded) {
+                it.libraryManga.manga.isLocal() ||
+                    it.downloadCount > 0 ||
+                    downloadManager.getDownloadCount(it.libraryManga.manga) > 0
             }
         }
 
-        val filterFnUnread: (LibraryItem) -> Boolean = unread@{
-            if (filterUnread == TriStateFilter.DISABLED) return@unread true
-
-            val isUnread = it.libraryManga.unreadCount > 0
-            return@unread if (filterUnread == TriStateFilter.ENABLED_IS) {
-                isUnread
-            } else {
-                !isUnread
-            }
+        val filterFnUnread: (LibraryItem) -> Boolean = {
+            applyFilter(filterUnread) { it.libraryManga.unreadCount > 0 }
         }
 
-        val filterFnStarted: (LibraryItem) -> Boolean = started@{
-            if (filterStarted == TriStateFilter.DISABLED) return@started true
-
-            val hasStarted = it.libraryManga.hasStarted
-            return@started if (filterStarted == TriStateFilter.ENABLED_IS) {
-                hasStarted
-            } else {
-                !hasStarted
-            }
+        val filterFnStarted: (LibraryItem) -> Boolean = {
+            applyFilter(filterStarted) { it.libraryManga.hasStarted }
         }
 
-        val filterFnBookmarked: (LibraryItem) -> Boolean = bookmarked@{
-            if (filterBookmarked == TriStateFilter.DISABLED) return@bookmarked true
-
-            val hasBookmarks = it.libraryManga.hasBookmarks
-            return@bookmarked if (filterBookmarked == TriStateFilter.ENABLED_IS) {
-                hasBookmarks
-            } else {
-                !hasBookmarks
-            }
+        val filterFnBookmarked: (LibraryItem) -> Boolean = {
+            applyFilter(filterBookmarked) { it.libraryManga.hasBookmarks }
         }
 
-        val filterFnCompleted: (LibraryItem) -> Boolean = completed@{
-            if (filterCompleted == TriStateFilter.DISABLED) return@completed true
-
-            val isCompleted = it.libraryManga.manga.status.toInt() == SManga.COMPLETED
-            return@completed if (filterCompleted == TriStateFilter.ENABLED_IS) {
-                isCompleted
-            } else {
-                !isCompleted
-            }
+        val filterFnCompleted: (LibraryItem) -> Boolean = {
+            applyFilter(filterCompleted) { it.libraryManga.manga.status.toInt() == SManga.COMPLETED }
         }
 
         val filterFnTracking: (LibraryItem) -> Boolean = tracking@{ item ->
@@ -245,30 +214,19 @@ class LibraryScreenModel(
 
             val mangaTracks = trackMap[item.libraryManga.id].orEmpty()
 
-            val exclude = mangaTracks.fastFilter { it in excludedTracks }
-            val include = mangaTracks.fastFilter { it in includedTracks }
+            val isExcluded = excludedTracks.isNotEmpty() && mangaTracks.fastAny { it in excludedTracks }
+            val isIncluded = includedTracks.isEmpty() || mangaTracks.fastAny { it in includedTracks }
 
-            // TODO: Simplify the filter logic
-            if (includedTracks.isNotEmpty() && excludedTracks.isNotEmpty()) {
-                return@tracking if (exclude.isNotEmpty()) false else include.isNotEmpty()
-            }
-
-            if (excludedTracks.isNotEmpty()) return@tracking exclude.isEmpty()
-
-            if (includedTracks.isNotEmpty()) return@tracking include.isNotEmpty()
-
-            return@tracking false
+            return@tracking !isExcluded && isIncluded
         }
 
-        val filterFn: (LibraryItem) -> Boolean = filter@{
-            return@filter !(
-                !filterFnDownloaded(it) ||
-                    !filterFnUnread(it) ||
-                    !filterFnStarted(it) ||
-                    !filterFnBookmarked(it) ||
-                    !filterFnCompleted(it) ||
-                    !filterFnTracking(it)
-                )
+        val filterFn: (LibraryItem) -> Boolean = {
+            filterFnDownloaded(it) &&
+                filterFnUnread(it) &&
+                filterFnStarted(it) &&
+                filterFnBookmarked(it) &&
+                filterFnCompleted(it) &&
+                filterFnTracking(it)
         }
 
         return this.mapValues { entry -> entry.value.fastFilter(filterFn) }

+ 4 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt

@@ -70,6 +70,7 @@ import tachiyomi.domain.manga.interactor.GetMangaWithChapters
 import tachiyomi.domain.manga.interactor.SetMangaChapterFlags
 import tachiyomi.domain.manga.model.Manga
 import tachiyomi.domain.manga.model.TriStateFilter
+import tachiyomi.domain.manga.model.applyFilter
 import tachiyomi.domain.track.interactor.GetTracks
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
@@ -999,27 +1000,9 @@ sealed class MangaScreenState {
             val downloadedFilter = manga.downloadedFilter
             val bookmarkedFilter = manga.bookmarkedFilter
             return asSequence()
-                .filter { (chapter) ->
-                    when (unreadFilter) {
-                        TriStateFilter.DISABLED -> true
-                        TriStateFilter.ENABLED_IS -> !chapter.read
-                        TriStateFilter.ENABLED_NOT -> chapter.read
-                    }
-                }
-                .filter { (chapter) ->
-                    when (bookmarkedFilter) {
-                        TriStateFilter.DISABLED -> true
-                        TriStateFilter.ENABLED_IS -> chapter.bookmark
-                        TriStateFilter.ENABLED_NOT -> !chapter.bookmark
-                    }
-                }
-                .filter {
-                    when (downloadedFilter) {
-                        TriStateFilter.DISABLED -> true
-                        TriStateFilter.ENABLED_IS -> it.isDownloaded || isLocalManga
-                        TriStateFilter.ENABLED_NOT -> !it.isDownloaded && !isLocalManga
-                    }
-                }
+                .filter { (chapter) -> applyFilter(unreadFilter) { !chapter.read } }
+                .filter { (chapter) -> applyFilter(bookmarkedFilter) { chapter.bookmark } }
+                .filter { applyFilter(downloadedFilter) { it.isDownloaded || isLocalManga } }
                 .sortedWith { (chapter1), (chapter2) -> getChapterSort(manga).invoke(chapter1, chapter2) }
         }
     }

+ 6 - 0
domain/src/main/java/tachiyomi/domain/manga/model/TriStateFilter.kt

@@ -14,3 +14,9 @@ enum class TriStateFilter {
         }
     }
 }
+
+inline fun applyFilter(filter: TriStateFilter, predicate: () -> Boolean): Boolean = when (filter) {
+    TriStateFilter.DISABLED -> true
+    TriStateFilter.ENABLED_IS -> predicate()
+    TriStateFilter.ENABLED_NOT -> !predicate()
+}