Complete group filters

This commit is contained in:
len
2017-01-15 17:04:31 +01:00
parent e76fb7a524
commit 71ab6d38e4
18 changed files with 217 additions and 193 deletions

View File

@@ -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()

View File

@@ -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())
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -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)
}

View File

@@ -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?>?) {

View File

@@ -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)) }