mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Implement long hold selection for Manga Chapters and library
Co-Authored-By: zhuoyang <zhuoyang@users.noreply.github.com> Co-Authored-By: Jays2Kings <Jays2Kings@users.noreply.github.com>
This commit is contained in:
		| @@ -1,11 +1,11 @@ | ||||
| package eu.kanade.tachiyomi.ui.library | ||||
|  | ||||
| import android.content.Context | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import android.util.AttributeSet | ||||
| import android.view.View | ||||
| import android.widget.FrameLayout | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import eu.davidea.flexibleadapter.FlexibleAdapter | ||||
| import eu.davidea.flexibleadapter.SelectableAdapter | ||||
| import eu.kanade.tachiyomi.R | ||||
| @@ -18,8 +18,8 @@ import eu.kanade.tachiyomi.util.inflate | ||||
| import eu.kanade.tachiyomi.util.plusAssign | ||||
| import eu.kanade.tachiyomi.util.toast | ||||
| import eu.kanade.tachiyomi.widget.AutofitRecyclerView | ||||
| import kotlinx.android.synthetic.main.chapters_controller.fast_scroller | ||||
| import kotlinx.android.synthetic.main.library_category.view.* | ||||
| import kotlinx.android.synthetic.main.library_category.view.fast_scroller | ||||
| import kotlinx.android.synthetic.main.library_category.view.swipe_refresh | ||||
| import rx.subscriptions.CompositeSubscription | ||||
| import uy.kohesive.injekt.injectLazy | ||||
|  | ||||
| @@ -62,6 +62,8 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|      */ | ||||
|     private var subscriptions = CompositeSubscription() | ||||
|  | ||||
|     private var lastClickPosition = -1 | ||||
|  | ||||
|     fun onCreate(controller: LibraryController) { | ||||
|         this.controller = controller | ||||
|  | ||||
| @@ -174,6 +176,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|             } | ||||
|             is LibrarySelectionEvent.Unselected -> { | ||||
|                 findAndToggleSelection(event.manga) | ||||
|                 if (adapter.indexOf(event.manga) != -1) lastClickPosition = -1 | ||||
|                 if (controller.selectedMangas.isEmpty()) { | ||||
|                     adapter.mode = SelectableAdapter.Mode.SINGLE | ||||
|                 } | ||||
| @@ -181,6 +184,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|             is LibrarySelectionEvent.Cleared -> { | ||||
|                 adapter.mode = SelectableAdapter.Mode.SINGLE | ||||
|                 adapter.clearSelection() | ||||
|                 lastClickPosition = -1 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -204,10 +208,11 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|      * @param position the position of the element clicked. | ||||
|      * @return true if the item should be selected, false otherwise. | ||||
|      */ | ||||
|     override fun onItemClick(view: View, position: Int): Boolean { | ||||
|     override fun onItemClick(view: View?, 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 == SelectableAdapter.Mode.MULTI) { | ||||
|             lastClickPosition = position | ||||
|             toggleSelection(position) | ||||
|             return true | ||||
|         } else { | ||||
| @@ -223,7 +228,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|      */ | ||||
|     override fun onItemLongClick(position: Int) { | ||||
|         controller.createActionModeIfNeeded() | ||||
|         toggleSelection(position) | ||||
|         when { | ||||
|             lastClickPosition == -1 -> setSelection(position) | ||||
|             lastClickPosition > position -> for (i in position until lastClickPosition) | ||||
|                 setSelection(i) | ||||
|             lastClickPosition < position -> for (i in lastClickPosition + 1..position) | ||||
|                 setSelection(i) | ||||
|             else -> setSelection(position) | ||||
|         } | ||||
|         lastClickPosition = position | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -247,4 +260,17 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att | ||||
|         controller.invalidateActionMode() | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Tells the presenter to set the selection for the given position. | ||||
|      * | ||||
|      * @param position the position to toggle. | ||||
|      */ | ||||
|     private fun setSelection(position: Int) { | ||||
|         val item = adapter.getItem(position) ?: return | ||||
|  | ||||
|         controller.setSelection(item.manga, true) | ||||
|         controller.invalidateActionMode() | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -55,6 +55,8 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|      */ | ||||
|     private val selectedItems = mutableSetOf<ChapterItem>() | ||||
|  | ||||
|     private var lastClickPosition = -1 | ||||
|  | ||||
|     init { | ||||
|         setHasOptionsMenu(true) | ||||
|         setOptionsMenuHidden(true) | ||||
| @@ -184,8 +186,9 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|     fun onNextChapters(chapters: List<ChapterItem>) { | ||||
|         // If the list is empty, fetch chapters from source if the conditions are met | ||||
|         // We use presenter chapters instead because they are always unfiltered | ||||
|         if (presenter.chapters.isEmpty()) | ||||
|         if (presenter.chapters.isEmpty()) { | ||||
|             initialFetchChapters() | ||||
|         } | ||||
|  | ||||
|         val adapter = adapter ?: return | ||||
|         adapter.updateDataSet(chapters) | ||||
| @@ -242,10 +245,11 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|         startActivity(intent) | ||||
|     } | ||||
|  | ||||
|     override fun onItemClick(view: View, position: Int): Boolean { | ||||
|     override fun onItemClick(view: View?, position: Int): Boolean { | ||||
|         val adapter = adapter ?: return false | ||||
|         val item = adapter.getItem(position) ?: return false | ||||
|         if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) { | ||||
|             lastClickPosition = position | ||||
|             toggleSelection(position) | ||||
|             return true | ||||
|         } else { | ||||
| @@ -256,7 +260,16 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|  | ||||
|     override fun onItemLongClick(position: Int) { | ||||
|         createActionModeIfNeeded() | ||||
|         toggleSelection(position) | ||||
|         when { | ||||
|             lastClickPosition == -1 -> setSelection(position) | ||||
|             lastClickPosition > position -> for (i in position until lastClickPosition) | ||||
|                 setSelection(i) | ||||
|             lastClickPosition < position -> for (i in lastClickPosition + 1..position) | ||||
|                 setSelection(i) | ||||
|             else -> setSelection(position) | ||||
|         } | ||||
|         lastClickPosition = position | ||||
|         adapter?.notifyDataSetChanged() | ||||
|     } | ||||
|  | ||||
|     // SELECTIONS & ACTION MODE | ||||
| @@ -265,6 +278,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|         val adapter = adapter ?: return | ||||
|         val item = adapter.getItem(position) ?: return | ||||
|         adapter.toggleSelection(position) | ||||
|         adapter.notifyDataSetChanged() | ||||
|         if (adapter.isSelected(position)) { | ||||
|             selectedItems.add(item) | ||||
|         } else { | ||||
| @@ -273,6 +287,16 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|         actionMode?.invalidate() | ||||
|     } | ||||
|  | ||||
|     private fun setSelection(position: Int) { | ||||
|         val adapter = adapter ?: return | ||||
|         val item = adapter.getItem(position) ?: return | ||||
|         if (!adapter.isSelected(position)) { | ||||
|             adapter.toggleSelection(position) | ||||
|             selectedItems.add(item) | ||||
|             actionMode?.invalidate() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun getSelectedChapters(): List<ChapterItem> { | ||||
|         val adapter = adapter ?: return emptyList() | ||||
|         return adapter.selectedPositions.mapNotNull { adapter.getItem(it) } | ||||
| @@ -285,6 +309,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|     } | ||||
|  | ||||
|     private fun destroyActionModeIfNeeded() { | ||||
|         lastClickPosition = -1 | ||||
|         actionMode?.finish() | ||||
|     } | ||||
|  | ||||
| @@ -373,7 +398,6 @@ class ChaptersController : NucleusController<ChaptersPresenter>(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private fun showDeleteChaptersConfirmationDialog() { | ||||
|         DeleteChaptersDialog(this).showDialog(router) | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user