mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-07 11:17:25 +01:00
Update flexible adapter. Show fast scroller in chapters screen
This commit is contained in:
parent
6b1a3a20e5
commit
5c4139be45
@ -194,7 +194,7 @@ dependencies {
|
|||||||
// UI
|
// UI
|
||||||
implementation 'com.dmitrymalkovich.android:material-design-dimens:1.4'
|
implementation 'com.dmitrymalkovich.android:material-design-dimens:1.4'
|
||||||
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
|
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
|
||||||
implementation 'eu.davidea:flexible-adapter:5.0.0-rc1'
|
implementation 'eu.davidea:flexible-adapter:5.0.0-rc3'
|
||||||
implementation 'com.nononsenseapps:filepicker:2.5.2'
|
implementation 'com.nononsenseapps:filepicker:2.5.2'
|
||||||
implementation 'com.github.amulyakhare:TextDrawable:558677e'
|
implementation 'com.github.amulyakhare:TextDrawable:558677e'
|
||||||
implementation('com.afollestad.material-dialogs:core:0.9.4.7') {
|
implementation('com.afollestad.material-dialogs:core:0.9.4.7') {
|
||||||
|
@ -44,7 +44,7 @@ open class CatalogueController(bundle: Bundle) :
|
|||||||
SecondaryDrawerController,
|
SecondaryDrawerController,
|
||||||
FlexibleAdapter.OnItemClickListener,
|
FlexibleAdapter.OnItemClickListener,
|
||||||
FlexibleAdapter.OnItemLongClickListener,
|
FlexibleAdapter.OnItemLongClickListener,
|
||||||
FlexibleAdapter.EndlessScrollListener<ProgressItem>,
|
FlexibleAdapter.EndlessScrollListener,
|
||||||
ChangeMangaCategoriesDialog.Listener {
|
ChangeMangaCategoriesDialog.Listener {
|
||||||
|
|
||||||
constructor(source: CatalogueSource) : this(Bundle().apply {
|
constructor(source: CatalogueSource) : this(Bundle().apply {
|
||||||
|
@ -1,39 +1,40 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue
|
package eu.kanade.tachiyomi.ui.catalogue
|
||||||
|
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
||||||
|
|
||||||
class CatalogueItem(val manga: Manga) : AbstractFlexibleItem<CatalogueHolder>() {
|
class CatalogueItem(val manga: Manga, private val catalogueAsList: Preference<Boolean>) :
|
||||||
|
AbstractFlexibleItem<CatalogueHolder>() {
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.catalogue_grid_item
|
return if (catalogueAsList.getOrDefault())
|
||||||
|
R.layout.catalogue_list_item
|
||||||
|
else
|
||||||
|
R.layout.catalogue_grid_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueHolder {
|
||||||
inflater: LayoutInflater,
|
val parent = adapter.recyclerView
|
||||||
parent: ViewGroup): CatalogueHolder {
|
return if (parent is AutofitRecyclerView) {
|
||||||
|
view.apply {
|
||||||
if (parent is AutofitRecyclerView) {
|
|
||||||
val view = parent.inflate(R.layout.catalogue_grid_item).apply {
|
|
||||||
card.layoutParams = FrameLayout.LayoutParams(
|
card.layoutParams = FrameLayout.LayoutParams(
|
||||||
MATCH_PARENT, parent.itemWidth / 3 * 4)
|
MATCH_PARENT, parent.itemWidth / 3 * 4)
|
||||||
gradient.layoutParams = FrameLayout.LayoutParams(
|
gradient.layoutParams = FrameLayout.LayoutParams(
|
||||||
MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM)
|
MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM)
|
||||||
}
|
}
|
||||||
return CatalogueGridHolder(view, adapter)
|
CatalogueGridHolder(view, adapter)
|
||||||
} else {
|
} else {
|
||||||
val view = parent.inflate(R.layout.catalogue_list_item)
|
CatalogueListHolder(view, adapter)
|
||||||
return CatalogueListHolder(view, adapter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setFilters(items: List<IFlexible<*>>) {
|
fun setFilters(items: List<IFlexible<*>>) {
|
||||||
adapter.updateDataSet(items.toMutableList())
|
adapter.updateDataSet(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -131,13 +131,15 @@ open class CataloguePresenter(
|
|||||||
|
|
||||||
val sourceId = source.id
|
val sourceId = source.id
|
||||||
|
|
||||||
|
val catalogueAsList = prefs.catalogueAsList()
|
||||||
|
|
||||||
// Prepare the pager.
|
// Prepare the pager.
|
||||||
pagerSubscription?.let { remove(it) }
|
pagerSubscription?.let { remove(it) }
|
||||||
pagerSubscription = pager.results()
|
pagerSubscription = pager.results()
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.map { it.first to it.second.map { networkToLocalManga(it, sourceId) } }
|
.map { it.first to it.second.map { networkToLocalManga(it, sourceId) } }
|
||||||
.doOnNext { initializeMangas(it.second) }
|
.doOnNext { initializeMangas(it.second) }
|
||||||
.map { it.first to it.second.map(::CatalogueItem) }
|
.map { it.first to it.second.map { CatalogueItem(it, catalogueAsList) } }
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeReplay({ view, (page, mangas) ->
|
.subscribeReplay({ view, (page, mangas) ->
|
||||||
view.onAddPage(page, mangas)
|
view.onAddPage(page, mangas)
|
||||||
|
@ -1,30 +1,27 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue
|
package eu.kanade.tachiyomi.ui.catalogue
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
|
|
||||||
class ProgressItem : AbstractFlexibleItem<ProgressItem.Holder>() {
|
class ProgressItem : AbstractFlexibleItem<ProgressItem.Holder>() {
|
||||||
|
|
||||||
var loadMore = true
|
private var loadMore = true
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.catalogue_progress_item
|
return R.layout.catalogue_progress_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: Holder, position: Int, payloads: List<Any?>) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>) {
|
||||||
holder.progressBar.visibility = View.GONE
|
holder.progressBar.visibility = View.GONE
|
||||||
holder.progressMessage.visibility = View.GONE
|
holder.progressMessage.visibility = View.GONE
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.filter
|
package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -16,8 +14,8 @@ open class CheckboxItem(val filter: Filter.CheckBox) : AbstractFlexibleItem<Chec
|
|||||||
return R.layout.navigation_view_checkbox
|
return R.layout.navigation_view_checkbox
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.filter
|
package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
@ -19,8 +17,12 @@ class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<Grou
|
|||||||
return R.layout.navigation_view_group
|
return R.layout.navigation_view_group
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun getItemViewType(): Int {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return 101
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.support.design.R
|
import android.support.design.R
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
@ -18,8 +16,8 @@ class HeaderItem(val filter: Filter.Header) : AbstractHeaderItem<HeaderItem.Hold
|
|||||||
return R.layout.design_navigation_item_subheader
|
return R.layout.design_navigation_item_subheader
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.filter
|
package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@ -19,8 +17,8 @@ open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<Selec
|
|||||||
return R.layout.navigation_view_spinner
|
return R.layout.navigation_view_spinner
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.support.design.R
|
import android.support.design.R
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
@ -17,8 +15,8 @@ class SeparatorItem(val filter: Filter.Separator) : AbstractHeaderItem<Separator
|
|||||||
return R.layout.design_navigation_item_separator
|
return R.layout.design_navigation_item_separator
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.filter
|
package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem
|
||||||
import eu.davidea.flexibleadapter.items.ISectionable
|
import eu.davidea.flexibleadapter.items.ISectionable
|
||||||
@ -12,13 +10,16 @@ import eu.kanade.tachiyomi.util.setVectorCompat
|
|||||||
|
|
||||||
class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGroup.Holder, ISectionable<*, *>>() {
|
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 {
|
override fun getLayoutRes(): Int {
|
||||||
return R.id.catalogue_filter_sort_group
|
return R.layout.navigation_view_group
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun getItemViewType(): Int {
|
||||||
return Holder(inflater.inflate(R.layout.navigation_view_group, parent, false), adapter)
|
return 100
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter
|
|||||||
|
|
||||||
import android.support.graphics.drawable.VectorDrawableCompat
|
import android.support.graphics.drawable.VectorDrawableCompat
|
||||||
import android.support.v4.content.ContextCompat
|
import android.support.v4.content.ContextCompat
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.CheckedTextView
|
import android.widget.CheckedTextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||||
@ -15,13 +13,16 @@ import eu.kanade.tachiyomi.util.getResourceColor
|
|||||||
|
|
||||||
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {
|
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 {
|
override fun getLayoutRes(): Int {
|
||||||
return R.id.catalogue_filter_sort_item
|
return R.layout.navigation_view_checkedtext
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun getItemViewType(): Int {
|
||||||
return Holder(inflater.inflate(R.layout.navigation_view_checkedtext, parent, false), adapter)
|
return 102
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.filter
|
package eu.kanade.tachiyomi.ui.catalogue.filter
|
||||||
|
|
||||||
import android.support.design.widget.TextInputLayout
|
import android.support.design.widget.TextInputLayout
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -18,8 +16,8 @@ open class TextItem(val filter: Filter.Text) : AbstractFlexibleItem<TextItem.Hol
|
|||||||
return R.layout.navigation_view_text
|
return R.layout.navigation_view_text
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter
|
|||||||
|
|
||||||
import android.support.design.R
|
import android.support.design.R
|
||||||
import android.support.graphics.drawable.VectorDrawableCompat
|
import android.support.graphics.drawable.VectorDrawableCompat
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.CheckedTextView
|
import android.widget.CheckedTextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -20,8 +18,12 @@ open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriS
|
|||||||
return TR.layout.navigation_view_checkedtext
|
return TR.layout.navigation_view_checkedtext
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup?): Holder {
|
override fun getItemViewType(): Int {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return 103
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.global_search
|
package eu.kanade.tachiyomi.ui.catalogue.global_search
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
|
||||||
|
|
||||||
class CatalogueSearchCardItem(val manga: Manga) : AbstractFlexibleItem<CatalogueSearchCardHolder>() {
|
class CatalogueSearchCardItem(val manga: Manga) : AbstractFlexibleItem<CatalogueSearchCardHolder>() {
|
||||||
|
|
||||||
@ -14,9 +12,8 @@ class CatalogueSearchCardItem(val manga: Manga) : AbstractFlexibleItem<Catalogue
|
|||||||
return R.layout.catalogue_global_search_controller_card_item
|
return R.layout.catalogue_global_search_controller_card_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueSearchCardHolder {
|
||||||
parent: ViewGroup): CatalogueSearchCardHolder {
|
return CatalogueSearchCardHolder(view, adapter as CatalogueSearchCardAdapter)
|
||||||
return CatalogueSearchCardHolder(parent.inflate(layoutRes), adapter as CatalogueSearchCardAdapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: CatalogueSearchCardHolder,
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: CatalogueSearchCardHolder,
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.global_search
|
package eu.kanade.tachiyomi.ui.catalogue.global_search
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item that contains search result information.
|
* Item that contains search result information.
|
||||||
@ -30,9 +28,8 @@ class CatalogueSearchItem(val source: CatalogueSource, val results: List<Catalog
|
|||||||
*
|
*
|
||||||
* @return holder of view.
|
* @return holder of view.
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueSearchHolder {
|
||||||
parent: ViewGroup): CatalogueSearchHolder {
|
return CatalogueSearchHolder(view, adapter as CatalogueSearchAdapter)
|
||||||
return CatalogueSearchHolder(parent.inflate(layoutRes), adapter as CatalogueSearchAdapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,7 +221,7 @@ class CatalogueMainController : NucleusController<CatalogueMainPresenter>(),
|
|||||||
* Called to update adapter containing sources.
|
* Called to update adapter containing sources.
|
||||||
*/
|
*/
|
||||||
fun setSources(sources: List<IFlexible<*>>) {
|
fun setSources(sources: List<IFlexible<*>>) {
|
||||||
adapter?.updateDataSet(sources.toMutableList())
|
adapter?.updateDataSet(sources)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.main
|
package eu.kanade.tachiyomi.ui.catalogue.main
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -23,10 +22,8 @@ data class LangItem(val code: String) : AbstractHeaderItem<LangHolder>() {
|
|||||||
/**
|
/**
|
||||||
* Creates a new view holder for this item.
|
* Creates a new view holder for this item.
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): LangHolder {
|
||||||
parent: ViewGroup): LangHolder {
|
return LangHolder(view, adapter)
|
||||||
|
|
||||||
return LangHolder(inflater.inflate(layoutRes, parent, false), adapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.catalogue.main
|
package eu.kanade.tachiyomi.ui.catalogue.main
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -26,10 +25,7 @@ data class SourceItem(val source: CatalogueSource, val header: LangItem? = null)
|
|||||||
/**
|
/**
|
||||||
* Creates a new view holder for this item.
|
* Creates a new view holder for this item.
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): SourceHolder {
|
||||||
parent: ViewGroup): SourceHolder {
|
|
||||||
|
|
||||||
val view = inflater.inflate(layoutRes, parent, false)
|
|
||||||
return SourceHolder(view, adapter as CatalogueMainAdapter)
|
return SourceHolder(view, adapter as CatalogueMainAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ class CategoryAdapter(controller: CategoryController) :
|
|||||||
*/
|
*/
|
||||||
override fun clearSelection() {
|
override fun clearSelection() {
|
||||||
super.clearSelection()
|
super.clearSelection()
|
||||||
(0 until itemCount).forEach { getItem(it).isSelected = false }
|
(0 until itemCount).forEach { getItem(it)?.isSelected = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the active selections from the model.
|
* Clears the active selections from the model.
|
||||||
*/
|
*/
|
||||||
fun clearModelSelection() {
|
fun clearModelSelection() {
|
||||||
selectedPositions.forEach { getItem(it).isSelected = false }
|
selectedPositions.forEach { getItem(it)?.isSelected = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +37,7 @@ class CategoryAdapter(controller: CategoryController) :
|
|||||||
*/
|
*/
|
||||||
override fun toggleSelection(position: Int) {
|
override fun toggleSelection(position: Int) {
|
||||||
super.toggleSelection(position)
|
super.toggleSelection(position)
|
||||||
getItem(position).isSelected = isSelected(position)
|
getItem(position)?.isSelected = isSelected(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnItemReleaseListener {
|
interface OnItemReleaseListener {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.ui.category
|
package eu.kanade.tachiyomi.ui.category
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.support.design.widget.Snackbar
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.view.ActionMode
|
import android.support.v7.view.ActionMode
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
@ -8,11 +9,12 @@ import android.support.v7.widget.RecyclerView
|
|||||||
import android.view.*
|
import android.view.*
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
import com.jakewharton.rxbinding.view.clicks
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
|
import eu.davidea.flexibleadapter.helpers.UndoHelper
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.util.toast
|
import eu.kanade.tachiyomi.util.toast
|
||||||
import eu.kanade.tachiyomi.widget.UndoHelper
|
|
||||||
import kotlinx.android.synthetic.main.categories_controller.view.*
|
import kotlinx.android.synthetic.main.categories_controller.view.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +40,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
private var adapter: CategoryAdapter? = null
|
private var adapter: CategoryAdapter? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undo helper for deleting categories.
|
* Undo helper used for restoring a deleted category.
|
||||||
*/
|
*/
|
||||||
private var undoHelper: UndoHelper? = null
|
private var undoHelper: UndoHelper? = null
|
||||||
|
|
||||||
@ -79,6 +81,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
adapter?.isHandleDragEnabled = true
|
adapter?.isHandleDragEnabled = true
|
||||||
|
adapter?.isPermanentDelete = false
|
||||||
|
|
||||||
fab.clicks().subscribeUntilDestroy {
|
fab.clicks().subscribeUntilDestroy {
|
||||||
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
||||||
@ -93,7 +96,8 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*/
|
*/
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
super.onDestroyView(view)
|
super.onDestroyView(view)
|
||||||
undoHelper?.dismissNow() // confirm categories deletion if required
|
// Manually call callback to delete categories if required
|
||||||
|
undoHelper?.onDeleteConfirmed(Snackbar.Callback.DISMISS_EVENT_MANUAL)
|
||||||
undoHelper = null
|
undoHelper = null
|
||||||
actionMode = null
|
actionMode = null
|
||||||
adapter = null
|
adapter = null
|
||||||
@ -106,7 +110,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*/
|
*/
|
||||||
fun setCategories(categories: List<CategoryItem>) {
|
fun setCategories(categories: List<CategoryItem>) {
|
||||||
actionMode?.finish()
|
actionMode?.finish()
|
||||||
adapter?.updateDataSet(categories.toMutableList())
|
adapter?.updateDataSet(categories)
|
||||||
val selected = categories.filter { it.isSelected }
|
val selected = categories.filter { it.isSelected }
|
||||||
if (selected.isNotEmpty()) {
|
if (selected.isNotEmpty()) {
|
||||||
selected.forEach { onItemLongClick(categories.indexOf(it)) }
|
selected.forEach { onItemLongClick(categories.indexOf(it)) }
|
||||||
@ -126,7 +130,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
// Inflate menu.
|
// Inflate menu.
|
||||||
mode.menuInflater.inflate(R.menu.category_selection, menu)
|
mode.menuInflater.inflate(R.menu.category_selection, menu)
|
||||||
// Enable adapter multi selection.
|
// Enable adapter multi selection.
|
||||||
adapter?.mode = FlexibleAdapter.MODE_MULTI
|
adapter?.mode = SelectableAdapter.Mode.MULTI
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,26 +165,20 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
|
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_delete -> {
|
R.id.action_delete -> {
|
||||||
undoHelper = UndoHelper(adapter, this).apply {
|
undoHelper = UndoHelper(adapter, this)
|
||||||
withAction(UndoHelper.ACTION_REMOVE, object : UndoHelper.OnActionListener {
|
undoHelper?.start(adapter.selectedPositions, view!!,
|
||||||
override fun onPreAction(): Boolean {
|
R.string.snack_categories_deleted, R.string.action_undo, 3000)
|
||||||
adapter.clearModelSelection()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostAction() {
|
mode.finish()
|
||||||
mode.finish()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
remove(adapter.selectedPositions, view!!,
|
|
||||||
R.string.snack_categories_deleted, R.string.action_undo, 3000)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
R.id.action_edit -> {
|
R.id.action_edit -> {
|
||||||
// Edit selected category
|
// Edit selected category
|
||||||
if (adapter.selectedItemCount == 1) {
|
if (adapter.selectedItemCount == 1) {
|
||||||
val position = adapter.selectedPositions.first()
|
val position = adapter.selectedPositions.first()
|
||||||
editCategory(adapter.getItem(position).category)
|
val category = adapter.getItem(position)?.category
|
||||||
|
if (category != null) {
|
||||||
|
editCategory(category)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
@ -195,7 +193,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*/
|
*/
|
||||||
override fun onDestroyActionMode(mode: ActionMode) {
|
override fun onDestroyActionMode(mode: ActionMode) {
|
||||||
// Reset adapter to single selection
|
// Reset adapter to single selection
|
||||||
adapter?.mode = FlexibleAdapter.MODE_IDLE
|
adapter?.mode = SelectableAdapter.Mode.IDLE
|
||||||
adapter?.clearSelection()
|
adapter?.clearSelection()
|
||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
@ -260,7 +258,7 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*/
|
*/
|
||||||
override fun onItemReleased(position: Int) {
|
override fun onItemReleased(position: Int) {
|
||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
val categories = (0..adapter.itemCount-1).map { adapter.getItem(it).category }
|
val categories = (0 until adapter.itemCount).mapNotNull { adapter.getItem(it)?.category }
|
||||||
presenter.reorderCategories(categories)
|
presenter.reorderCategories(categories)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,18 +267,21 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*
|
*
|
||||||
* @param action The action performed.
|
* @param action The action performed.
|
||||||
*/
|
*/
|
||||||
override fun onUndoConfirmed(action: Int) {
|
override fun onActionCanceled(action: Int) {
|
||||||
adapter?.restoreDeletedItems()
|
adapter?.restoreDeletedItems()
|
||||||
|
undoHelper = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the time to restore the items expires.
|
* Called when the time to restore the items expires.
|
||||||
*
|
*
|
||||||
* @param action The action performed.
|
* @param action The action performed.
|
||||||
|
* @param event The event that triggered the action
|
||||||
*/
|
*/
|
||||||
override fun onDeleteConfirmed(action: Int) {
|
override fun onActionConfirmed(action: Int, event: Int) {
|
||||||
val adapter = adapter ?: return
|
val adapter = adapter ?: return
|
||||||
presenter.deleteCategories(adapter.deletedItems.map { it.category })
|
presenter.deleteCategories(adapter.deletedItems.map { it.category })
|
||||||
|
undoHelper = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.category
|
package eu.kanade.tachiyomi.ui.category
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category item for a recycler view.
|
* Category item for a recycler view.
|
||||||
@ -28,15 +26,11 @@ class CategoryItem(val category: Category) : AbstractFlexibleItem<CategoryHolder
|
|||||||
/**
|
/**
|
||||||
* Returns a new view holder for this item.
|
* Returns a new view holder for this item.
|
||||||
*
|
*
|
||||||
|
* @param view The view of this item.
|
||||||
* @param adapter The adapter of this item.
|
* @param adapter The adapter of this item.
|
||||||
* @param inflater The layout inflater for XML inflation.
|
|
||||||
* @param parent The container view.
|
|
||||||
*/
|
*/
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CategoryHolder {
|
||||||
inflater: LayoutInflater,
|
return CategoryHolder(view, adapter as CategoryAdapter)
|
||||||
parent: ViewGroup): CategoryHolder {
|
|
||||||
|
|
||||||
return CategoryHolder(parent.inflate(layoutRes), adapter as CategoryAdapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@ import android.support.v7.widget.RecyclerView
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
@ -103,9 +104,9 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
this.category = category
|
this.category = category
|
||||||
|
|
||||||
adapter.mode = if (controller.selectedMangas.isNotEmpty()) {
|
adapter.mode = if (controller.selectedMangas.isNotEmpty()) {
|
||||||
FlexibleAdapter.MODE_MULTI
|
SelectableAdapter.Mode.MULTI
|
||||||
} else {
|
} else {
|
||||||
FlexibleAdapter.MODE_SINGLE
|
SelectableAdapter.Mode.SINGLE
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions += controller.searchRelay
|
subscriptions += controller.searchRelay
|
||||||
@ -144,7 +145,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
// Update the category with its manga.
|
// Update the category with its manga.
|
||||||
adapter.setItems(mangaForCategory)
|
adapter.setItems(mangaForCategory)
|
||||||
|
|
||||||
if (adapter.mode == FlexibleAdapter.MODE_MULTI) {
|
if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||||
controller.selectedMangas.forEach { manga ->
|
controller.selectedMangas.forEach { manga ->
|
||||||
val position = adapter.indexOf(manga)
|
val position = adapter.indexOf(manga)
|
||||||
if (position != -1 && !adapter.isSelected(position)) {
|
if (position != -1 && !adapter.isSelected(position)) {
|
||||||
@ -164,19 +165,19 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
private fun onSelectionChanged(event: LibrarySelectionEvent) {
|
private fun onSelectionChanged(event: LibrarySelectionEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is LibrarySelectionEvent.Selected -> {
|
is LibrarySelectionEvent.Selected -> {
|
||||||
if (adapter.mode != FlexibleAdapter.MODE_MULTI) {
|
if (adapter.mode != SelectableAdapter.Mode.MULTI) {
|
||||||
adapter.mode = FlexibleAdapter.MODE_MULTI
|
adapter.mode = SelectableAdapter.Mode.MULTI
|
||||||
}
|
}
|
||||||
findAndToggleSelection(event.manga)
|
findAndToggleSelection(event.manga)
|
||||||
}
|
}
|
||||||
is LibrarySelectionEvent.Unselected -> {
|
is LibrarySelectionEvent.Unselected -> {
|
||||||
findAndToggleSelection(event.manga)
|
findAndToggleSelection(event.manga)
|
||||||
if (controller.selectedMangas.isEmpty()) {
|
if (controller.selectedMangas.isEmpty()) {
|
||||||
adapter.mode = FlexibleAdapter.MODE_SINGLE
|
adapter.mode = SelectableAdapter.Mode.SINGLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is LibrarySelectionEvent.Cleared -> {
|
is LibrarySelectionEvent.Cleared -> {
|
||||||
adapter.mode = FlexibleAdapter.MODE_SINGLE
|
adapter.mode = SelectableAdapter.Mode.SINGLE
|
||||||
adapter.clearSelection()
|
adapter.clearSelection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +205,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
override fun onItemClick(position: Int): Boolean {
|
override fun onItemClick(position: Int): Boolean {
|
||||||
// If the action mode is created and the position is valid, toggle the selection.
|
// If the action mode is created and the position is valid, toggle the selection.
|
||||||
val item = adapter.getItem(position) ?: return false
|
val item = adapter.getItem(position) ?: return false
|
||||||
if (adapter.mode == FlexibleAdapter.MODE_MULTI) {
|
if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||||
toggleSelection(position)
|
toggleSelection(position)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,33 +1,35 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFilterable
|
import eu.davidea.flexibleadapter.items.IFilterable
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
|
||||||
|
|
||||||
class LibraryItem(val manga: LibraryManga) : AbstractFlexibleItem<LibraryHolder>(), IFilterable {
|
class LibraryItem(val manga: LibraryManga, private val libraryAsList: Preference<Boolean>) :
|
||||||
|
AbstractFlexibleItem<LibraryHolder>(), IFilterable {
|
||||||
|
|
||||||
var downloadCount = -1
|
var downloadCount = -1
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return R.layout.catalogue_grid_item
|
return if (libraryAsList.getOrDefault())
|
||||||
|
R.layout.catalogue_list_item
|
||||||
|
else
|
||||||
|
R.layout.catalogue_grid_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): LibraryHolder {
|
||||||
inflater: LayoutInflater,
|
val parent = adapter.recyclerView
|
||||||
parent: ViewGroup): LibraryHolder {
|
|
||||||
|
|
||||||
return if (parent is AutofitRecyclerView) {
|
return if (parent is AutofitRecyclerView) {
|
||||||
val view = parent.inflate(R.layout.catalogue_grid_item).apply {
|
view.apply {
|
||||||
val coverHeight = parent.itemWidth / 3 * 4
|
val coverHeight = parent.itemWidth / 3 * 4
|
||||||
card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight)
|
card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight)
|
||||||
gradient.layoutParams = FrameLayout.LayoutParams(
|
gradient.layoutParams = FrameLayout.LayoutParams(
|
||||||
@ -35,7 +37,6 @@ class LibraryItem(val manga: LibraryManga) : AbstractFlexibleItem<LibraryHolder>
|
|||||||
}
|
}
|
||||||
LibraryGridHolder(view, adapter)
|
LibraryGridHolder(view, adapter)
|
||||||
} else {
|
} else {
|
||||||
val view = parent.inflate(R.layout.catalogue_list_item)
|
|
||||||
LibraryListHolder(view, adapter)
|
LibraryListHolder(view, adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,8 +290,11 @@ class LibraryPresenter(
|
|||||||
* value.
|
* value.
|
||||||
*/
|
*/
|
||||||
private fun getLibraryMangasObservable(): Observable<LibraryMap> {
|
private fun getLibraryMangasObservable(): Observable<LibraryMap> {
|
||||||
|
val libraryAsList = preferences.libraryAsList()
|
||||||
return db.getLibraryMangas().asRxObservable()
|
return db.getLibraryMangas().asRxObservable()
|
||||||
.map { list -> list.map(::LibraryItem).groupBy { it.manga.category } }
|
.map { list ->
|
||||||
|
list.map { LibraryItem(it, libraryAsList) }.groupBy { it.manga.category }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.manga.chapter
|
package eu.kanade.tachiyomi.ui.manga.chapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -27,11 +26,8 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) : AbstractFlexibleItem
|
|||||||
return R.layout.chapters_item
|
return R.layout.chapters_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): ChapterHolder {
|
||||||
inflater: LayoutInflater,
|
return ChapterHolder(view, adapter as ChaptersAdapter)
|
||||||
parent: ViewGroup): ChapterHolder {
|
|
||||||
|
|
||||||
return ChapterHolder(inflater.inflate(layoutRes, parent, false), adapter as ChaptersAdapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>,
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>,
|
||||||
|
@ -29,9 +29,9 @@ class ChaptersAdapter(
|
|||||||
|
|
||||||
val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
|
val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT)
|
||||||
|
|
||||||
override fun updateDataSet(items: List<ChapterItem>) {
|
override fun updateDataSet(items: List<ChapterItem>?) {
|
||||||
this.items = items
|
this.items = items ?: emptyList()
|
||||||
super.updateDataSet(items.toList())
|
super.updateDataSet(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indexOf(item: ChapterItem): Int {
|
fun indexOf(item: ChapterItem): Int {
|
||||||
|
@ -14,6 +14,7 @@ import android.view.*
|
|||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
import com.jakewharton.rxbinding.view.clicks
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
@ -79,9 +80,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
recycler.layoutManager = LinearLayoutManager(context)
|
recycler.layoutManager = LinearLayoutManager(context)
|
||||||
recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
|
recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
|
||||||
recycler.setHasFixedSize(true)
|
recycler.setHasFixedSize(true)
|
||||||
// TODO enable in a future commit
|
adapter?.fastScroller = view.fast_scroller
|
||||||
// adapter.setFastScroller(fast_scroller, context.getResourceColor(R.attr.colorAccent))
|
|
||||||
// adapter.toggleFastScroller()
|
|
||||||
|
|
||||||
swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
|
swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
|
||||||
|
|
||||||
@ -247,7 +246,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
override fun onItemClick(position: Int): Boolean {
|
override fun onItemClick(position: Int): Boolean {
|
||||||
val adapter = adapter ?: return false
|
val adapter = adapter ?: return false
|
||||||
val item = adapter.getItem(position) ?: return false
|
val item = adapter.getItem(position) ?: return false
|
||||||
if (actionMode != null && adapter.mode == FlexibleAdapter.MODE_MULTI) {
|
if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||||
toggleSelection(position)
|
toggleSelection(position)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -277,7 +276,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
|
|
||||||
fun getSelectedChapters(): List<ChapterItem> {
|
fun getSelectedChapters(): List<ChapterItem> {
|
||||||
val adapter = adapter ?: return emptyList()
|
val adapter = adapter ?: return emptyList()
|
||||||
return adapter.selectedPositions.map { adapter.getItem(it) }
|
return adapter.selectedPositions.mapNotNull { adapter.getItem(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createActionModeIfNeeded() {
|
fun createActionModeIfNeeded() {
|
||||||
@ -292,7 +291,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
|
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
mode.menuInflater.inflate(R.menu.chapter_selection, menu)
|
mode.menuInflater.inflate(R.menu.chapter_selection, menu)
|
||||||
adapter?.mode = FlexibleAdapter.MODE_MULTI
|
adapter?.mode = SelectableAdapter.Mode.MULTI
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +319,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyActionMode(mode: ActionMode) {
|
override fun onDestroyActionMode(mode: ActionMode) {
|
||||||
adapter?.mode = FlexibleAdapter.MODE_SINGLE
|
adapter?.mode = SelectableAdapter.Mode.SINGLE
|
||||||
adapter?.clearSelection()
|
adapter?.clearSelection()
|
||||||
selectedItems.clear()
|
selectedItems.clear()
|
||||||
actionMode = null
|
actionMode = null
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.ui.recent_updates
|
package eu.kanade.tachiyomi.ui.recent_updates
|
||||||
|
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||||
@ -17,8 +15,8 @@ class DateItem(val date: Date) : AbstractHeaderItem<DateItem.Holder>() {
|
|||||||
return R.layout.recent_chapters_section_item
|
return R.layout.recent_chapters_section_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder {
|
||||||
return Holder(inflater.inflate(layoutRes, parent, false), adapter)
|
return Holder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.recent_updates
|
package eu.kanade.tachiyomi.ui.recent_updates
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -27,11 +26,7 @@ class RecentChapterItem(val chapter: Chapter, val manga: Manga, header: DateItem
|
|||||||
return R.layout.recent_chapters_item
|
return R.layout.recent_chapters_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): RecentChapterHolder {
|
||||||
inflater: LayoutInflater,
|
|
||||||
parent: ViewGroup): RecentChapterHolder {
|
|
||||||
|
|
||||||
val view = inflater.inflate(layoutRes, parent, false)
|
|
||||||
return RecentChapterHolder(view , adapter as RecentChaptersAdapter)
|
return RecentChapterHolder(view , adapter as RecentChaptersAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
|||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.scrollStateChanges
|
import com.jakewharton.rxbinding.support.v7.widget.scrollStateChanges
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
@ -120,7 +121,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
|
|||||||
|
|
||||||
// Get item from position
|
// Get item from position
|
||||||
val item = adapter.getItem(position) as? RecentChapterItem ?: return false
|
val item = adapter.getItem(position) as? RecentChapterItem ?: return false
|
||||||
if (actionMode != null && adapter.mode == FlexibleAdapter.MODE_MULTI) {
|
if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||||
toggleSelection(position)
|
toggleSelection(position)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -175,7 +176,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
|
|||||||
*/
|
*/
|
||||||
fun onNextRecentChapters(chapters: List<IFlexible<*>>) {
|
fun onNextRecentChapters(chapters: List<IFlexible<*>>) {
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
adapter?.updateDataSet(chapters.toMutableList())
|
adapter?.updateDataSet(chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUpdateEmptyView(size: Int) {
|
override fun onUpdateEmptyView(size: Int) {
|
||||||
@ -295,7 +296,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
|
|||||||
*/
|
*/
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
mode.menuInflater.inflate(R.menu.chapter_recent_selection, menu)
|
mode.menuInflater.inflate(R.menu.chapter_recent_selection, menu)
|
||||||
adapter?.mode = FlexibleAdapter.MODE_MULTI
|
adapter?.mode = SelectableAdapter.Mode.MULTI
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +333,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(),
|
|||||||
* @param mode the ActionMode object
|
* @param mode the ActionMode object
|
||||||
*/
|
*/
|
||||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||||
adapter?.mode = FlexibleAdapter.MODE_IDLE
|
adapter?.mode = SelectableAdapter.Mode.IDLE
|
||||||
adapter?.clearSelection()
|
adapter?.clearSelection()
|
||||||
actionMode = null
|
actionMode = null
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.recently_read
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -77,7 +76,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
* @param mangaHistory list of manga history
|
* @param mangaHistory list of manga history
|
||||||
*/
|
*/
|
||||||
fun onNextManga(mangaHistory: List<RecentlyReadItem>) {
|
fun onNextManga(mangaHistory: List<RecentlyReadItem>) {
|
||||||
adapter?.updateDataSet(mangaHistory.toList())
|
adapter?.updateDataSet(mangaHistory)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUpdateEmptyView(size: Int) {
|
override fun onUpdateEmptyView(size: Int) {
|
||||||
@ -91,10 +90,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
|
|
||||||
override fun onResumeClick(position: Int) {
|
override fun onResumeClick(position: Int) {
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
val adapter = adapter ?: return
|
val (manga, chapter, _) = adapter?.getItem(position)?.mch ?: return
|
||||||
if (position == RecyclerView.NO_POSITION) return
|
|
||||||
|
|
||||||
val (manga, chapter, _) = adapter.getItem(position).mch
|
|
||||||
|
|
||||||
val nextChapter = presenter.getNextChapter(chapter, manga)
|
val nextChapter = presenter.getNextChapter(chapter, manga)
|
||||||
if (nextChapter != null) {
|
if (nextChapter != null) {
|
||||||
@ -106,11 +102,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onRemoveClick(position: Int) {
|
override fun onRemoveClick(position: Int) {
|
||||||
val adapter = adapter ?: return
|
val (manga, _, history) = adapter?.getItem(position)?.mch ?: return
|
||||||
if (position == RecyclerView.NO_POSITION) return
|
|
||||||
|
|
||||||
val (manga, _, history) = adapter.getItem(position).mch
|
|
||||||
|
|
||||||
RemoveHistoryDialog(this, manga, history).showDialog(router)
|
RemoveHistoryDialog(this, manga, history).showDialog(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package eu.kanade.tachiyomi.ui.recently_read
|
package eu.kanade.tachiyomi.ui.recently_read
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
||||||
import eu.kanade.tachiyomi.util.inflate
|
|
||||||
|
|
||||||
class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<RecentlyReadHolder>() {
|
class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<RecentlyReadHolder>() {
|
||||||
|
|
||||||
@ -14,11 +12,7 @@ class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<Rece
|
|||||||
return R.layout.recently_read_item
|
return R.layout.recently_read_item
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createViewHolder(adapter: FlexibleAdapter<*>,
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): RecentlyReadHolder {
|
||||||
inflater: LayoutInflater,
|
|
||||||
parent: ViewGroup): RecentlyReadHolder {
|
|
||||||
|
|
||||||
val view = parent.inflate(layoutRes)
|
|
||||||
return RecentlyReadHolder(view, adapter as RecentlyReadAdapter)
|
return RecentlyReadHolder(view, adapter as RecentlyReadAdapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,281 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 Davide Steduto
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package eu.kanade.tachiyomi.widget;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.support.annotation.ColorInt;
|
|
||||||
import android.support.annotation.IntDef;
|
|
||||||
import android.support.annotation.IntRange;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.StringRes;
|
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to simplify the Undo operation with FlexibleAdapter.
|
|
||||||
*
|
|
||||||
* @author Davide Steduto
|
|
||||||
* @since 30/04/2016
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public class UndoHelper extends Snackbar.Callback {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default undo-timeout of 5''.
|
|
||||||
*/
|
|
||||||
public static final int UNDO_TIMEOUT = 5000;
|
|
||||||
/**
|
|
||||||
* Indicates that the Confirmation Listener (Undo and Delete) will perform a deletion.
|
|
||||||
*/
|
|
||||||
public static final int ACTION_REMOVE = 0;
|
|
||||||
/**
|
|
||||||
* Indicates that the Confirmation Listener (Undo and Delete) will perform an update.
|
|
||||||
*/
|
|
||||||
public static final int ACTION_UPDATE = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Annotation interface for Undo actions.
|
|
||||||
*/
|
|
||||||
@IntDef({ACTION_REMOVE, ACTION_UPDATE})
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
public @interface Action {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
private int mAction = ACTION_REMOVE;
|
|
||||||
private List<Integer> mPositions = null;
|
|
||||||
private Object mPayload = null;
|
|
||||||
private FlexibleAdapter mAdapter;
|
|
||||||
private Snackbar mSnackbar = null;
|
|
||||||
private OnActionListener mActionListener;
|
|
||||||
private OnUndoListener mUndoListener;
|
|
||||||
private @ColorInt int mActionTextColor = Color.TRANSPARENT;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor.
|
|
||||||
* <p>By calling this constructor, {@link FlexibleAdapter#setPermanentDelete(boolean)}
|
|
||||||
* is set {@code false} automatically.
|
|
||||||
*
|
|
||||||
* @param adapter the instance of {@code FlexibleAdapter}
|
|
||||||
* @param undoListener the callback for the Undo and Delete confirmation
|
|
||||||
*/
|
|
||||||
public UndoHelper(FlexibleAdapter adapter, OnUndoListener undoListener) {
|
|
||||||
this.mAdapter = adapter;
|
|
||||||
this.mUndoListener = undoListener;
|
|
||||||
adapter.setPermanentDelete(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the payload to inform other linked items about the change in action.
|
|
||||||
*
|
|
||||||
* @param payload any non-null user object to notify the parent (the payload will be
|
|
||||||
* therefore passed to the bind method of the parent ViewHolder),
|
|
||||||
* pass null to <u>not</u> notify the parent
|
|
||||||
* @return this object, so it can be chained
|
|
||||||
*/
|
|
||||||
public UndoHelper withPayload(Object payload) {
|
|
||||||
this.mPayload = payload;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default {@link UndoHelper#ACTION_REMOVE} is performed.
|
|
||||||
*
|
|
||||||
* @param action the action, one of {@link UndoHelper#ACTION_REMOVE}, {@link UndoHelper#ACTION_UPDATE}
|
|
||||||
* @param actionListener the listener for the custom action to perform before the deletion
|
|
||||||
* @return this object, so it can be chained
|
|
||||||
*/
|
|
||||||
public UndoHelper withAction(@Action int action, @NonNull OnActionListener actionListener) {
|
|
||||||
this.mAction = action;
|
|
||||||
this.mActionListener = actionListener;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the text color of the action.
|
|
||||||
*
|
|
||||||
* @param color the color for the action button
|
|
||||||
* @return this object, so it can be chained
|
|
||||||
*/
|
|
||||||
public UndoHelper withActionTextColor(@ColorInt int color) {
|
|
||||||
this.mActionTextColor = color;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As {@link #remove(List, View, CharSequence, CharSequence, int)} but with String
|
|
||||||
* resources instead of CharSequence.
|
|
||||||
*/
|
|
||||||
public void remove(List<Integer> positions, @NonNull View mainView,
|
|
||||||
@StringRes int messageStringResId, @StringRes int actionStringResId,
|
|
||||||
@IntRange(from = -1) int undoTime) {
|
|
||||||
Context context = mainView.getContext();
|
|
||||||
remove(positions, mainView, context.getString(messageStringResId),
|
|
||||||
context.getString(actionStringResId), undoTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the action on the specified positions and displays a SnackBar to Undo
|
|
||||||
* the operation. To customize the UPDATE event, please set a custom listener with
|
|
||||||
* {@link #withAction(int, OnActionListener)} method.
|
|
||||||
* <p>By default the DELETE action will be performed.</p>
|
|
||||||
*
|
|
||||||
* @param positions the position to delete or update
|
|
||||||
* @param mainView the view to find a parent from
|
|
||||||
* @param message the text to show. Can be formatted text
|
|
||||||
* @param actionText the action text to display
|
|
||||||
* @param undoTime How long to display the message. Either {@link Snackbar#LENGTH_SHORT} or
|
|
||||||
* {@link Snackbar#LENGTH_LONG} or any custom Integer.
|
|
||||||
* @see #remove(List, View, int, int, int)
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("WrongConstant")
|
|
||||||
public void remove(List<Integer> positions, @NonNull View mainView,
|
|
||||||
CharSequence message, CharSequence actionText,
|
|
||||||
@IntRange(from = -1) int undoTime) {
|
|
||||||
this.mPositions = positions;
|
|
||||||
Snackbar snackbar;
|
|
||||||
if (!mAdapter.isPermanentDelete()) {
|
|
||||||
snackbar = Snackbar.make(mainView, message, undoTime > 0 ? undoTime + 400 : undoTime)
|
|
||||||
.setAction(actionText, new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (mUndoListener != null)
|
|
||||||
mUndoListener.onUndoConfirmed(mAction);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
snackbar = Snackbar.make(mainView, message, undoTime);
|
|
||||||
}
|
|
||||||
if (mActionTextColor != Color.TRANSPARENT) {
|
|
||||||
snackbar.setActionTextColor(mActionTextColor);
|
|
||||||
}
|
|
||||||
mSnackbar = snackbar;
|
|
||||||
snackbar.addCallback(this);
|
|
||||||
snackbar.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dismissNow() {
|
|
||||||
if (mSnackbar != null) {
|
|
||||||
mSnackbar.removeCallback(this);
|
|
||||||
mSnackbar.dismiss();
|
|
||||||
onDismissed(mSnackbar, Snackbar.Callback.DISMISS_EVENT_MANUAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onDismissed(Snackbar snackbar, int event) {
|
|
||||||
if (mAdapter.isPermanentDelete()) return;
|
|
||||||
switch (event) {
|
|
||||||
case DISMISS_EVENT_SWIPE:
|
|
||||||
case DISMISS_EVENT_MANUAL:
|
|
||||||
case DISMISS_EVENT_TIMEOUT:
|
|
||||||
if (mUndoListener != null)
|
|
||||||
mUndoListener.onDeleteConfirmed(mAction);
|
|
||||||
mAdapter.emptyBin();
|
|
||||||
mSnackbar = null;
|
|
||||||
case DISMISS_EVENT_CONSECUTIVE:
|
|
||||||
case DISMISS_EVENT_ACTION:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onShown(Snackbar snackbar) {
|
|
||||||
boolean consumed = false;
|
|
||||||
// Perform the action before deletion
|
|
||||||
if (mActionListener != null) consumed = mActionListener.onPreAction();
|
|
||||||
// Remove selected items from Adapter list after SnackBar is shown
|
|
||||||
if (!consumed) mAdapter.removeItems(mPositions, mPayload);
|
|
||||||
// Perform the action after the deletion
|
|
||||||
if (mActionListener != null) mActionListener.onPostAction();
|
|
||||||
// Here, we can notify the callback only in case of permanent deletion
|
|
||||||
if (mAdapter.isPermanentDelete() && mUndoListener != null)
|
|
||||||
mUndoListener.onDeleteConfirmed(mAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic implementation of {@link OnActionListener} interface.
|
|
||||||
* <p>Override the methods as your convenience.</p>
|
|
||||||
*/
|
|
||||||
public static class SimpleActionListener implements OnActionListener {
|
|
||||||
@Override
|
|
||||||
public boolean onPreAction() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPostAction() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnActionListener {
|
|
||||||
/**
|
|
||||||
* Performs the custom action before item deletion.
|
|
||||||
*
|
|
||||||
* @return true if action has been consumed and should stop the deletion, false to
|
|
||||||
* continue with the deletion
|
|
||||||
*/
|
|
||||||
boolean onPreAction();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs custom action After items deletion. Useful to finish the action mode and perform
|
|
||||||
* secondary custom actions.
|
|
||||||
*/
|
|
||||||
void onPostAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 30/04/2016
|
|
||||||
*/
|
|
||||||
public interface OnUndoListener {
|
|
||||||
/**
|
|
||||||
* Called when Undo event is triggered. Perform custom action after restoration.
|
|
||||||
* <p>Usually for a delete restoration you should call
|
|
||||||
* {@link FlexibleAdapter#restoreDeletedItems()}.</p>
|
|
||||||
*
|
|
||||||
* @param action one of {@link UndoHelper#ACTION_REMOVE}, {@link UndoHelper#ACTION_UPDATE}
|
|
||||||
*/
|
|
||||||
void onUndoConfirmed(int action);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when Undo timeout is over and action must be committed in the user Database.
|
|
||||||
* <p>Due to Java Generic, it's too complicated and not well manageable if we pass the
|
|
||||||
* List<T> object.<br/>
|
|
||||||
* So, to get deleted items, use {@link FlexibleAdapter#getDeletedItems()} from the
|
|
||||||
* implementation of this method.</p>
|
|
||||||
*
|
|
||||||
* @param action one of {@link UndoHelper#ACTION_REMOVE}, {@link UndoHelper#ACTION_UPDATE}
|
|
||||||
*/
|
|
||||||
void onDeleteConfirmed(int action);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -43,7 +43,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
android:visibility="gone"
|
app:fastScrollerBubbleEnabled="false"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
Loading…
Reference in New Issue
Block a user