Add filter for tracking (#4276)

* Add filter for tracking or not

* Use .any

* Access database only when needed

(cherry picked from commit 5cddc0c3875fffa205bd7fbc7f881cc60871b5be)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
This commit is contained in:
Andreas 2021-01-17 21:40:17 +01:00 committed by Jobobby04
parent 84a28ddb87
commit c92c9fada5
7 changed files with 62 additions and 26 deletions

View File

@ -10,6 +10,15 @@ import eu.kanade.tachiyomi.data.track.TrackService
interface TrackQueries : DbProvider { interface TrackQueries : DbProvider {
fun getTracks() = db.get()
.listOfObjects(Track::class.java)
.withQuery(
Query.builder()
.table(TrackTable.TABLE)
.build()
)
.prepare()
fun getTracks(manga: Manga) = db.get() fun getTracks(manga: Manga) = db.get()
.listOfObjects(Track::class.java) .listOfObjects(Track::class.java)
.withQuery( .withQuery(

View File

@ -123,9 +123,9 @@ object PreferenceKeys {
const val filterCompleted = "pref_filter_library_completed" const val filterCompleted = "pref_filter_library_completed"
const val filterStarted = "pref_filter_library_started" const val filterTracking = "pref_filter_library_tracking"
const val filterTracked = "pref_filter_library_tracked" const val filterStarted = "pref_filter_library_started"
const val filterLewd = "pref_filter_library_lewd" const val filterLewd = "pref_filter_library_lewd"

View File

@ -221,9 +221,9 @@ class PreferencesHelper(val context: Context) {
fun filterCompleted() = flowPrefs.getInt(Keys.filterCompleted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) fun filterCompleted() = flowPrefs.getInt(Keys.filterCompleted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterStarted() = flowPrefs.getInt(Keys.filterStarted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) fun filterTracking() = flowPrefs.getInt(Keys.filterTracking, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterTracked() = flowPrefs.getInt(Keys.filterTracked, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) fun filterStarted() = flowPrefs.getInt(Keys.filterStarted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value) fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.ui.category.CategoryAdapter import eu.kanade.tachiyomi.ui.category.CategoryAdapter
import eu.kanade.tachiyomi.util.lang.withUIContext
import exh.isMetadataSource import exh.isMetadataSource
import exh.metadata.sql.models.SearchTag import exh.metadata.sql.models.SearchTag
import exh.metadata.sql.models.SearchTitle import exh.metadata.sql.models.SearchTitle
@ -28,7 +29,6 @@ import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -96,7 +96,7 @@ class LibraryCategoryAdapter(view: LibraryCategoryView, val controller: LibraryC
preferences.filterCompleted().get() == Filter.TriState.STATE_IGNORE && preferences.filterCompleted().get() == Filter.TriState.STATE_IGNORE &&
preferences.filterStarted().get() == Filter.TriState.STATE_IGNORE && preferences.filterStarted().get() == Filter.TriState.STATE_IGNORE &&
preferences.filterUnread().get() == Filter.TriState.STATE_IGNORE && preferences.filterUnread().get() == Filter.TriState.STATE_IGNORE &&
preferences.filterTracked().get() == Filter.TriState.STATE_IGNORE && preferences.filterTracking().get() == Filter.TriState.STATE_IGNORE &&
preferences.filterLewd().get() == Filter.TriState.STATE_IGNORE preferences.filterLewd().get() == Filter.TriState.STATE_IGNORE
// EXH --> // EXH -->
@ -153,7 +153,7 @@ class LibraryCategoryAdapter(view: LibraryCategoryView, val controller: LibraryC
mangas mangas
} }
withContext(Dispatchers.Main) { withUIContext {
updateDataSet(newManga) updateDataSet(newManga)
} }
} }

View File

@ -63,9 +63,9 @@ class LibraryPresenter(
private val coverCache: CoverCache = Injekt.get(), private val coverCache: CoverCache = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val downloadManager: DownloadManager = Injekt.get(), private val downloadManager: DownloadManager = Injekt.get(),
private val trackManager: TrackManager = Injekt.get(),
// SY --> // SY -->
private val customMangaManager: CustomMangaManager = Injekt.get(), private val customMangaManager: CustomMangaManager = Injekt.get()
private val trackManager: TrackManager = Injekt.get()
// SY <-- // SY <--
) : BasePresenter<LibraryController>() { ) : BasePresenter<LibraryController>() {
@ -141,8 +141,8 @@ class LibraryPresenter(
lib.copy(mangaMap = map, categories = categories) lib.copy(mangaMap = map, categories = categories)
} }
// SY <-- // SY <--
.combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) { lib, _ -> .combineLatest(getFilterObservable()) { lib, tracks ->
lib.copy(mangaMap = applyFilters(lib.mangaMap)) lib.copy(mangaMap = applyFilters(lib.mangaMap, tracks))
} }
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ -> .combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { lib, _ ->
lib.copy(mangaMap = applySort(lib.mangaMap)) lib.copy(mangaMap = applySort(lib.mangaMap))
@ -159,14 +159,14 @@ class LibraryPresenter(
* *
* @param map the map to filter. * @param map the map to filter.
*/ */
private fun applyFilters(map: LibraryMap): LibraryMap { private fun applyFilters(map: LibraryMap, trackMap: Map<Long, Boolean>): LibraryMap {
val downloadedOnly = preferences.downloadedOnly().get() val downloadedOnly = preferences.downloadedOnly().get()
val filterDownloaded = preferences.filterDownloaded().get() val filterDownloaded = preferences.filterDownloaded().get()
val filterUnread = preferences.filterUnread().get() val filterUnread = preferences.filterUnread().get()
val filterCompleted = preferences.filterCompleted().get() val filterCompleted = preferences.filterCompleted().get()
val tracking = preferences.filterTracking().get()
// SY --> // SY -->
val filterStarted = preferences.filterStarted().get() val filterStarted = preferences.filterStarted().get()
val filterTracked = preferences.filterTracked().get()
val filterLewd = preferences.filterLewd().get() val filterLewd = preferences.filterLewd().get()
// SY <-- // SY <--
@ -198,6 +198,14 @@ class LibraryPresenter(
else !isDownloaded else !isDownloaded
} }
val filterFnTracking: (LibraryItem) -> Boolean = tracking@{ item ->
if (tracking == State.IGNORE.value) return@tracking true
val isTracking = trackMap[item.manga.id ?: -1] ?: false
return@tracking if (tracking == State.INCLUDE.value) isTracking else !isTracking
}
// SY --> // SY -->
val filterFnStarted: (LibraryItem) -> Boolean = started@{ item -> val filterFnStarted: (LibraryItem) -> Boolean = started@{ item ->
if (filterStarted == State.IGNORE.value) return@started true if (filterStarted == State.IGNORE.value) return@started true
@ -207,14 +215,6 @@ class LibraryPresenter(
else !hasRead else !hasRead
} }
val filterFnTracked: (LibraryItem) -> Boolean = tracked@{ item ->
if (filterTracked == State.IGNORE.value) return@tracked true
val hasTracks = db.getTracks(item.manga).executeAsBlocking().filterNot { it.sync_id == TrackManager.MDLIST && it.status == FollowStatus.UNFOLLOWED.int }.isNotEmpty()
return@tracked if (filterTracked == State.INCLUDE.value) hasTracks
else !hasTracks
}
val filterFnLewd: (LibraryItem) -> Boolean = lewd@{ item -> val filterFnLewd: (LibraryItem) -> Boolean = lewd@{ item ->
if (filterLewd == State.IGNORE.value) return@lewd true if (filterLewd == State.IGNORE.value) return@lewd true
val isLewd = item.manga.isLewd() val isLewd = item.manga.isLewd()
@ -229,9 +229,9 @@ class LibraryPresenter(
!filterFnUnread(item) || !filterFnUnread(item) ||
!filterFnCompleted(item) || !filterFnCompleted(item) ||
!filterFnDownloaded(item) || !filterFnDownloaded(item) ||
!filterFnTracking(item) ||
// SY --> // SY -->
!filterFnStarted(item) || !filterFnStarted(item) ||
!filterFnTracked(item) ||
!filterFnLewd(item) !filterFnLewd(item)
// SY <-- // SY <--
) )
@ -432,6 +432,29 @@ class LibraryPresenter(
} }
} }
/**
* Get the tracked manga from the database and checks if the filter gets changed
*
* @return an observable of tracked manga.
*/
private fun getFilterObservable(): Observable<Map<Long, Boolean>> {
return getTracksObservable().combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) { tracks, _ -> tracks }
}
/**
* Get the tracked manga from the database
*
* @return an observable of tracked manga.
*/
private fun getTracksObservable(): Observable<Map<Long, Boolean>> {
return db.getTracks().asRxObservable().map { tracks ->
tracks.associate { track ->
val isLogged = tracks.any { trackManager.getService(it.sync_id)?.isLogged ?: false }
Pair(track.manga_id, isLogged)
}
}.observeOn(Schedulers.io())
}
/** /**
* Requests the library to be filtered. * Requests the library to be filtered.
*/ */

View File

@ -82,16 +82,19 @@ class LibrarySettingsSheet(
private val downloaded = Item.TriStateGroup(R.string.action_filter_downloaded, this) private val downloaded = Item.TriStateGroup(R.string.action_filter_downloaded, this)
private val unread = Item.TriStateGroup(R.string.action_filter_unread, this) private val unread = Item.TriStateGroup(R.string.action_filter_unread, this)
private val completed = Item.TriStateGroup(R.string.completed, this) private val completed = Item.TriStateGroup(R.string.completed, this)
private val tracking = Item.TriStateGroup(R.string.action_filter_tracking, this)
// SY -->
private val started = Item.TriStateGroup(R.string.started, this) private val started = Item.TriStateGroup(R.string.started, this)
private val tracked = Item.TriStateGroup(R.string.tracked, this)
private val lewd = Item.TriStateGroup(R.string.lewd, this) private val lewd = Item.TriStateGroup(R.string.lewd, this)
// SY <--
override val header = null override val header = null
// SY --> // SY -->
override val items = ( override val items = (
if (Injekt.get<TrackManager>().hasLoggedServices()) { if (Injekt.get<TrackManager>().hasLoggedServices()) {
listOf(downloaded, unread, completed, started, tracked, lewd) listOf(downloaded, unread, completed, tracking, started, lewd)
} else { } else {
listOf(downloaded, unread, completed, started, lewd) listOf(downloaded, unread, completed, started, lewd)
} }
@ -109,9 +112,9 @@ class LibrarySettingsSheet(
} }
unread.state = preferences.filterUnread().get() unread.state = preferences.filterUnread().get()
completed.state = preferences.filterCompleted().get() completed.state = preferences.filterCompleted().get()
tracking.state = preferences.filterTracking().get()
// SY --> // SY -->
started.state = preferences.filterStarted().get() started.state = preferences.filterStarted().get()
tracked.state = preferences.filterTracked().get()
lewd.state = preferences.filterLewd().get() lewd.state = preferences.filterLewd().get()
// SY <-- // SY <--
} }
@ -129,9 +132,9 @@ class LibrarySettingsSheet(
downloaded -> preferences.filterDownloaded().set(newState) downloaded -> preferences.filterDownloaded().set(newState)
unread -> preferences.filterUnread().set(newState) unread -> preferences.filterUnread().set(newState)
completed -> preferences.filterCompleted().set(newState) completed -> preferences.filterCompleted().set(newState)
tracking -> preferences.filterTracking().set(newState)
// SY --> // SY -->
started -> preferences.filterStarted().set(newState) started -> preferences.filterStarted().set(newState)
tracked -> preferences.filterTracked().set(newState)
lewd -> preferences.filterLewd().set(newState) lewd -> preferences.filterLewd().set(newState)
// SY <-- // SY <--
} }

View File

@ -34,6 +34,7 @@
<string name="action_filter">Filter</string> <string name="action_filter">Filter</string>
<string name="action_filter_downloaded">Downloaded</string> <string name="action_filter_downloaded">Downloaded</string>
<string name="action_filter_bookmarked">Bookmarked</string> <string name="action_filter_bookmarked">Bookmarked</string>
<string name="action_filter_tracking">Tracking</string>
<string name="action_filter_unread">Unread</string> <string name="action_filter_unread">Unread</string>
<string name="action_filter_empty">Remove filter</string> <string name="action_filter_empty">Remove filter</string>
<string name="action_sort_alpha">Alphabetically</string> <string name="action_sort_alpha">Alphabetically</string>