Context menus

This commit is contained in:
Koitharu
2024-09-24 16:35:44 +03:00
parent 5a2a31d1c8
commit 063527b240
35 changed files with 320 additions and 190 deletions

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.bookmarks.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@@ -129,7 +130,11 @@ class AllBookmarksFragment :
}
override fun onItemLongClick(item: Bookmark, view: View): Boolean {
return selectionController?.onItemLongClick(item.pageId) ?: false
return selectionController?.onItemLongClick(view, item.pageId) ?: false
}
override fun onItemContextClick(item: Bookmark, view: View): Boolean {
return selectionController?.onItemContextClick(view, item.pageId) ?: false
}
override fun onRetryClick(error: Throwable) = Unit
@@ -148,23 +153,23 @@ class AllBookmarksFragment :
override fun onCreateActionMode(
controller: ListSelectionController,
mode: ActionMode,
menuInflater: MenuInflater,
menu: Menu,
): Boolean {
mode.menuInflater.inflate(R.menu.mode_bookmarks, menu)
menuInflater.inflate(R.menu.mode_bookmarks, menu)
return true
}
override fun onActionItemClicked(
controller: ListSelectionController,
mode: ActionMode,
mode: ActionMode?,
item: MenuItem,
): Boolean {
return when (item.itemId) {
R.id.action_remove -> {
val ids = selectionController?.snapshot() ?: return false
viewModel.removeBookmarks(ids)
mode.finish()
mode?.finish()
true
}

View File

@@ -22,10 +22,7 @@ fun bookmarkLargeAD(
) = adapterDelegateViewBinding<Bookmark, ListModel, ItemBookmarkLargeBinding>(
{ inflater, parent -> ItemBookmarkLargeBinding.inflate(inflater, parent, false) },
) {
val listener = AdapterDelegateClickListenerAdapter(this, clickListener)
binding.root.setOnClickListener(listener)
binding.root.setOnLongClickListener(listener)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind {
binding.imageViewThumb.newImageRequest(lifecycleOwner, item.imageLoadData)?.run {

View File

@@ -21,10 +21,7 @@ fun bookmarkListAD(
) = adapterDelegateViewBinding<Bookmark, Bookmark, ItemBookmarkBinding>(
{ inflater, parent -> ItemBookmarkBinding.inflate(inflater, parent, false) },
) {
val listener = AdapterDelegateClickListenerAdapter(this, clickListener)
binding.root.setOnClickListener(listener)
binding.root.setOnLongClickListener(listener)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind {
binding.imageViewThumb.newImageRequest(lifecycleOwner, item.imageLoadData)?.run {

View File

@@ -0,0 +1,8 @@
package org.koitharu.kotatsu.core.ui
import android.view.View
fun interface OnContextClickListenerCompat {
fun onContextClick(v: View): Boolean
}

View File

@@ -3,18 +3,46 @@ package org.koitharu.kotatsu.core.ui.list
import android.view.View
import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import androidx.core.util.Function
import com.hannesdorfmann.adapterdelegates4.dsl.AdapterDelegateViewBindingViewHolder
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
class AdapterDelegateClickListenerAdapter<I>(
class AdapterDelegateClickListenerAdapter<I, O>(
private val adapterDelegate: AdapterDelegateViewBindingViewHolder<out I, *>,
private val clickListener: OnListItemClickListener<I>,
) : OnClickListener, OnLongClickListener {
private val clickListener: OnListItemClickListener<O>,
private val itemMapper: Function<I, O>,
) : OnClickListener, OnLongClickListener, OnContextClickListenerCompat {
override fun onClick(v: View) {
clickListener.onItemClick(adapterDelegate.item, v)
clickListener.onItemClick(mappedItem(), v)
}
override fun onLongClick(v: View): Boolean {
return clickListener.onItemLongClick(adapterDelegate.item, v)
return clickListener.onItemLongClick(mappedItem(), v)
}
override fun onContextClick(v: View): Boolean {
return clickListener.onItemContextClick(mappedItem(), v)
}
private fun mappedItem(): O = itemMapper.apply(adapterDelegate.item)
fun attach(itemView: View) {
itemView.setOnClickListener(this)
itemView.setOnLongClickListener(this)
itemView.setOnContextClickListenerCompat(this)
}
companion object {
operator fun <T> invoke(
adapterDelegate: AdapterDelegateViewBindingViewHolder<out T, *>,
clickListener: OnListItemClickListener<T>
): AdapterDelegateClickListenerAdapter<T, T> = AdapterDelegateClickListenerAdapter(
adapterDelegate = adapterDelegate,
clickListener = clickListener,
itemMapper = { x -> x },
)
}
}

View File

@@ -2,10 +2,14 @@ package org.koitharu.kotatsu.core.ui.list
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.PopupMenu
import androidx.collection.LongSet
import androidx.collection.longSetOf
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
@@ -29,18 +33,21 @@ class ListSelectionController(
) : ActionMode.Callback, SavedStateRegistry.SavedStateProvider {
private var actionMode: ActionMode? = null
private var focusedItemId: LongSet? = null
var useActionMode: Boolean = true
val count: Int
get() = decoration.checkedItemsCount
get() = if (focusedItemId != null) 1 else decoration.checkedItemsCount
init {
registryOwner.lifecycle.addObserver(StateEventObserver())
}
fun snapshot(): Set<Long> = peekCheckedIds().toSet()
fun snapshot(): Set<Long> = (focusedItemId ?: peekCheckedIds()).toSet()
fun peekCheckedIds(): LongSet {
return decoration.checkedItemsIds
return focusedItemId ?: decoration.checkedItemsIds
}
fun clear() {
@@ -52,6 +59,7 @@ class ListSelectionController(
if (ids.isEmpty()) {
return
}
startActionMode()
decoration.checkAll(ids)
notifySelectionChanged()
}
@@ -80,15 +88,42 @@ class ListSelectionController(
return false
}
fun onItemLongClick(id: Long): Boolean {
return startActionMode()?.also {
decoration.setItemIsChecked(id, true)
notifySelectionChanged()
} != null
fun onItemLongClick(view: View, id: Long): Boolean {
return if (useActionMode) {
startSelection(id)
} else {
onItemContextClick(view, id)
}
}
fun onItemContextClick(view: View, id: Long): Boolean {
focusedItemId = longSetOf(id)
val menu = PopupMenu(view.context, view)
callback.onCreateActionMode(this, menu.menuInflater, menu.menu)
callback.onPrepareActionMode(this, null, menu.menu)
menu.setForceShowIcon(true)
if (menu.menu.hasVisibleItems()) {
menu.setOnMenuItemClickListener { menuItem ->
callback.onActionItemClicked(this, null, menuItem)
}
menu.setOnDismissListener {
focusedItemId = null
}
menu.show()
return true
} else {
focusedItemId = null
return false
}
}
fun startSelection(id: Long): Boolean = startActionMode()?.also {
decoration.setItemIsChecked(id, true)
notifySelectionChanged()
} != null
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
return callback.onCreateActionMode(this, mode, menu)
return callback.onCreateActionMode(this, mode.menuInflater, menu)
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
@@ -106,6 +141,7 @@ class ListSelectionController(
}
private fun startActionMode(): ActionMode? {
focusedItemId = null
return actionMode ?: appCompatDelegate.startSupportActionMode(this).also {
actionMode = it
}
@@ -134,14 +170,14 @@ class ListSelectionController(
fun onSelectionChanged(controller: ListSelectionController, count: Int)
fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean
fun onCreateActionMode(controller: ListSelectionController, menuInflater: MenuInflater, menu: Menu): Boolean
fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.title = controller.count.toString()
fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
mode?.title = controller.count.toString()
return true
}
fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean
fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean
fun onDestroyActionMode(controller: ListSelectionController, mode: ActionMode) = Unit
}

View File

@@ -6,5 +6,7 @@ fun interface OnListItemClickListener<I> {
fun onItemClick(item: I, view: View)
fun onItemLongClick(item: I, view: View) = false
fun onItemLongClick(item: I, view: View): Boolean = false
fun onItemContextClick(item: I, view: View): Boolean = onItemLongClick(item, view)
}

View File

@@ -4,11 +4,15 @@ import android.view.MenuItem
import android.view.View
import androidx.appcompat.widget.PopupMenu
import androidx.core.view.MenuProvider
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
class PopupMenuMediator(
private val provider: MenuProvider,
) : View.OnLongClickListener, PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
) : View.OnLongClickListener, OnContextClickListenerCompat, PopupMenu.OnMenuItemClickListener,
PopupMenu.OnDismissListener {
override fun onContextClick(v: View): Boolean = onLongClick(v)
override fun onLongClick(v: View): Boolean {
val menu = PopupMenu(v.context, v)

View File

@@ -21,6 +21,7 @@ import com.google.android.material.progressindicator.BaseProgressIndicator
import com.google.android.material.slider.RangeSlider
import com.google.android.material.slider.Slider
import com.google.android.material.tabs.TabLayout
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import kotlin.math.roundToInt
fun View.hasGlobalPoint(x: Int, y: Int): Boolean {
@@ -153,9 +154,9 @@ fun BaseProgressIndicator<*>.showOrHide(value: Boolean) {
}
}
fun View.setOnContextClickListenerCompat(listener: View.OnLongClickListener) {
fun View.setOnContextClickListenerCompat(listener: OnContextClickListenerCompat) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setOnContextClickListener(listener::onLongClick)
setOnContextClickListener(listener::onContextClick)
}
}

View File

@@ -54,6 +54,7 @@ import org.koitharu.kotatsu.core.parser.MangaIntent
import org.koitharu.kotatsu.core.parser.favicon.faviconUri
import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.ui.OnContextClickListenerCompat
import org.koitharu.kotatsu.core.ui.image.ChipIconTarget
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
@@ -114,7 +115,8 @@ class DetailsActivity :
BaseActivity<ActivityDetailsBinding>(),
View.OnClickListener,
View.OnLongClickListener, PopupMenu.OnMenuItemClickListener, View.OnLayoutChangeListener,
ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener<Bookmark> {
ViewTreeObserver.OnDrawListener, ChipsView.OnChipClickListener, OnListItemClickListener<Bookmark>,
OnContextClickListenerCompat {
@Inject
lateinit var shortcutManager: AppShortcutManager
@@ -291,6 +293,8 @@ class DetailsActivity :
startActivity(MangaListActivity.newIntent(this, tag.source, MangaListFilter(tags = setOf(tag))))
}
override fun onContextClick(v: View): Boolean = onLongClick(v)
override fun onLongClick(v: View): Boolean = when (v.id) {
R.id.button_read -> {
val menu = PopupMenu(v.context, v)

View File

@@ -18,9 +18,7 @@ fun chapterGridItemAD(
on = { item, _, _ -> item is ChapterListItem && item.isGrid },
) {
val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener)
itemView.setOnClickListener(eventListener)
itemView.setOnLongClickListener(eventListener)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind { payloads ->
if (payloads.isEmpty()) {

View File

@@ -22,9 +22,7 @@ fun chapterListItemAD(
on = { item, _, _ -> item is ChapterListItem && !item.isGrid },
) {
val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener)
itemView.setOnClickListener(eventListener)
itemView.setOnLongClickListener(eventListener)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind {
binding.textViewTitle.text = item.chapter.name

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.details.ui.pager.bookmarks
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@@ -133,7 +134,11 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
}
override fun onItemLongClick(item: Bookmark, view: View): Boolean {
return selectionController?.onItemLongClick(item.pageId) ?: false
return selectionController?.onItemLongClick(view, item.pageId) ?: false
}
override fun onItemContextClick(item: Bookmark, view: View): Boolean {
return selectionController?.onItemContextClick(view, item.pageId) ?: false
}
override fun onSelectionChanged(controller: ListSelectionController, count: Int) {
@@ -142,23 +147,23 @@ class BookmarksFragment : BaseFragment<FragmentMangaBookmarksBinding>(),
override fun onCreateActionMode(
controller: ListSelectionController,
mode: ActionMode,
menuInflater: MenuInflater,
menu: Menu,
): Boolean {
mode.menuInflater.inflate(R.menu.mode_bookmarks, menu)
menuInflater.inflate(R.menu.mode_bookmarks, menu)
return true
}
override fun onActionItemClicked(
controller: ListSelectionController,
mode: ActionMode,
mode: ActionMode?,
item: MenuItem,
): Boolean {
return when (item.itemId) {
R.id.action_remove -> {
val ids = selectionController?.snapshot() ?: return false
viewModel.removeBookmarks(ids)
mode.finish()
mode?.finish()
true
}

View File

@@ -116,7 +116,11 @@ class ChaptersFragment :
}
override fun onItemLongClick(item: ChapterListItem, view: View): Boolean {
return selectionController?.onItemLongClick(item.chapter.id) ?: false
return selectionController?.onItemLongClick(view, item.chapter.id) ?: false
}
override fun onItemContextClick(item: ChapterListItem, view: View): Boolean {
return selectionController?.onItemContextClick(view, item.chapter.id) ?: false
}
override fun onWindowInsetsChanged(insets: Insets) = Unit
@@ -149,7 +153,7 @@ class ChaptersFragment :
items?.indexOfFirst(predicate) ?: -1
}
if (position >= 0) {
selectionController?.onItemLongClick(chapterId)
selectionController?.startSelection(chapterId)
val lm = (viewBinding?.recyclerViewChapters?.layoutManager as? LinearLayoutManager)
if (lm != null) {
val offset = resources.getDimensionPixelOffset(R.dimen.chapter_list_item_height)

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.details.ui.pager.chapters
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.RecyclerView
@@ -19,12 +20,16 @@ class ChaptersSelectionCallback(
recyclerView: RecyclerView,
) : BaseListSelectionCallback(recyclerView) {
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_chapters, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_chapters, menu)
return true
}
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
val selectedIds = controller.peekCheckedIds()
val allItems = viewModel.chapters.value
val items = allItems.withIndex().filter { it.value.chapter.id in selectedIds }
@@ -38,7 +43,7 @@ class ChaptersSelectionCallback(
menu.findItem(R.id.action_delete).isVisible = canDelete
menu.findItem(R.id.action_select_all).isVisible = items.size < allItems.size
menu.findItem(R.id.action_mark_current).isVisible = items.size == 1
mode.title = items.size.toString()
mode?.title = items.size.toString()
var hasGap = false
for (i in 0 until items.size - 1) {
if (items[i].index + 1 != items[i + 1].index) {
@@ -50,11 +55,11 @@ class ChaptersSelectionCallback(
return true
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_save -> {
viewModel.download(controller.snapshot())
mode.finish()
mode?.finish()
true
}
@@ -73,7 +78,7 @@ class ChaptersSelectionCallback(
).show()
}
}
mode.finish()
mode?.finish()
true
}
@@ -112,7 +117,7 @@ class ChaptersSelectionCallback(
} else {
return false
}
mode.finish()
mode?.finish()
true
}

View File

@@ -32,9 +32,7 @@ fun pageThumbnailAD(
height = (gridWidth / 13f * 18f).toInt(),
)
val clickListenerAdapter = AdapterDelegateClickListenerAdapter(this, clickListener)
binding.root.setOnClickListener(clickListenerAdapter)
binding.root.setOnLongClickListener(clickListenerAdapter)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind {
val data: Any = item.page.preview?.takeUnless { it.isEmpty() } ?: item.page.toMangaPage()

View File

@@ -1,7 +1,7 @@
package org.koitharu.kotatsu.details.ui.related
import android.view.Menu
import androidx.appcompat.view.ActionMode
import android.view.MenuInflater
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
@@ -16,9 +16,13 @@ class RelatedListFragment : MangaListFragment() {
override fun onScrolledToEnd() = Unit
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, mode, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
}

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.download.ui.list
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.activity.viewModels
@@ -87,7 +88,11 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
}
override fun onItemLongClick(item: DownloadItemModel, view: View): Boolean {
return selectionController.onItemLongClick(item.id.mostSignificantBits)
return selectionController.onItemLongClick(view, item.id.mostSignificantBits)
}
override fun onItemContextClick(item: DownloadItemModel, view: View): Boolean {
return selectionController.onItemContextClick(view, item.id.mostSignificantBits)
}
override fun onExpandClick(item: DownloadItemModel) {
@@ -120,34 +125,38 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
viewBinding.recyclerView.invalidateItemDecorations()
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_downloads, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_downloads, menu)
return true
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_resume -> {
viewModel.resume(controller.snapshot())
mode.finish()
mode?.finish()
true
}
R.id.action_pause -> {
viewModel.pause(controller.snapshot())
mode.finish()
mode?.finish()
true
}
R.id.action_cancel -> {
viewModel.cancel(controller.snapshot())
mode.finish()
mode?.finish()
true
}
R.id.action_remove -> {
viewModel.remove(controller.snapshot())
mode.finish()
mode?.finish()
true
}
@@ -160,7 +169,7 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
}
}
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
val snapshot = viewModel.snapshot(controller.peekCheckedIds())
var canPause = true
var canResume = true

View File

@@ -7,6 +7,7 @@ import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@@ -147,7 +148,11 @@ class ExploreFragment :
}
override fun onItemLongClick(item: MangaSourceItem, view: View): Boolean {
return sourceSelectionController?.onItemLongClick(item.id) ?: false
return sourceSelectionController?.onItemLongClick(view, item.id) ?: false
}
override fun onItemContextClick(item: MangaSourceItem, view: View): Boolean {
return sourceSelectionController?.onItemContextClick(view, item.id) ?: false
}
override fun onRetryClick(error: Throwable) = Unit
@@ -160,12 +165,16 @@ class ExploreFragment :
viewBinding?.recyclerView?.invalidateItemDecorations()
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_source, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_source, menu)
return true
}
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
val selectedSources = viewModel.sourcesSnapshot(controller.peekCheckedIds())
val isSingleSelection = selectedSources.size == 1
menu.findItem(R.id.action_settings).isVisible = isSingleSelection
@@ -177,7 +186,7 @@ class ExploreFragment :
return super.onPrepareActionMode(controller, mode, menu)
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
val selectedSources = viewModel.sourcesSnapshot(controller.peekCheckedIds())
if (selectedSources.isEmpty()) {
return false
@@ -186,35 +195,35 @@ class ExploreFragment :
R.id.action_settings -> {
val source = selectedSources.singleOrNull() ?: return false
startActivity(SettingsActivity.newSourceSettingsIntent(requireContext(), source))
mode.finish()
mode?.finish()
}
R.id.action_disable -> {
viewModel.disableSources(selectedSources)
mode.finish()
mode?.finish()
}
R.id.action_delete -> {
selectedSources.forEach {
(it.mangaSource as? ExternalMangaSource)?.let { uninstallExternalSource(it) }
}
mode.finish()
mode?.finish()
}
R.id.action_shortcut -> {
val source = selectedSources.singleOrNull() ?: return false
viewModel.requestPinShortcut(source)
mode.finish()
mode?.finish()
}
R.id.action_pin -> {
viewModel.setSourcesPinned(selectedSources, isPinned = true)
mode.finish()
mode?.finish()
}
R.id.action_unpin -> {
viewModel.setSourcesPinned(selectedSources, isPinned = false)
mode.finish()
mode?.finish()
}
else -> return false

View File

@@ -20,7 +20,6 @@ import org.koitharu.kotatsu.core.util.ext.drawableStart
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.recyclerView
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.setProgressIcon
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.core.util.ext.textAndVisible
@@ -117,13 +116,9 @@ fun exploreSourceListItemAD(
on = { item, _, _ -> item is MangaSourceItem && !item.isGrid },
) {
val eventListener = AdapterDelegateClickListenerAdapter(this, listener)
AdapterDelegateClickListenerAdapter(this, listener).attach(itemView)
val iconPinned = ContextCompat.getDrawable(context, R.drawable.ic_pin_small)
binding.root.setOnClickListener(eventListener)
binding.root.setOnLongClickListener(eventListener)
binding.root.setOnContextClickListenerCompat(eventListener)
bind {
binding.textViewTitle.text = item.source.getTitle(context)
binding.textViewTitle.drawableStart = if (item.source.isPinned) iconPinned else null
@@ -154,13 +149,9 @@ fun exploreSourceGridItemAD(
on = { item, _, _ -> item is MangaSourceItem && item.isGrid },
) {
val eventListener = AdapterDelegateClickListenerAdapter(this, listener)
AdapterDelegateClickListenerAdapter(this, listener).attach(itemView)
val iconPinned = ContextCompat.getDrawable(context, R.drawable.ic_pin_small)
binding.root.setOnClickListener(eventListener)
binding.root.setOnLongClickListener(eventListener)
binding.root.setOnContextClickListenerCompat(eventListener)
bind {
binding.textViewTitle.text = item.source.getTitle(context)
binding.textViewTitle.drawableStart = if (item.source.isPinned) iconPinned else null

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.favourites.ui.categories
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.RecyclerView
@@ -17,12 +18,16 @@ class CategoriesSelectionCallback(
recyclerView.invalidateItemDecorations()
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_category, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_category, menu)
return true
}
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
val categories = viewModel.getCategories(controller.peekCheckedIds())
var canShow = categories.isNotEmpty()
var canHide = canShow
@@ -35,11 +40,11 @@ class CategoriesSelectionCallback(
}
menu.findItem(R.id.action_show)?.isVisible = canShow
menu.findItem(R.id.action_hide)?.isVisible = canHide
mode.title = controller.count.toString()
mode?.title = controller.count.toString()
return true
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
/*R.id.action_view -> {
val id = controller.peekCheckedIds().singleOrNull() ?: return false
@@ -53,13 +58,13 @@ class CategoriesSelectionCallback(
R.id.action_show -> {
viewModel.setIsVisible(controller.snapshot(), true)
mode.finish()
mode?.finish()
true
}
R.id.action_hide -> {
viewModel.setIsVisible(controller.snapshot(), false)
mode.finish()
mode?.finish()
true
}
@@ -72,7 +77,7 @@ class CategoriesSelectionCallback(
}
}
private fun confirmDeleteCategories(ids: Set<Long>, mode: ActionMode) {
private fun confirmDeleteCategories(ids: Set<Long>, mode: ActionMode?) {
buildAlertDialog(recyclerView.context, isCentered = true) {
setMessage(R.string.categories_delete_confirm)
setTitle(R.string.remove_category)
@@ -80,7 +85,7 @@ class CategoriesSelectionCallback(
setNegativeButton(android.R.string.cancel, null)
setPositiveButton(R.string.remove) { _, _ ->
viewModel.deleteCategories(ids)
mode.finish()
mode?.finish()
}
}.show()
}

View File

@@ -98,7 +98,11 @@ class FavouriteCategoriesActivity :
}
override fun onItemLongClick(item: FavouriteCategory?, view: View): Boolean {
return item != null && selectionController.onItemLongClick(item.id)
return item != null && selectionController.onItemLongClick(view, item.id)
}
override fun onItemContextClick(item: FavouriteCategory?, view: View): Boolean {
return item != null && selectionController.onItemContextClick(view, item.id)
}
override fun onSupportActionModeStarted(mode: ActionMode) {

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.favourites.ui.list
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.view.ActionMode
@@ -52,27 +53,32 @@ class FavouritesListFragment : MangaListFragment(), PopupMenu.OnMenuItemClickLis
return true
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_favourites, menu)
return super.onCreateActionMode(controller, mode, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_favourites, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_remove -> {
viewModel.removeFromFavourites(selectedItemsIds)
mode.finish()
mode?.finish()
true
}
R.id.action_mark_current -> {
val itemsSnapshot = selectedItems
MaterialAlertDialogBuilder(context ?: return false)
.setTitle(item.title)
.setMessage(R.string.mark_as_completed_prompt)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok) { _, _ ->
viewModel.markAsRead(selectedItems)
mode.finish()
viewModel.markAsRead(itemsSnapshot)
mode?.finish()
}.show()
true
}

View File

@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.history.ui
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.view.ActionMode
import androidx.fragment.app.viewModels
@@ -34,28 +35,33 @@ class HistoryListFragment : MangaListFragment() {
override fun onEmptyActionClick() = viewModel.clearFilter()
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_history, menu)
return super.onCreateActionMode(controller, mode, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_history, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_remove -> {
viewModel.removeFromHistory(selectedItemsIds)
mode.finish()
mode?.finish()
true
}
R.id.action_mark_current -> {
val itemsSnapshot = selectedItems
buildAlertDialog(context ?: return false, isCentered = true) {
setTitle(item.title)
setIcon(item.icon)
setMessage(R.string.mark_as_completed_prompt)
setNegativeButton(android.R.string.cancel, null)
setPositiveButton(android.R.string.ok) { _, _ ->
viewModel.markAsRead(selectedItems)
mode.finish()
viewModel.markAsRead(itemsSnapshot)
mode?.finish()
}
}.show()
true

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.list.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
@@ -11,7 +12,6 @@ import androidx.annotation.CallSuper
import androidx.appcompat.view.ActionMode
import androidx.collection.ArraySet
import androidx.core.graphics.Insets
import androidx.core.view.isNotEmpty
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.GridLayoutManager
@@ -153,7 +153,11 @@ abstract class MangaListFragment :
}
override fun onItemLongClick(item: Manga, view: View): Boolean {
return selectionController?.onItemLongClick(item.id) ?: false
return selectionController?.onItemLongClick(view, item.id) ?: false
}
override fun onItemContextClick(item: Manga, view: View): Boolean {
return selectionController?.onItemContextClick(view, item.id) ?: false
}
override fun onReadClick(manga: Manga, view: View) {
@@ -280,18 +284,22 @@ abstract class MangaListFragment :
}
@CallSuper
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
override fun onPrepareActionMode(controller: ListSelectionController, mode: ActionMode?, menu: Menu): Boolean {
val hasNoLocal = selectedItems.none { it.isLocal }
menu.findItem(R.id.action_save)?.isVisible = hasNoLocal
menu.findItem(R.id.action_fix)?.isVisible = hasNoLocal
return super.onPrepareActionMode(controller, mode, menu)
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
return menu.isNotEmpty()
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
return menu.hasVisibleItems()
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_select_all -> {
val ids = listAdapter?.items?.mapNotNull {
@@ -303,31 +311,32 @@ abstract class MangaListFragment :
R.id.action_share -> {
ShareHelper(requireContext()).shareMangaLinks(selectedItems)
mode.finish()
mode?.finish()
true
}
R.id.action_favourite -> {
FavoriteSheet.show(getChildFragmentManager(), selectedItems)
mode.finish()
mode?.finish()
true
}
R.id.action_save -> {
viewModel.download(selectedItems)
mode.finish()
mode?.finish()
true
}
R.id.action_fix -> {
val itemsSnapshot = selectedItemsIds
buildAlertDialog(context ?: return false, isCentered = true) {
setTitle(item.title)
setIcon(item.icon)
setMessage(R.string.manga_fix_prompt)
setNegativeButton(android.R.string.cancel, null)
setPositiveButton(R.string.fix) { _, _ ->
AutoFixService.start(context, selectedItemsIds)
mode.finish()
AutoFixService.start(context, itemsSnapshot)
mode?.finish()
}
}.show()
true

View File

@@ -1,6 +1,5 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
@@ -8,11 +7,11 @@ import com.google.android.material.badge.BadgeDrawable
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.databinding.ItemMangaGridBinding
import org.koitharu.kotatsu.list.ui.ListModelDiffCallback.Companion.PAYLOAD_PROGRESS_CHANGED
@@ -31,13 +30,7 @@ fun mangaGridItemAD(
) {
var badge: BadgeDrawable? = null
val eventListener = object : View.OnClickListener, View.OnLongClickListener {
override fun onClick(v: View) = clickListener.onItemClick(item.manga, v)
override fun onLongClick(v: View): Boolean = clickListener.onItemLongClick(item.manga, v)
}
itemView.setOnClickListener(eventListener)
itemView.setOnLongClickListener(eventListener)
itemView.setOnContextClickListenerCompat(eventListener)
AdapterDelegateClickListenerAdapter(this, clickListener, MangaGridModel::manga).attach(itemView)
sizeResolver.attachToView(lifecycleOwner, itemView, binding.textViewTitle, binding.progressView)
bind { payloads ->

View File

@@ -1,16 +1,15 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
import com.google.android.material.badge.BadgeDrawable
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver
import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemMangaListDetailsBinding
@@ -27,14 +26,7 @@ fun mangaListDetailedItemAD(
) {
var badge: BadgeDrawable? = null
val listenerAdapter = object : View.OnClickListener, View.OnLongClickListener {
override fun onClick(v: View) = clickListener.onItemClick(item.manga, v)
override fun onLongClick(v: View): Boolean = clickListener.onItemLongClick(item.manga, v)
}
itemView.setOnClickListener(listenerAdapter)
itemView.setOnLongClickListener(listenerAdapter)
itemView.setOnContextClickListenerCompat(listenerAdapter)
AdapterDelegateClickListenerAdapter(this, clickListener, MangaDetailedListModel::manga).attach(itemView)
bind { payloads ->
binding.textViewTitle.text = item.title

View File

@@ -1,16 +1,15 @@
package org.koitharu.kotatsu.list.ui.adapter
import android.view.View
import androidx.lifecycle.LifecycleOwner
import coil.ImageLoader
import com.google.android.material.badge.BadgeDrawable
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.defaultPlaceholders
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemMangaListBinding
@@ -27,13 +26,7 @@ fun mangaListItemAD(
) {
var badge: BadgeDrawable? = null
val eventListener = object : View.OnClickListener, View.OnLongClickListener {
override fun onClick(v: View) = clickListener.onItemClick(item.manga, v)
override fun onLongClick(v: View): Boolean = clickListener.onItemLongClick(item.manga, v)
}
itemView.setOnClickListener(eventListener)
itemView.setOnLongClickListener(eventListener)
itemView.setOnContextClickListenerCompat(eventListener)
AdapterDelegateClickListenerAdapter(this, clickListener, MangaCompactListModel::manga).attach(itemView)
bind {
binding.textViewTitle.text = item.title

View File

@@ -4,6 +4,7 @@ import android.Manifest
import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
@@ -88,16 +89,16 @@ class LocalListFragment : MangaListFragment(), FilterCoordinator.Owner {
override fun onCreateActionMode(
controller: ListSelectionController,
mode: ActionMode,
menuInflater: MenuInflater,
menu: Menu,
): Boolean {
mode.menuInflater.inflate(R.menu.mode_local, menu)
return super.onCreateActionMode(controller, mode, menu)
menuInflater.inflate(R.menu.mode_local, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
override fun onActionItemClicked(
controller: ListSelectionController,
mode: ActionMode,
mode: ActionMode?,
item: MenuItem,
): Boolean {
return when (item.itemId) {
@@ -109,7 +110,7 @@ class LocalListFragment : MangaListFragment(), FilterCoordinator.Owner {
R.id.action_share -> {
val files = selectedItems.map { it.url.toUri().toFile() }
ShareHelper(requireContext()).shareCbz(files)
mode.finish()
mode?.finish()
true
}
@@ -117,13 +118,13 @@ class LocalListFragment : MangaListFragment(), FilterCoordinator.Owner {
}
}
private fun showDeletionConfirm(ids: Set<Long>, mode: ActionMode) {
private fun showDeletionConfirm(ids: Set<Long>, mode: ActionMode?) {
MaterialAlertDialogBuilder(context ?: return)
.setTitle(R.string.delete_manga)
.setMessage(getString(R.string.text_delete_local_manga_batch))
.setPositiveButton(R.string.delete) { _, _ ->
viewModel.delete(ids)
mode.finish()
mode?.finish()
}
.setNegativeButton(android.R.string.cancel, null)
.show()

View File

@@ -5,7 +5,6 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.view.ActionMode
import androidx.core.view.MenuProvider
import androidx.fragment.app.viewModels
import com.google.android.material.snackbar.Snackbar
@@ -56,9 +55,13 @@ class RemoteListFragment : MangaListFragment(), FilterCoordinator.Owner {
viewModel.loadNextPage()
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, mode, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
override fun onFilterClick(view: View?) {

View File

@@ -20,8 +20,7 @@ fun scrobblingMangaAD(
{ layoutInflater, parent -> ItemScrobblingMangaBinding.inflate(layoutInflater, parent, false) },
) {
val clickListenerAdapter = AdapterDelegateClickListenerAdapter(this, clickListener)
itemView.setOnClickListener(clickListenerAdapter)
AdapterDelegateClickListenerAdapter(this, clickListener).attach(itemView)
bind {
binding.imageViewCover.newImageRequest(lifecycleOwner, item.coverUrl)?.run {

View File

@@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.activity.viewModels
@@ -118,7 +119,11 @@ class SearchActivity :
}
override fun onItemLongClick(item: Manga, view: View): Boolean {
return selectionController.onItemLongClick(item.id)
return selectionController.onItemLongClick(view, item.id)
}
override fun onItemContextClick(item: Manga, view: View): Boolean {
return selectionController.onItemContextClick(view, item.id)
}
override fun onReadClick(manga: Manga, view: View) {
@@ -155,28 +160,32 @@ class SearchActivity :
viewBinding.recyclerView.invalidateNestedItemDecorations()
}
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_remote, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_remote, menu)
return true
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_share -> {
ShareHelper(this).shareMangaLinks(collectSelectedItems())
mode.finish()
mode?.finish()
true
}
R.id.action_favourite -> {
FavoriteSheet.show(supportFragmentManager, collectSelectedItems())
mode.finish()
mode?.finish()
true
}
R.id.action_save -> {
viewModel.download(collectSelectedItems())
mode.finish()
mode?.finish()
true
}

View File

@@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.view.ActionMode
import androidx.core.view.MenuProvider
import androidx.fragment.app.viewModels
import com.google.android.material.snackbar.Snackbar
@@ -29,11 +28,11 @@ class SuggestionsFragment : MangaListFragment() {
override fun onCreateActionMode(
controller: ListSelectionController,
mode: ActionMode,
menuInflater: MenuInflater,
menu: Menu,
): Boolean {
mode.menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, mode, menu)
menuInflater.inflate(R.menu.mode_remote, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
private inner class SuggestionMenuProvider : MenuProvider {
@@ -71,10 +70,11 @@ class SuggestionsFragment : MangaListFragment() {
companion object {
@Deprecated(
"", ReplaceWith(
"",
ReplaceWith(
"SuggestionsFragment()",
"org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment"
)
"org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment",
),
)
fun newInstance() = SuggestionsFragment()
}

View File

@@ -62,6 +62,8 @@ class FeedFragment :
onItemClick(item.manga, v)
}
with(binding.recyclerView) {
val paddingVertical = resources.getDimensionPixelSize(R.dimen.list_spacing_normal)
setPadding(0, paddingVertical, 0, paddingVertical)
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
adapter = feedAdapter
setHasFixedSize(true)

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.tracker.ui.updates
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.view.ActionMode
import androidx.fragment.app.viewModels
@@ -17,16 +18,20 @@ class UpdatesFragment : MangaListFragment() {
override fun onScrolledToEnd() = Unit
override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.mode_updates, menu)
return super.onCreateActionMode(controller, mode, menu)
override fun onCreateActionMode(
controller: ListSelectionController,
menuInflater: MenuInflater,
menu: Menu
): Boolean {
menuInflater.inflate(R.menu.mode_updates, menu)
return super.onCreateActionMode(controller, menuInflater, menu)
}
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean {
override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode?, item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_remove -> {
viewModel.remove(controller.snapshot())
mode.finish()
mode?.finish()
true
}