TriState Filter on library
hXtreme
This commit is contained in:
parent
5874a4d2df
commit
73b1ee5e15
@ -38,7 +38,7 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
versionCode 42
|
versionCode 43
|
||||||
versionName "0.9.0"
|
versionName "0.9.0"
|
||||||
|
|
||||||
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
|
||||||
|
@ -149,11 +149,11 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false)
|
fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false)
|
||||||
|
|
||||||
fun filterDownloaded() = rxPrefs.getBoolean(Keys.filterDownloaded, false)
|
fun filterDownloaded() = rxPrefs.getInteger(Keys.filterDownloaded, 0)
|
||||||
|
|
||||||
fun filterUnread() = rxPrefs.getBoolean(Keys.filterUnread, false)
|
fun filterUnread() = rxPrefs.getInteger(Keys.filterUnread, 0)
|
||||||
|
|
||||||
fun filterCompleted() = rxPrefs.getBoolean(Keys.filterCompleted, false)
|
fun filterCompleted() = rxPrefs.getInteger(Keys.filterCompleted, 0)
|
||||||
|
|
||||||
fun librarySortingMode() = rxPrefs.getInteger(Keys.librarySortingMode, 0)
|
fun librarySortingMode() = rxPrefs.getInteger(Keys.librarySortingMode, 0)
|
||||||
|
|
||||||
@ -176,4 +176,13 @@ class PreferencesHelper(val context: Context) {
|
|||||||
fun migrateFlags() = rxPrefs.getInteger("migrate_flags", Int.MAX_VALUE)
|
fun migrateFlags() = rxPrefs.getInteger("migrate_flags", Int.MAX_VALUE)
|
||||||
|
|
||||||
fun trustedSignatures() = rxPrefs.getStringSet("trusted_signatures", emptySet())
|
fun trustedSignatures() = rxPrefs.getStringSet("trusted_signatures", emptySet())
|
||||||
|
|
||||||
|
fun upgradeFilters() {
|
||||||
|
val filterDl = rxPrefs.getBoolean(Keys.filterDownloaded, false).getOrDefault()
|
||||||
|
val filterUn = rxPrefs.getBoolean(Keys.filterUnread, false).getOrDefault()
|
||||||
|
val filterCm = rxPrefs.getBoolean(Keys.filterCompleted, false).getOrDefault()
|
||||||
|
filterDownloaded().set(if (filterDl) 1 else 0)
|
||||||
|
filterUnread().set(if (filterUn) 1 else 0)
|
||||||
|
filterCompleted().set(if (filterCm) 1 else 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,14 @@ import android.util.AttributeSet
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
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.ui.catalogue.filter.TriStateItem
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_ASC
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_ASC
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_DESC
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_DESC
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_NONE
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.MultiSort.Companion.SORT_NONE
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +52,7 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A
|
|||||||
* Returns true if there's at least one filter from [FilterGroup] active.
|
* Returns true if there's at least one filter from [FilterGroup] active.
|
||||||
*/
|
*/
|
||||||
fun hasActiveFilters(): Boolean {
|
fun hasActiveFilters(): Boolean {
|
||||||
return (groups[0] as FilterGroup).items.any { it.checked }
|
return (groups[0] as FilterGroup).items.any { it.state != STATE_IGNORE }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,11 +73,11 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A
|
|||||||
*/
|
*/
|
||||||
inner class FilterGroup : Group {
|
inner class FilterGroup : Group {
|
||||||
|
|
||||||
private val downloaded = Item.CheckboxGroup(R.string.action_filter_downloaded, this)
|
private val downloaded = Item.TriStateGroup(R.string.action_filter_downloaded, this)
|
||||||
|
|
||||||
private val unread = Item.CheckboxGroup(R.string.action_filter_unread, this)
|
private val unread = Item.TriStateGroup(R.string.action_filter_unread, this)
|
||||||
|
|
||||||
private val completed = Item.CheckboxGroup(R.string.completed, this)
|
private val completed = Item.TriStateGroup(R.string.completed, this)
|
||||||
|
|
||||||
override val items = listOf(downloaded, unread, completed)
|
override val items = listOf(downloaded, unread, completed)
|
||||||
|
|
||||||
@ -82,18 +86,28 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A
|
|||||||
override val footer = Item.Separator()
|
override val footer = Item.Separator()
|
||||||
|
|
||||||
override fun initModels() {
|
override fun initModels() {
|
||||||
downloaded.checked = preferences.filterDownloaded().getOrDefault()
|
try {
|
||||||
unread.checked = preferences.filterUnread().getOrDefault()
|
downloaded.state = preferences.filterDownloaded().getOrDefault()
|
||||||
completed.checked = preferences.filterCompleted().getOrDefault()
|
unread.state = preferences.filterUnread().getOrDefault()
|
||||||
|
completed.state = preferences.filterCompleted().getOrDefault()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
preferences.upgradeFilters()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClicked(item: Item) {
|
override fun onItemClicked(item: Item) {
|
||||||
item as Item.CheckboxGroup
|
item as Item.TriStateGroup
|
||||||
item.checked = !item.checked
|
val newState = when (item.state) {
|
||||||
|
STATE_IGNORE -> STATE_INCLUDE
|
||||||
|
STATE_INCLUDE -> STATE_EXCLUDE
|
||||||
|
else -> STATE_IGNORE
|
||||||
|
}
|
||||||
|
item.state = newState
|
||||||
when (item) {
|
when (item) {
|
||||||
downloaded -> preferences.filterDownloaded().set(item.checked)
|
downloaded -> preferences.filterDownloaded().set(item.state)
|
||||||
unread -> preferences.filterUnread().set(item.checked)
|
unread -> preferences.filterUnread().set(item.state)
|
||||||
completed -> preferences.filterCompleted().set(item.checked)
|
completed -> preferences.filterCompleted().set(item.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.notifyItemChanged(item)
|
adapter.notifyItemChanged(item)
|
||||||
|
@ -17,11 +17,14 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_INCLUDE
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
||||||
import eu.kanade.tachiyomi.util.combineLatest
|
import eu.kanade.tachiyomi.util.combineLatest
|
||||||
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
|
import eu.kanade.tachiyomi.util.isNullOrUnsubscribed
|
||||||
import eu.kanade.tachiyomi.util.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.syncChaptersWithSource
|
||||||
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_IGNORE
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -121,26 +124,22 @@ class LibraryPresenter(
|
|||||||
|
|
||||||
val filterFn: (LibraryItem) -> Boolean = f@ { item ->
|
val filterFn: (LibraryItem) -> Boolean = f@ { item ->
|
||||||
// Filter when there isn't unread chapters.
|
// Filter when there isn't unread chapters.
|
||||||
if (filterUnread && item.manga.unread == 0) {
|
if (filterUnread == STATE_INCLUDE && item.manga.unread == 0) return@f false
|
||||||
return@f false
|
if (filterUnread == STATE_EXCLUDE && item.manga.unread > 0) return@f false
|
||||||
}
|
|
||||||
|
|
||||||
if (filterCompleted && item.manga.status != SManga.COMPLETED) {
|
if (filterCompleted == STATE_INCLUDE && item.manga.status != SManga.COMPLETED)
|
||||||
|
return@f false
|
||||||
|
if (filterCompleted == STATE_EXCLUDE && item.manga.status == SManga.COMPLETED)
|
||||||
return@f false
|
return@f false
|
||||||
}
|
|
||||||
|
|
||||||
// Filter when there are no downloads.
|
// Filter when there are no downloads.
|
||||||
if (filterDownloaded) {
|
if (filterDownloaded != STATE_IGNORE) {
|
||||||
// Local manga are always downloaded
|
val isDownloaded = when {
|
||||||
if (item.manga.source == LocalSource.ID) {
|
item.manga.source == LocalSource.ID -> true
|
||||||
return@f true
|
item.downloadCount != -1 -> item.downloadCount > 0
|
||||||
|
else -> downloadManager.getDownloadCount(item.manga) > 0
|
||||||
}
|
}
|
||||||
// Don't bother with directory checking if download count has been set.
|
return@f if (filterDownloaded == STATE_INCLUDE) isDownloaded else !isDownloaded
|
||||||
if (item.downloadCount != -1) {
|
|
||||||
return@f item.downloadCount > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return@f downloadManager.getDownloadCount(item.manga) > 0
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,18 @@ open class ExtendedNavigationView @JvmOverloads constructor(
|
|||||||
setTint(context.getResourceColor(R.attr.colorAccent))
|
setTint(context.getResourceColor(R.attr.colorAccent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vector tinted with the accent color.
|
||||||
|
*
|
||||||
|
* @param context any context.
|
||||||
|
* @param resId the vector resource to load and tint
|
||||||
|
*/
|
||||||
|
fun tintVector(context: Context, resId: Int, colorId: Int): Drawable {
|
||||||
|
return VectorDrawableCompat.create(context.resources, resId, context.theme)!!.apply {
|
||||||
|
setTint(context.getResourceColor(colorId))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +119,25 @@ open class ExtendedNavigationView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TriStateGroup(resId: Int, group: Group) : MultiStateGroup(resId, group) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val STATE_IGNORE = 0
|
||||||
|
const val STATE_INCLUDE = 1
|
||||||
|
const val STATE_EXCLUDE = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStateDrawable(context: Context): Drawable? {
|
||||||
|
return when(state) {
|
||||||
|
STATE_INCLUDE -> tintVector(context, R.drawable.ic_check_box_24dp)
|
||||||
|
STATE_EXCLUDE -> tintVector(context, R.drawable.ic_check_box_x_24dp,
|
||||||
|
android.R.attr.textColorSecondary)
|
||||||
|
else -> tintVector(context, R.drawable.ic_check_box_outline_blank_24dp,
|
||||||
|
android.R.attr.textColorSecondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user