From 36bbb906c1de4bd97ad138c14cb1956f0983ecca Mon Sep 17 00:00:00 2001 From: len Date: Thu, 15 Dec 2016 18:51:12 +0100 Subject: [PATCH] Library sort change doesn't trigger filtering --- .../tachiyomi/ui/library/LibraryFragment.kt | 4 +- .../tachiyomi/ui/library/LibraryPresenter.kt | 97 +++++++++++-------- .../eu/kanade/tachiyomi/util/LocaleHelper.kt | 2 +- .../eu/kanade/tachiyomi/util/RxExtensions.kt | 7 +- app/src/main/res/raw/changelog_debug.xml | 8 -- 5 files changed, 64 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt index de9b52267..9a0787cd0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryFragment.kt @@ -275,7 +275,7 @@ class LibraryFragment : BaseRxFragment(), ActionMode.Callback * Called when a filter is changed. */ private fun onFilterChanged() { - presenter.requestLibraryUpdate() + presenter.requestFilterUpdate() activity.supportInvalidateOptionsMenu() } @@ -283,7 +283,7 @@ class LibraryFragment : BaseRxFragment(), ActionMode.Callback * Called when the sorting mode is changed. */ private fun onSortChanged() { - presenter.requestLibraryUpdate() + presenter.requestSortUpdate() } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 4c92d07a7..acdffc33f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.util.combineLatest import eu.kanade.tachiyomi.util.isNullOrUnsubscribed import rx.Observable import rx.Subscription @@ -83,12 +84,12 @@ class LibraryPresenter : BasePresenter() { /** * 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 + private val sortTriggerRelay = BehaviorRelay.create(Unit) /** * Library subscription. @@ -105,16 +106,23 @@ class LibraryPresenter : BasePresenter() { */ fun subscribeLibrary() { if (librarySubscription.isNullOrUnsubscribed()) { - librarySubscription = Observable.combineLatest(getLibraryObservable(), - updateTriggerRelay.observeOn(Schedulers.io()), - { library, updateTrigger -> library }) - .map { Pair(it.first, applyFilters(it.second)) } + librarySubscription = getLibraryObservable() + .combineLatest(filterTriggerRelay.observeOn(Schedulers.io()), + { lib, tick -> Pair(lib.first, applyFilters(lib.second)) }) + .combineLatest(sortTriggerRelay.observeOn(Schedulers.io()), + { lib, tick -> Pair(lib.first, applySort(lib.second)) }) .observeOn(AndroidSchedulers.mainThread()) - .subscribeLatestCache( - { view, pair -> view.onNextLibraryUpdate(pair.first, pair.second) }) + .subscribeLatestCache({ view, pair -> + 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>): Map> { // Cached list of downloaded manga directories given a source id. val mangaDirectories = mutableMapOf>() @@ -126,7 +134,7 @@ class LibraryPresenter : BasePresenter() { val filterUnread = preferences.filterUnread().getOrDefault() - val filterFn: (Manga) -> Boolean = f@ { manga: Manga -> + val filterFn: (Manga) -> Boolean = f@ { manga -> // Filter out manga without source. val source = sourceManager.get(manga.source) ?: return@f false @@ -154,24 +162,46 @@ class LibraryPresenter : BasePresenter() { 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>): Map> { val sortingMode = preferences.librarySortingMode().getOrDefault() + + // TODO lazy initialization in kotlin 1.1 + var lastReadManga: Map? = null if (sortingMode == LibrarySort.LAST_READ) { var counter = 0 lastReadManga = db.getLastReadManga().executeAsBlocking() .associate { it.id!! to counter++ } } - val comparator: Comparator = if (preferences.librarySortingAscending().getOrDefault()) - Comparator { m1, m2 -> sortManga(sortingMode, m1, m2) } - else - Comparator { m1, m2 -> sortManga(sortingMode, m2, m1) } - - return map.mapValues { entry -> - entry.value - .filter(filterFn) - .sortedWith(comparator) + val sortFn: (Manga, Manga) -> Int = { manga1, manga2 -> + when (sortingMode) { + LibrarySort.ALPHA -> manga1.title.compareTo(manga2.title) + LibrarySort.LAST_READ -> { + // Get index of manga, set equal to list if size unknown. + val manga1LastRead = lastReadManga!![manga1.id!!] ?: lastReadManga!!.size + val manga2LastRead = lastReadManga!![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") + } } + + 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() { /** * Requests the library to be filtered. */ - fun requestLibraryUpdate() { - updateTriggerRelay.call(Unit) + fun requestFilterUpdate() { + filterTriggerRelay.call(Unit) } /** - * Compares the two manga determined by sorting mode. - * 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 + * Requests the library to be sorted. */ - fun sortManga(sortingMode: Int, manga1: Manga, manga2: Manga): Int { - return when (sortingMode) { - 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") - } + fun requestSortUpdate() { + sortTriggerRelay.call(Unit) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt index 4fa048d2b..1850bad24 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt @@ -27,7 +27,7 @@ object LocaleHelper { } } - fun updateCfg(app: Application, config: Configuration){ + fun updateCfg(app: Application, config: Configuration) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { config.locale = pLocale app.baseContext.resources.updateConfiguration(config, app.baseContext.resources.displayMetrics) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/RxExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/RxExtensions.kt index 9561dfe69..1f4933552 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/RxExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/RxExtensions.kt @@ -1,8 +1,13 @@ package eu.kanade.tachiyomi.util +import rx.Observable import rx.Subscription import rx.subscriptions.CompositeSubscription fun Subscription?.isNullOrUnsubscribed() = this == null || isUnsubscribed -operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription) \ No newline at end of file +operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription) + +fun Observable.combineLatest(o2: Observable, combineFn: (T, U) -> R): Observable { + return Observable.combineLatest(this, o2, combineFn) +} \ No newline at end of file diff --git a/app/src/main/res/raw/changelog_debug.xml b/app/src/main/res/raw/changelog_debug.xml index 81999d770..2393bc919 100644 --- a/app/src/main/res/raw/changelog_debug.xml +++ b/app/src/main/res/raw/changelog_debug.xml @@ -28,12 +28,4 @@ - - Library sort for "last updated" will only work with manga updated after this - version. - - - \ No newline at end of file