mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Update flexible adapter. Show fast scroller in chapters screen
This commit is contained in:
		| @@ -44,7 +44,7 @@ open class CatalogueController(bundle: Bundle) : | ||||
|         SecondaryDrawerController, | ||||
|         FlexibleAdapter.OnItemClickListener, | ||||
|         FlexibleAdapter.OnItemLongClickListener, | ||||
|         FlexibleAdapter.EndlessScrollListener<ProgressItem>, | ||||
|         FlexibleAdapter.EndlessScrollListener, | ||||
|         ChangeMangaCategoriesDialog.Listener { | ||||
|  | ||||
|     constructor(source: CatalogueSource) : this(Bundle().apply { | ||||
|   | ||||
| @@ -1,39 +1,40 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue | ||||
|  | ||||
| import android.view.Gravity | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.widget.FrameLayout | ||||
| import com.f2prateek.rx.preferences.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| 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 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 { | ||||
|         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<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): CatalogueHolder { | ||||
|  | ||||
|         if (parent is AutofitRecyclerView) { | ||||
|             val view = parent.inflate(R.layout.catalogue_grid_item).apply { | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueHolder { | ||||
|         val parent = adapter.recyclerView | ||||
|         return if (parent is AutofitRecyclerView) { | ||||
|             view.apply { | ||||
|                 card.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 4) | ||||
|                 gradient.layoutParams = FrameLayout.LayoutParams( | ||||
|                         MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM) | ||||
|             } | ||||
|             return CatalogueGridHolder(view, adapter) | ||||
|             CatalogueGridHolder(view, adapter) | ||||
|         } else { | ||||
|             val view = parent.inflate(R.layout.catalogue_list_item) | ||||
|             return CatalogueListHolder(view, adapter) | ||||
|             CatalogueListHolder(view, adapter) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,7 @@ class CatalogueNavigationView @JvmOverloads constructor(context: Context, attrs: | ||||
|     } | ||||
|  | ||||
|     fun setFilters(items: List<IFlexible<*>>) { | ||||
|         adapter.updateDataSet(items.toMutableList()) | ||||
|         adapter.updateDataSet(items) | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -131,13 +131,15 @@ open class CataloguePresenter( | ||||
|  | ||||
|         val sourceId = source.id | ||||
|  | ||||
|         val catalogueAsList = prefs.catalogueAsList() | ||||
|  | ||||
|         // Prepare the pager. | ||||
|         pagerSubscription?.let { remove(it) } | ||||
|         pagerSubscription = pager.results() | ||||
|                 .observeOn(Schedulers.io()) | ||||
|                 .map { it.first to it.second.map { networkToLocalManga(it, sourceId) } } | ||||
|                 .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()) | ||||
|                 .subscribeReplay({ view, (page, mangas) -> | ||||
|                     view.onAddPage(page, mangas) | ||||
|   | ||||
| @@ -1,30 +1,27 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.ProgressBar | ||||
| import android.widget.TextView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.davidea.flexibleadapter.items.IFlexible | ||||
| import eu.davidea.viewholders.FlexibleViewHolder | ||||
| import eu.kanade.tachiyomi.R | ||||
|  | ||||
|  | ||||
| class ProgressItem : AbstractFlexibleItem<ProgressItem.Holder>() { | ||||
|  | ||||
|     var loadMore = true | ||||
|     private var loadMore = true | ||||
|  | ||||
|     override fun getLayoutRes(): Int { | ||||
|         return R.layout.catalogue_progress_item | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         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.progressMessage.visibility = View.GONE | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.CheckBox | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| 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 | ||||
| @@ -19,8 +17,12 @@ class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<Grou | ||||
|         return R.layout.navigation_view_group | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun getItemViewType(): Int { | ||||
|         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?>?) { | ||||
|   | ||||
| @@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.annotation.SuppressLint | ||||
| import android.support.design.R | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.TextView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.ArrayAdapter | ||||
| import android.widget.Spinner | ||||
| import android.widget.TextView | ||||
| @@ -19,8 +17,8 @@ open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<Selec | ||||
|         return R.layout.navigation_view_spinner | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     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.support.design.R | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractHeaderItem | ||||
| import eu.davidea.viewholders.FlexibleViewHolder | ||||
| @@ -17,8 +15,8 @@ class SeparatorItem(val filter: Filter.Separator) : AbstractHeaderItem<Separator | ||||
|         return R.layout.design_navigation_item_separator | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) { | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem | ||||
| 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<*, *>>() { | ||||
|  | ||||
|     // Use an id instead of the layout res to allow to reuse the layout. | ||||
|     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 { | ||||
|         return Holder(inflater.inflate(R.layout.navigation_view_group, parent, false), adapter) | ||||
|     override fun getItemViewType(): Int { | ||||
|         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?>?) { | ||||
|   | ||||
| @@ -2,9 +2,7 @@ package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.support.graphics.drawable.VectorDrawableCompat | ||||
| import android.support.v4.content.ContextCompat | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.CheckedTextView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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) { | ||||
|  | ||||
|     // Use an id instead of the layout res to allow to reuse the layout. | ||||
|     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 { | ||||
|         return Holder(inflater.inflate(R.layout.navigation_view_checkedtext, parent, false), adapter) | ||||
|     override fun getItemViewType(): Int { | ||||
|         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?>?) { | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.filter | ||||
|  | ||||
| import android.support.design.widget.TextInputLayout | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.EditText | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     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.graphics.drawable.VectorDrawableCompat | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.CheckedTextView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup?): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun getItemViewType(): Int { | ||||
|         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?>?) { | ||||
|   | ||||
| @@ -1,12 +1,10 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.global_search | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| import eu.kanade.tachiyomi.util.inflate | ||||
|  | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): CatalogueSearchCardHolder { | ||||
|         return CatalogueSearchCardHolder(parent.inflate(layoutRes), adapter as CatalogueSearchCardAdapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueSearchCardHolder { | ||||
|         return CatalogueSearchCardHolder(view, adapter as CatalogueSearchCardAdapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: CatalogueSearchCardHolder, | ||||
|   | ||||
| @@ -1,12 +1,10 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.global_search | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.source.CatalogueSource | ||||
| import eu.kanade.tachiyomi.util.inflate | ||||
|  | ||||
| /** | ||||
|  * Item that contains search result information. | ||||
| @@ -30,9 +28,8 @@ class CatalogueSearchItem(val source: CatalogueSource, val results: List<Catalog | ||||
|      * | ||||
|      * @return holder of view. | ||||
|      */ | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): CatalogueSearchHolder { | ||||
|         return CatalogueSearchHolder(parent.inflate(layoutRes), adapter as CatalogueSearchAdapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CatalogueSearchHolder { | ||||
|         return CatalogueSearchHolder(view, adapter as CatalogueSearchAdapter) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -221,7 +221,7 @@ class CatalogueMainController : NucleusController<CatalogueMainPresenter>(), | ||||
|      * Called to update adapter containing sources. | ||||
|      */ | ||||
|     fun setSources(sources: List<IFlexible<*>>) { | ||||
|         adapter?.updateDataSet(sources.toMutableList()) | ||||
|         adapter?.updateDataSet(sources) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.main | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractHeaderItem | ||||
| 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. | ||||
|      */ | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): LangHolder { | ||||
|  | ||||
|         return LangHolder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): LangHolder { | ||||
|         return LangHolder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.catalogue.main | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractSectionableItem | ||||
| 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. | ||||
|      */ | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): SourceHolder { | ||||
|  | ||||
|         val view = inflater.inflate(layoutRes, parent, false) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): SourceHolder { | ||||
|         return SourceHolder(view, adapter as CatalogueMainAdapter) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -20,14 +20,14 @@ class CategoryAdapter(controller: CategoryController) : | ||||
|      */ | ||||
|     override fun 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. | ||||
|      */ | ||||
|     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) { | ||||
|         super.toggleSelection(position) | ||||
|         getItem(position).isSelected = isSelected(position) | ||||
|         getItem(position)?.isSelected = isSelected(position) | ||||
|     } | ||||
|  | ||||
|     interface OnItemReleaseListener { | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package eu.kanade.tachiyomi.ui.category | ||||
|  | ||||
| import android.os.Bundle | ||||
| import android.support.design.widget.Snackbar | ||||
| import android.support.v7.app.AppCompatActivity | ||||
| import android.support.v7.view.ActionMode | ||||
| import android.support.v7.widget.LinearLayoutManager | ||||
| @@ -8,11 +9,12 @@ import android.support.v7.widget.RecyclerView | ||||
| import android.view.* | ||||
| import com.jakewharton.rxbinding.view.clicks | ||||
| 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.data.database.models.Category | ||||
| import eu.kanade.tachiyomi.ui.base.controller.NucleusController | ||||
| import eu.kanade.tachiyomi.util.toast | ||||
| import eu.kanade.tachiyomi.widget.UndoHelper | ||||
| import kotlinx.android.synthetic.main.categories_controller.view.* | ||||
|  | ||||
| /** | ||||
| @@ -38,7 +40,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|     private var adapter: CategoryAdapter? = null | ||||
|  | ||||
|     /** | ||||
|      * Undo helper for deleting categories. | ||||
|      * Undo helper used for restoring a deleted category. | ||||
|      */ | ||||
|     private var undoHelper: UndoHelper? = null | ||||
|  | ||||
| @@ -79,6 +81,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|             recycler.setHasFixedSize(true) | ||||
|             recycler.adapter = adapter | ||||
|             adapter?.isHandleDragEnabled = true | ||||
|             adapter?.isPermanentDelete = false | ||||
|  | ||||
|             fab.clicks().subscribeUntilDestroy { | ||||
|                 CategoryCreateDialog(this@CategoryController).showDialog(router, null) | ||||
| @@ -93,7 +96,8 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|      */ | ||||
|     override fun onDestroyView(view: 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 | ||||
|         actionMode = null | ||||
|         adapter = null | ||||
| @@ -106,7 +110,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|      */ | ||||
|     fun setCategories(categories: List<CategoryItem>) { | ||||
|         actionMode?.finish() | ||||
|         adapter?.updateDataSet(categories.toMutableList()) | ||||
|         adapter?.updateDataSet(categories) | ||||
|         val selected = categories.filter { it.isSelected } | ||||
|         if (selected.isNotEmpty()) { | ||||
|             selected.forEach { onItemLongClick(categories.indexOf(it)) } | ||||
| @@ -126,7 +130,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|         // Inflate menu. | ||||
|         mode.menuInflater.inflate(R.menu.category_selection, menu) | ||||
|         // Enable adapter multi selection. | ||||
|         adapter?.mode = FlexibleAdapter.MODE_MULTI | ||||
|         adapter?.mode = SelectableAdapter.Mode.MULTI | ||||
|         return true | ||||
|     } | ||||
|  | ||||
| @@ -161,26 +165,20 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|  | ||||
|         when (item.itemId) { | ||||
|             R.id.action_delete -> { | ||||
|                 undoHelper = UndoHelper(adapter, this).apply { | ||||
|                     withAction(UndoHelper.ACTION_REMOVE, object : UndoHelper.OnActionListener { | ||||
|                         override fun onPreAction(): Boolean { | ||||
|                             adapter.clearModelSelection() | ||||
|                             return false | ||||
|                         } | ||||
|                 undoHelper = UndoHelper(adapter, this) | ||||
|                 undoHelper?.start(adapter.selectedPositions, view!!, | ||||
|                                 R.string.snack_categories_deleted, R.string.action_undo, 3000) | ||||
|  | ||||
|                         override fun onPostAction() { | ||||
|                             mode.finish() | ||||
|                         } | ||||
|                     }) | ||||
|                     remove(adapter.selectedPositions, view!!, | ||||
|                             R.string.snack_categories_deleted, R.string.action_undo, 3000) | ||||
|                 } | ||||
|                 mode.finish() | ||||
|             } | ||||
|             R.id.action_edit -> { | ||||
|                 // Edit selected category | ||||
|                 if (adapter.selectedItemCount == 1) { | ||||
|                     val position = adapter.selectedPositions.first() | ||||
|                     editCategory(adapter.getItem(position).category) | ||||
|                     val category = adapter.getItem(position)?.category | ||||
|                     if (category != null) { | ||||
|                         editCategory(category) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else -> return false | ||||
| @@ -195,7 +193,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|      */ | ||||
|     override fun onDestroyActionMode(mode: ActionMode) { | ||||
|         // Reset adapter to single selection | ||||
|         adapter?.mode = FlexibleAdapter.MODE_IDLE | ||||
|         adapter?.mode = SelectableAdapter.Mode.IDLE | ||||
|         adapter?.clearSelection() | ||||
|         actionMode = null | ||||
|     } | ||||
| @@ -260,7 +258,7 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|      */ | ||||
|     override fun onItemReleased(position: Int) { | ||||
|         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) | ||||
|     } | ||||
|  | ||||
| @@ -269,18 +267,21 @@ class CategoryController : NucleusController<CategoryPresenter>(), | ||||
|      * | ||||
|      * @param action The action performed. | ||||
|      */ | ||||
|     override fun onUndoConfirmed(action: Int) { | ||||
|     override fun onActionCanceled(action: Int) { | ||||
|         adapter?.restoreDeletedItems() | ||||
|         undoHelper = null | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Called when the time to restore the items expires. | ||||
|      * | ||||
|      * @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 | ||||
|         presenter.deleteCategories(adapter.deletedItems.map { it.category }) | ||||
|         undoHelper = null | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,12 +1,10 @@ | ||||
| package eu.kanade.tachiyomi.ui.category | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Category | ||||
| import eu.kanade.tachiyomi.util.inflate | ||||
|  | ||||
| /** | ||||
|  * 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. | ||||
|      * | ||||
|      * @param view The view 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<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): CategoryHolder { | ||||
|  | ||||
|         return CategoryHolder(parent.inflate(layoutRes), adapter as CategoryAdapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): CategoryHolder { | ||||
|         return CategoryHolder(view, adapter as CategoryAdapter) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import android.support.v7.widget.RecyclerView | ||||
| import android.util.AttributeSet | ||||
| import android.widget.FrameLayout | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.SelectableAdapter | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Category | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| @@ -103,9 +104,9 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|         this.category = category | ||||
|  | ||||
|         adapter.mode = if (controller.selectedMangas.isNotEmpty()) { | ||||
|             FlexibleAdapter.MODE_MULTI | ||||
|             SelectableAdapter.Mode.MULTI | ||||
|         } else { | ||||
|             FlexibleAdapter.MODE_SINGLE | ||||
|             SelectableAdapter.Mode.SINGLE | ||||
|         } | ||||
|  | ||||
|         subscriptions += controller.searchRelay | ||||
| @@ -144,7 +145,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|         // Update the category with its manga. | ||||
|         adapter.setItems(mangaForCategory) | ||||
|  | ||||
|         if (adapter.mode == FlexibleAdapter.MODE_MULTI) { | ||||
|         if (adapter.mode == SelectableAdapter.Mode.MULTI) { | ||||
|             controller.selectedMangas.forEach { manga -> | ||||
|                 val position = adapter.indexOf(manga) | ||||
|                 if (position != -1 && !adapter.isSelected(position)) { | ||||
| @@ -164,19 +165,19 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|     private fun onSelectionChanged(event: LibrarySelectionEvent) { | ||||
|         when (event) { | ||||
|             is LibrarySelectionEvent.Selected -> { | ||||
|                 if (adapter.mode != FlexibleAdapter.MODE_MULTI) { | ||||
|                     adapter.mode = FlexibleAdapter.MODE_MULTI | ||||
|                 if (adapter.mode != SelectableAdapter.Mode.MULTI) { | ||||
|                     adapter.mode = SelectableAdapter.Mode.MULTI | ||||
|                 } | ||||
|                 findAndToggleSelection(event.manga) | ||||
|             } | ||||
|             is LibrarySelectionEvent.Unselected -> { | ||||
|                 findAndToggleSelection(event.manga) | ||||
|                 if (controller.selectedMangas.isEmpty()) { | ||||
|                     adapter.mode = FlexibleAdapter.MODE_SINGLE | ||||
|                     adapter.mode = SelectableAdapter.Mode.SINGLE | ||||
|                 } | ||||
|             } | ||||
|             is LibrarySelectionEvent.Cleared -> { | ||||
|                 adapter.mode = FlexibleAdapter.MODE_SINGLE | ||||
|                 adapter.mode = SelectableAdapter.Mode.SINGLE | ||||
|                 adapter.clearSelection() | ||||
|             } | ||||
|         } | ||||
| @@ -204,7 +205,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|     override fun onItemClick(position: Int): Boolean { | ||||
|         // If the action mode is created and the position is valid, toggle the selection. | ||||
|         val item = adapter.getItem(position) ?: return false | ||||
|         if (adapter.mode == FlexibleAdapter.MODE_MULTI) { | ||||
|         if (adapter.mode == SelectableAdapter.Mode.MULTI) { | ||||
|             toggleSelection(position) | ||||
|             return true | ||||
|         } else { | ||||
|   | ||||
| @@ -1,33 +1,35 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.view.Gravity | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.widget.FrameLayout | ||||
| import com.f2prateek.rx.preferences.Preference | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.davidea.flexibleadapter.items.IFilterable | ||||
| import eu.kanade.tachiyomi.R | ||||
| 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 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 | ||||
|  | ||||
|     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<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): LibraryHolder { | ||||
|  | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): LibraryHolder { | ||||
|         val parent = adapter.recyclerView | ||||
|         return if (parent is AutofitRecyclerView) { | ||||
|             val view = parent.inflate(R.layout.catalogue_grid_item).apply { | ||||
|             view.apply { | ||||
|                 val coverHeight = parent.itemWidth / 3 * 4 | ||||
|                 card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) | ||||
|                 gradient.layoutParams = FrameLayout.LayoutParams( | ||||
| @@ -35,7 +37,6 @@ class LibraryItem(val manga: LibraryManga) : AbstractFlexibleItem<LibraryHolder> | ||||
|             } | ||||
|             LibraryGridHolder(view, adapter) | ||||
|         } else { | ||||
|             val view = parent.inflate(R.layout.catalogue_list_item) | ||||
|             LibraryListHolder(view, adapter) | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -290,8 +290,11 @@ class LibraryPresenter( | ||||
|      * value. | ||||
|      */ | ||||
|     private fun getLibraryMangasObservable(): Observable<LibraryMap> { | ||||
|         val libraryAsList = preferences.libraryAsList() | ||||
|         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 | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| @@ -27,11 +26,8 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) : AbstractFlexibleItem | ||||
|         return R.layout.chapters_item | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): ChapterHolder { | ||||
|  | ||||
|         return ChapterHolder(inflater.inflate(layoutRes, parent, false), adapter as ChaptersAdapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): ChapterHolder { | ||||
|         return ChapterHolder(view, adapter as ChaptersAdapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, | ||||
|   | ||||
| @@ -29,9 +29,9 @@ class ChaptersAdapter( | ||||
|  | ||||
|     val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.SHORT) | ||||
|  | ||||
|     override fun updateDataSet(items: List<ChapterItem>) { | ||||
|         this.items = items | ||||
|         super.updateDataSet(items.toList()) | ||||
|     override fun updateDataSet(items: List<ChapterItem>?) { | ||||
|         this.items = items ?: emptyList() | ||||
|         super.updateDataSet(items) | ||||
|     } | ||||
|  | ||||
|     fun indexOf(item: ChapterItem): Int { | ||||
|   | ||||
| @@ -14,6 +14,7 @@ import android.view.* | ||||
| import com.jakewharton.rxbinding.support.v4.widget.refreshes | ||||
| import com.jakewharton.rxbinding.view.clicks | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.SelectableAdapter | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.Chapter | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga | ||||
| @@ -79,9 +80,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|             recycler.layoutManager = LinearLayoutManager(context) | ||||
|             recycler.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) | ||||
|             recycler.setHasFixedSize(true) | ||||
|             // TODO enable in a future commit | ||||
| //             adapter.setFastScroller(fast_scroller, context.getResourceColor(R.attr.colorAccent)) | ||||
| //             adapter.toggleFastScroller() | ||||
|             adapter?.fastScroller = view.fast_scroller | ||||
|  | ||||
|             swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() } | ||||
|  | ||||
| @@ -247,7 +246,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|     override fun onItemClick(position: Int): Boolean { | ||||
|         val adapter = adapter ?: 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) | ||||
|             return true | ||||
|         } else { | ||||
| @@ -277,7 +276,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|  | ||||
|     fun getSelectedChapters(): List<ChapterItem> { | ||||
|         val adapter = adapter ?: return emptyList() | ||||
|         return adapter.selectedPositions.map { adapter.getItem(it) } | ||||
|         return adapter.selectedPositions.mapNotNull { adapter.getItem(it) } | ||||
|     } | ||||
|  | ||||
|     fun createActionModeIfNeeded() { | ||||
| @@ -292,7 +291,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|  | ||||
|     override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { | ||||
|         mode.menuInflater.inflate(R.menu.chapter_selection, menu) | ||||
|         adapter?.mode = FlexibleAdapter.MODE_MULTI | ||||
|         adapter?.mode = SelectableAdapter.Mode.MULTI | ||||
|         return true | ||||
|     } | ||||
|  | ||||
| @@ -320,7 +319,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyActionMode(mode: ActionMode) { | ||||
|         adapter?.mode = FlexibleAdapter.MODE_SINGLE | ||||
|         adapter?.mode = SelectableAdapter.Mode.SINGLE | ||||
|         adapter?.clearSelection() | ||||
|         selectedItems.clear() | ||||
|         actionMode = null | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| package eu.kanade.tachiyomi.ui.recent_updates | ||||
|  | ||||
| import android.text.format.DateUtils | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.TextView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, inflater: LayoutInflater, parent: ViewGroup): Holder { | ||||
|         return Holder(inflater.inflate(layoutRes, parent, false), adapter) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): Holder { | ||||
|         return Holder(view, adapter) | ||||
|     } | ||||
|  | ||||
|     override fun bindViewHolder(adapter: FlexibleAdapter<*>, holder: Holder, position: Int, payloads: List<Any?>?) { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package eu.kanade.tachiyomi.ui.recent_updates | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractSectionableItem | ||||
| 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 | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): RecentChapterHolder { | ||||
|  | ||||
|         val view = inflater.inflate(layoutRes, parent, false) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): RecentChapterHolder { | ||||
|         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.v7.widget.scrollStateChanges | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.SelectableAdapter | ||||
| import eu.davidea.flexibleadapter.items.IFlexible | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.download.model.Download | ||||
| @@ -120,7 +121,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(), | ||||
|  | ||||
|         // Get item from position | ||||
|         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) | ||||
|             return true | ||||
|         } else { | ||||
| @@ -175,7 +176,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(), | ||||
|      */ | ||||
|     fun onNextRecentChapters(chapters: List<IFlexible<*>>) { | ||||
|         destroyActionModeIfNeeded() | ||||
|         adapter?.updateDataSet(chapters.toMutableList()) | ||||
|         adapter?.updateDataSet(chapters) | ||||
|     } | ||||
|  | ||||
|     override fun onUpdateEmptyView(size: Int) { | ||||
| @@ -295,7 +296,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(), | ||||
|      */ | ||||
|     override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { | ||||
|         mode.menuInflater.inflate(R.menu.chapter_recent_selection, menu) | ||||
|         adapter?.mode = FlexibleAdapter.MODE_MULTI | ||||
|         adapter?.mode = SelectableAdapter.Mode.MULTI | ||||
|         return true | ||||
|     } | ||||
|  | ||||
| @@ -332,7 +333,7 @@ class RecentChaptersController : NucleusController<RecentChaptersPresenter>(), | ||||
|      * @param mode the ActionMode object | ||||
|      */ | ||||
|     override fun onDestroyActionMode(mode: ActionMode?) { | ||||
|         adapter?.mode = FlexibleAdapter.MODE_IDLE | ||||
|         adapter?.mode = SelectableAdapter.Mode.IDLE | ||||
|         adapter?.clearSelection() | ||||
|         actionMode = null | ||||
|     } | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.recently_read | ||||
|  | ||||
| import android.os.Bundle | ||||
| import android.support.v7.widget.LinearLayoutManager | ||||
| import android.support.v7.widget.RecyclerView | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| @@ -77,7 +76,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(), | ||||
|      * @param mangaHistory list of manga history | ||||
|      */ | ||||
|     fun onNextManga(mangaHistory: List<RecentlyReadItem>) { | ||||
|         adapter?.updateDataSet(mangaHistory.toList()) | ||||
|         adapter?.updateDataSet(mangaHistory) | ||||
|     } | ||||
|  | ||||
|     override fun onUpdateEmptyView(size: Int) { | ||||
| @@ -91,10 +90,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(), | ||||
|  | ||||
|     override fun onResumeClick(position: Int) { | ||||
|         val activity = activity ?: return | ||||
|         val adapter = adapter ?: return | ||||
|         if (position == RecyclerView.NO_POSITION) return | ||||
|  | ||||
|         val (manga, chapter, _) = adapter.getItem(position).mch | ||||
|         val (manga, chapter, _) = adapter?.getItem(position)?.mch ?: return | ||||
|  | ||||
|         val nextChapter = presenter.getNextChapter(chapter, manga) | ||||
|         if (nextChapter != null) { | ||||
| @@ -106,11 +102,7 @@ class RecentlyReadController : NucleusController<RecentlyReadPresenter>(), | ||||
|     } | ||||
|  | ||||
|     override fun onRemoveClick(position: Int) { | ||||
|         val adapter = adapter ?: return | ||||
|         if (position == RecyclerView.NO_POSITION) return | ||||
|  | ||||
|         val (manga, _, history) = adapter.getItem(position).mch | ||||
|  | ||||
|         val (manga, _, history) = adapter?.getItem(position)?.mch ?: return | ||||
|         RemoveHistoryDialog(this, manga, history).showDialog(router) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,10 @@ | ||||
| package eu.kanade.tachiyomi.ui.recently_read | ||||
|  | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.View | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.items.AbstractFlexibleItem | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory | ||||
| import eu.kanade.tachiyomi.util.inflate | ||||
|  | ||||
| class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<RecentlyReadHolder>() { | ||||
|  | ||||
| @@ -14,11 +12,7 @@ class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<Rece | ||||
|         return R.layout.recently_read_item | ||||
|     } | ||||
|  | ||||
|     override fun createViewHolder(adapter: FlexibleAdapter<*>, | ||||
|                                   inflater: LayoutInflater, | ||||
|                                   parent: ViewGroup): RecentlyReadHolder { | ||||
|  | ||||
|         val view = parent.inflate(layoutRes) | ||||
|     override fun createViewHolder(view: View, adapter: FlexibleAdapter<*>): RecentlyReadHolder { | ||||
|         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); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user