Library sort change doesn't trigger filtering

This commit is contained in:
len 2016-12-15 18:51:12 +01:00
parent 816cc17ed3
commit 36bbb906c1
5 changed files with 64 additions and 54 deletions

View File

@ -275,7 +275,7 @@ class LibraryFragment : BaseRxFragment<LibraryPresenter>(), ActionMode.Callback
* Called when a filter is changed. * Called when a filter is changed.
*/ */
private fun onFilterChanged() { private fun onFilterChanged() {
presenter.requestLibraryUpdate() presenter.requestFilterUpdate()
activity.supportInvalidateOptionsMenu() activity.supportInvalidateOptionsMenu()
} }
@ -283,7 +283,7 @@ class LibraryFragment : BaseRxFragment<LibraryPresenter>(), ActionMode.Callback
* Called when the sorting mode is changed. * Called when the sorting mode is changed.
*/ */
private fun onSortChanged() { private fun onSortChanged() {
presenter.requestLibraryUpdate() presenter.requestSortUpdate()
} }
/** /**

View File

@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.combineLatest
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
@ -83,12 +84,12 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
/** /**
* Relay used to apply the UI filters to the last emission of the library. * Relay used to apply the UI filters to the last emission of the library.
*/ */
private val updateTriggerRelay = BehaviorRelay.create(Unit) private val filterTriggerRelay = BehaviorRelay.create(Unit)
/** /**
* Value that contains library sorted by last read * Relay used to apply the selected sorting method to the last emission of the library.
*/ */
private lateinit var lastReadManga: Map<Long, Int> private val sortTriggerRelay = BehaviorRelay.create(Unit)
/** /**
* Library subscription. * Library subscription.
@ -105,16 +106,23 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
*/ */
fun subscribeLibrary() { fun subscribeLibrary() {
if (librarySubscription.isNullOrUnsubscribed()) { if (librarySubscription.isNullOrUnsubscribed()) {
librarySubscription = Observable.combineLatest(getLibraryObservable(), librarySubscription = getLibraryObservable()
updateTriggerRelay.observeOn(Schedulers.io()), .combineLatest(filterTriggerRelay.observeOn(Schedulers.io()),
{ library, updateTrigger -> library }) { lib, tick -> Pair(lib.first, applyFilters(lib.second)) })
.map { Pair(it.first, applyFilters(it.second)) } .combineLatest(sortTriggerRelay.observeOn(Schedulers.io()),
{ lib, tick -> Pair(lib.first, applySort(lib.second)) })
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache( .subscribeLatestCache({ view, pair ->
{ view, pair -> view.onNextLibraryUpdate(pair.first, pair.second) }) view.onNextLibraryUpdate(pair.first, pair.second)
})
} }
} }
/**
* Applies library filters to the given map of manga.
*
* @param map the map to filter.
*/
private fun applyFilters(map: Map<Int, List<Manga>>): Map<Int, List<Manga>> { private fun applyFilters(map: Map<Int, List<Manga>>): Map<Int, List<Manga>> {
// Cached list of downloaded manga directories given a source id. // Cached list of downloaded manga directories given a source id.
val mangaDirectories = mutableMapOf<Int, Array<UniFile>>() val mangaDirectories = mutableMapOf<Int, Array<UniFile>>()
@ -126,7 +134,7 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
val filterUnread = preferences.filterUnread().getOrDefault() val filterUnread = preferences.filterUnread().getOrDefault()
val filterFn: (Manga) -> Boolean = f@ { manga: Manga -> val filterFn: (Manga) -> Boolean = f@ { manga ->
// Filter out manga without source. // Filter out manga without source.
val source = sourceManager.get(manga.source) ?: return@f false val source = sourceManager.get(manga.source) ?: return@f false
@ -154,24 +162,46 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
true true
} }
// Sorting return map.mapValues { entry -> entry.value.filter(filterFn) }
}
/**
* Applies library sorting to the given map of manga.
*
* @param map the map to sort.
*/
private fun applySort(map: Map<Int, List<Manga>>): Map<Int, List<Manga>> {
val sortingMode = preferences.librarySortingMode().getOrDefault() val sortingMode = preferences.librarySortingMode().getOrDefault()
// TODO lazy initialization in kotlin 1.1
var lastReadManga: Map<Long, Int>? = null
if (sortingMode == LibrarySort.LAST_READ) { if (sortingMode == LibrarySort.LAST_READ) {
var counter = 0 var counter = 0
lastReadManga = db.getLastReadManga().executeAsBlocking() lastReadManga = db.getLastReadManga().executeAsBlocking()
.associate { it.id!! to counter++ } .associate { it.id!! to counter++ }
} }
val comparator: Comparator<Manga> = if (preferences.librarySortingAscending().getOrDefault()) val sortFn: (Manga, Manga) -> Int = { manga1, manga2 ->
Comparator { m1, m2 -> sortManga(sortingMode, m1, m2) } when (sortingMode) {
else LibrarySort.ALPHA -> manga1.title.compareTo(manga2.title)
Comparator { m1, m2 -> sortManga(sortingMode, m2, m1) } LibrarySort.LAST_READ -> {
// Get index of manga, set equal to list if size unknown.
return map.mapValues { entry -> val manga1LastRead = lastReadManga!![manga1.id!!] ?: lastReadManga!!.size
entry.value val manga2LastRead = lastReadManga!![manga2.id!!] ?: lastReadManga!!.size
.filter(filterFn) manga1LastRead.compareTo(manga2LastRead)
.sortedWith(comparator)
} }
LibrarySort.LAST_UPDATED -> manga2.last_update.compareTo(manga1.last_update)
LibrarySort.UNREAD -> manga1.unread.compareTo(manga2.unread)
else -> throw Exception("Unknown sorting mode")
}
}
val comparator = if (preferences.librarySortingAscending().getOrDefault())
Comparator(sortFn)
else
Collections.reverseOrder(sortFn)
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
} }
/** /**
@ -215,32 +245,15 @@ class LibraryPresenter : BasePresenter<LibraryFragment>() {
/** /**
* Requests the library to be filtered. * Requests the library to be filtered.
*/ */
fun requestLibraryUpdate() { fun requestFilterUpdate() {
updateTriggerRelay.call(Unit) filterTriggerRelay.call(Unit)
} }
/** /**
* Compares the two manga determined by sorting mode. * Requests the library to be sorted.
* Returns zero if this object is equal to the specified other object,
* a negative number if it's less than other, or a positive number if it's greater than other.
*
* @param sortingMode current sorting mode
* @param manga1 first manga to compare
* @param manga2 second manga to compare
*/ */
fun sortManga(sortingMode: Int, manga1: Manga, manga2: Manga): Int { fun requestSortUpdate() {
return when (sortingMode) { sortTriggerRelay.call(Unit)
LibrarySort.ALPHA -> manga1.title.compareTo(manga2.title)
LibrarySort.LAST_READ -> {
// Get index of manga, set equal to list if size unknown.
val manga1LastRead = lastReadManga.getOrElse(manga1.id!!, { lastReadManga.size })
val manga2LastRead = lastReadManga.getOrElse(manga2.id!!, { lastReadManga.size })
manga1LastRead.compareTo(manga2LastRead)
}
LibrarySort.LAST_UPDATED -> manga2.last_update.compareTo(manga1.last_update)
LibrarySort.UNREAD -> manga1.unread.compareTo(manga2.unread)
else -> throw Exception("Unknown sorting mode")
}
} }
/** /**

View File

@ -1,8 +1,13 @@
package eu.kanade.tachiyomi.util package eu.kanade.tachiyomi.util
import rx.Observable
import rx.Subscription import rx.Subscription
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
fun Subscription?.isNullOrUnsubscribed() = this == null || isUnsubscribed fun Subscription?.isNullOrUnsubscribed() = this == null || isUnsubscribed
operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription) operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription)
fun <T, U, R> Observable<T>.combineLatest(o2: Observable<U>, combineFn: (T, U) -> R): Observable<R> {
return Observable.combineLatest(this, o2, combineFn)
}

View File

@ -28,12 +28,4 @@
</changelogtext> </changelogtext>
</changelogversion> </changelogversion>
<changelogversion
changeDate=""
versionName="r359">
<changelogtext>Library sort for "last updated" will only work with manga updated after this
version.
</changelogtext>
</changelogversion>
</changelog> </changelog>