mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-12 20:19:05 +01:00
Complete group filters
This commit is contained in:
@@ -208,7 +208,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
|
||||
showProgressBar()
|
||||
adapter.clear()
|
||||
presenter.setActiveSource(source)
|
||||
navView?.setFilters(presenter.sourceFilters)
|
||||
navView?.setFilters(presenter.filterItems)
|
||||
activity.invalidateOptionsMenu()
|
||||
}
|
||||
}
|
||||
@@ -229,7 +229,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
|
||||
this.navView = navView
|
||||
activity.drawer.addView(navView)
|
||||
activity.drawer.addDrawerListener(drawerListener)
|
||||
navView.setFilters(presenter.sourceFilters)
|
||||
navView.setFilters(presenter.filterItems)
|
||||
|
||||
navView.post {
|
||||
if (isAdded && !activity.drawer.isDrawerOpen(navView))
|
||||
@@ -247,7 +247,7 @@ open class CatalogueFragment : BaseRxFragment<CataloguePresenter>(), FlexibleVie
|
||||
presenter.appliedFilters = FilterList()
|
||||
val newFilters = presenter.source.getFilterList()
|
||||
presenter.sourceFilters = newFilters
|
||||
navView.setFilters(newFilters)
|
||||
navView.setFilters(presenter.filterItems)
|
||||
}
|
||||
|
||||
showProgressBar()
|
||||
|
||||
@@ -5,11 +5,7 @@ import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.source.model.Filter
|
||||
import eu.kanade.tachiyomi.data.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.ui.catalogue.filter.*
|
||||
import eu.kanade.tachiyomi.util.inflate
|
||||
import eu.kanade.tachiyomi.widget.SimpleNavigationView
|
||||
import kotlinx.android.synthetic.main.catalogue_drawer_content.view.*
|
||||
@@ -18,7 +14,9 @@ import kotlinx.android.synthetic.main.catalogue_drawer_content.view.*
|
||||
class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null)
|
||||
: SimpleNavigationView(context, attrs) {
|
||||
|
||||
val adapter = FlexibleAdapter<IFlexible<*>>(null)
|
||||
val adapter: FlexibleAdapter<IFlexible<*>> = FlexibleAdapter<IFlexible<*>>(null)
|
||||
.setDisplayHeadersAtStartUp(true)
|
||||
.setStickyHeaders(true)
|
||||
|
||||
var onSearchClicked = {}
|
||||
|
||||
@@ -26,53 +24,17 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
|
||||
|
||||
init {
|
||||
recycler.adapter = adapter
|
||||
recycler.setHasFixedSize(true)
|
||||
val view = inflate(R.layout.catalogue_drawer_content)
|
||||
((view as ViewGroup).getChildAt(1) as ViewGroup).addView(recycler)
|
||||
addView(view)
|
||||
|
||||
search_btn.setOnClickListener { onSearchClicked() }
|
||||
reset_btn.setOnClickListener { onResetClicked() }
|
||||
|
||||
adapter.setDisplayHeadersAtStartUp(true)
|
||||
adapter.setStickyHeaders(true)
|
||||
}
|
||||
|
||||
fun setFilters(filters: FilterList) {
|
||||
val items = filters.mapNotNull {
|
||||
when (it) {
|
||||
is Filter.Header -> HeaderItem(it)
|
||||
is Filter.Separator -> SeparatorItem(it)
|
||||
is Filter.CheckBox -> CheckboxItem(it)
|
||||
is Filter.TriState -> TriStateItem(it)
|
||||
is Filter.Text -> TextItem(it)
|
||||
is Filter.Select<*> -> SelectItem(it)
|
||||
is Filter.Group<*> -> {
|
||||
val group = GroupItem(it)
|
||||
val subItems = it.state.mapNotNull {
|
||||
when (it) {
|
||||
is Filter.CheckBox -> CheckboxSectionItem(it)
|
||||
is Filter.TriState -> TriStateSectionItem(it)
|
||||
is Filter.Text -> TextSectionItem(it)
|
||||
is Filter.Select<*> -> SelectSectionItem(it)
|
||||
else -> null
|
||||
} as? ISectionable<*, *>
|
||||
}
|
||||
subItems.forEach { it.header = group }
|
||||
group.subItems = subItems
|
||||
group
|
||||
}
|
||||
is Filter.Sort -> {
|
||||
val group = SortGroup(it)
|
||||
val subItems = it.values.mapNotNull {
|
||||
SortItem(it, group)
|
||||
}
|
||||
group.subItems = subItems
|
||||
group
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
adapter.updateDataSet(items)
|
||||
fun setFilters(items: List<IFlexible<*>>) {
|
||||
adapter.updateDataSet(items.toMutableList())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package eu.kanade.tachiyomi.ui.catalogue
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@@ -9,10 +11,12 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.data.source.Source
|
||||
import eu.kanade.tachiyomi.data.source.SourceManager
|
||||
import eu.kanade.tachiyomi.data.source.model.Filter
|
||||
import eu.kanade.tachiyomi.data.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.data.source.model.SManga
|
||||
import eu.kanade.tachiyomi.data.source.online.LoginSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.catalogue.filter.*
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
@@ -68,6 +72,12 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
|
||||
* Modifiable list of filters.
|
||||
*/
|
||||
var sourceFilters = FilterList()
|
||||
set(value) {
|
||||
field = value
|
||||
filterItems = value.toItems()
|
||||
}
|
||||
|
||||
var filterItems: List<IFlexible<*>> = emptyList()
|
||||
|
||||
/**
|
||||
* List of filters used by the [Pager]. If empty alongside [query], the popular query is used.
|
||||
@@ -362,4 +372,41 @@ open class CataloguePresenter : BasePresenter<CatalogueFragment>() {
|
||||
return CataloguePager(source, query, filters)
|
||||
}
|
||||
|
||||
private fun FilterList.toItems(): List<IFlexible<*>> {
|
||||
return mapNotNull {
|
||||
when (it) {
|
||||
is Filter.Header -> HeaderItem(it)
|
||||
is Filter.Separator -> SeparatorItem(it)
|
||||
is Filter.CheckBox -> CheckboxItem(it)
|
||||
is Filter.TriState -> TriStateItem(it)
|
||||
is Filter.Text -> TextItem(it)
|
||||
is Filter.Select<*> -> SelectItem(it)
|
||||
is Filter.Group<*> -> {
|
||||
val group = GroupItem(it)
|
||||
val subItems = it.state.mapNotNull {
|
||||
when (it) {
|
||||
is Filter.CheckBox -> CheckboxSectionItem(it)
|
||||
is Filter.TriState -> TriStateSectionItem(it)
|
||||
is Filter.Text -> TextSectionItem(it)
|
||||
is Filter.Select<*> -> SelectSectionItem(it)
|
||||
else -> null
|
||||
} as? ISectionable<*, *>
|
||||
}
|
||||
subItems.forEach { it.header = group }
|
||||
group.subItems = subItems
|
||||
group
|
||||
}
|
||||
is Filter.Sort -> {
|
||||
val group = SortGroup(it)
|
||||
val subItems = it.values.mapNotNull {
|
||||
SortItem(it, group)
|
||||
}
|
||||
group.subItems = subItems
|
||||
group
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<Grou
|
||||
return filter.hashCode()
|
||||
}
|
||||
|
||||
class Holder(view: View, adapter: FlexibleAdapter<*>) : ExpandableViewHolder(view, adapter, true) {
|
||||
open class Holder(view: View, adapter: FlexibleAdapter<*>) : ExpandableViewHolder(view, adapter, true) {
|
||||
|
||||
val title = itemView.findViewById(R.id.title) as TextView
|
||||
val icon = itemView.findViewById(R.id.expand_icon) as ImageView
|
||||
|
||||
@@ -12,6 +12,18 @@ class TriStateSectionItem(filter: Filter.TriState) : TriStateItem(filter), ISect
|
||||
override fun setHeader(header: GroupItem?) {
|
||||
head = header
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is TriStateSectionItem) {
|
||||
return filter == other.filter
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return filter.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class TextSectionItem(filter: Filter.Text) : TextItem(filter), ISectionable<TextItem.Holder, GroupItem> {
|
||||
@@ -23,6 +35,18 @@ class TextSectionItem(filter: Filter.Text) : TextItem(filter), ISectionable<Text
|
||||
override fun setHeader(header: GroupItem?) {
|
||||
head = header
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is TextSectionItem) {
|
||||
return filter == other.filter
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return filter.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class CheckboxSectionItem(filter: Filter.CheckBox) : CheckboxItem(filter), ISectionable<CheckboxItem.Holder, GroupItem> {
|
||||
@@ -34,6 +58,18 @@ class CheckboxSectionItem(filter: Filter.CheckBox) : CheckboxItem(filter), ISect
|
||||
override fun setHeader(header: GroupItem?) {
|
||||
head = header
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is CheckboxSectionItem) {
|
||||
return filter == other.filter
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return filter.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
class SelectSectionItem(filter: Filter.Select<*>) : SelectItem(filter), ISectionable<SelectItem.Holder, GroupItem> {
|
||||
@@ -45,4 +81,16 @@ class SelectSectionItem(filter: Filter.Select<*>) : SelectItem(filter), ISection
|
||||
override fun setHeader(header: GroupItem?) {
|
||||
head = header
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is SelectSectionItem) {
|
||||
return filter == other.filter
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return filter.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,22 @@ package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
|
||||
import eu.davidea.flexibleadapter.items.ISectionable
|
||||
import eu.davidea.viewholders.ExpandableViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.source.model.Filter
|
||||
import eu.kanade.tachiyomi.util.setVectorCompat
|
||||
|
||||
class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGroup.Holder, ISectionable<*, *>>() {
|
||||
|
||||
// Use an id instead of the layout res to allow to reuse the layout.
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.navigation_view_sort
|
||||
return R.id.catalogue_filter_sort_group
|
||||
}
|
||||
|
||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
||||
return Holder(inflater.inflate(R.layout.navigation_view_group, parent, false), adapter)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||
@@ -44,14 +42,5 @@ class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGrou
|
||||
return filter.hashCode()
|
||||
}
|
||||
|
||||
class Holder(view: View, adapter: FlexibleAdapter<*>) : ExpandableViewHolder(view, adapter, true) {
|
||||
|
||||
val title = itemView.findViewById(R.id.title) as TextView
|
||||
val icon = itemView.findViewById(R.id.expand_icon) as ImageView
|
||||
|
||||
override fun shouldNotifyParentOnClick(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class Holder(view: View, adapter: FlexibleAdapter<*>) : GroupItem.Holder(view, adapter)
|
||||
}
|
||||
@@ -15,12 +15,13 @@ import eu.kanade.tachiyomi.util.getResourceColor
|
||||
|
||||
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {
|
||||
|
||||
// Use an id instead of the layout res to allow to reuse the layout.
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.navigation_view_sort_item
|
||||
return R.id.catalogue_filter_sort_item
|
||||
}
|
||||
|
||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
||||
return Holder(inflater.inflate(R.layout.navigation_view_checkedtext, parent, false), adapter)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||
|
||||
@@ -92,7 +92,7 @@ class CategoryActivity :
|
||||
*/
|
||||
fun setCategories(categories: List<CategoryItem>) {
|
||||
actionMode?.finish()
|
||||
adapter.updateDataSet(categories)
|
||||
adapter.updateDataSet(categories.toMutableList())
|
||||
val selected = categories.filter { it.isSelected }
|
||||
if (selected.isNotEmpty()) {
|
||||
selected.forEach { onItemLongClick(categories.indexOf(it)) }
|
||||
|
||||
Reference in New Issue
Block a user