Simplify filter logic (#9141)

* Remove unnecessary else branch

* Add TriStateFilter applyFilter

* Simplify filterFnTracking filter logic
This commit is contained in:
Two-Ai 2023-02-25 11:46:40 -05:00 committed by GitHub
parent 86b9262a7e
commit ed6809fa28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 136 deletions

View file

@ -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
}
}
return filter { chapter -> applyFilter(unreadFilter) { !chapter.read } }
.filter { chapter -> applyFilter(bookmarkedFilter) { chapter.bookmark } }
.filter { chapter ->
when (bookmarkedFilter) {
TriStateFilter.DISABLED -> true
TriStateFilter.ENABLED_IS -> chapter.bookmark
TriStateFilter.ENABLED_NOT -> !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) }
}

View file

@ -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")
}
}

View file

@ -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) }

View file

@ -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) }
}
}

View file

@ -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()
}