mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
refactor: simplify swipe/drag listeners for recycler views
This commit is contained in:
parent
3a60a8d75b
commit
576b586075
@ -0,0 +1,48 @@
|
||||
package com.github.libretube.extensions
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
fun RecyclerView.setOnDismissListener(onDismissedListener: (position: Int) -> Unit) {
|
||||
setActionListener(
|
||||
swipeDirections = arrayOf(ItemTouchHelper.LEFT),
|
||||
onDismissedListener = onDismissedListener
|
||||
)
|
||||
}
|
||||
|
||||
fun RecyclerView.setOnDraggedListener(onDragListener: (from: Int, to: Int) -> Unit) {
|
||||
setActionListener(
|
||||
dragDirections = arrayOf(ItemTouchHelper.DOWN, ItemTouchHelper.UP),
|
||||
onDragListener = onDragListener
|
||||
)
|
||||
}
|
||||
|
||||
fun RecyclerView.setActionListener(
|
||||
swipeDirections: Array<Int> = arrayOf(),
|
||||
dragDirections: Array<Int> = arrayOf(),
|
||||
onDragListener: (from: Int, to: Int) -> Unit = { _, _ -> },
|
||||
onDismissedListener: (position: Int) -> Unit = {}
|
||||
) {
|
||||
val itemTouchCallback =
|
||||
object : ItemTouchHelper.SimpleCallback(
|
||||
dragDirections.fold(0) { a, b -> a or b },
|
||||
swipeDirections.fold(0) { a, b -> a or b }
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
if (dragDirections.isEmpty()) return false
|
||||
|
||||
onDragListener.invoke(viewHolder.absoluteAdapterPosition, target.absoluteAdapterPosition)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
onDismissedListener.invoke(viewHolder.absoluteAdapterPosition)
|
||||
}
|
||||
}
|
||||
|
||||
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(this)
|
||||
}
|
@ -3,11 +3,10 @@ package com.github.libretube.ui.dialogs
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.databinding.SimpleOptionsRecyclerBinding
|
||||
import com.github.libretube.extensions.setOnDraggedListener
|
||||
import com.github.libretube.helpers.NavBarHelper
|
||||
import com.github.libretube.ui.adapters.NavBarOptionsAdapter
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@ -21,41 +20,15 @@ class NavBarOptionsDialog : DialogFragment() {
|
||||
NavBarHelper.getStartFragmentId(requireContext())
|
||||
)
|
||||
|
||||
val itemTouchCallback = object : ItemTouchHelper.Callback() {
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
|
||||
return makeMovementFlags(dragFlags, 0)
|
||||
}
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
val itemToMove = adapter.items[viewHolder.absoluteAdapterPosition]
|
||||
adapter.items.remove(itemToMove)
|
||||
adapter.items.add(target.absoluteAdapterPosition, itemToMove)
|
||||
|
||||
adapter.notifyItemMoved(
|
||||
viewHolder.absoluteAdapterPosition,
|
||||
target.absoluteAdapterPosition
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
binding.optionsRecycler.layoutManager = LinearLayoutManager(context)
|
||||
binding.optionsRecycler.adapter = adapter
|
||||
binding.optionsRecycler.setOnDraggedListener { from, to ->
|
||||
val itemToMove = adapter.items[from]
|
||||
adapter.items.remove(itemToMove)
|
||||
adapter.items.add(to, itemToMove)
|
||||
|
||||
val itemTouchHelper = ItemTouchHelper(itemTouchCallback)
|
||||
itemTouchHelper.attachToRecyclerView(binding.optionsRecycler)
|
||||
adapter.notifyItemMoved(from, to)
|
||||
}
|
||||
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.navigation_bar)
|
||||
|
@ -17,7 +17,6 @@ import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.github.libretube.R
|
||||
@ -31,6 +30,7 @@ import com.github.libretube.db.obj.filterByTab
|
||||
import com.github.libretube.extensions.ceilHalf
|
||||
import com.github.libretube.extensions.formatAsFileSize
|
||||
import com.github.libretube.extensions.serializable
|
||||
import com.github.libretube.extensions.setOnDismissListener
|
||||
import com.github.libretube.helpers.BackgroundHelper
|
||||
import com.github.libretube.helpers.DownloadHelper
|
||||
import com.github.libretube.helpers.NavigationHelper
|
||||
@ -216,29 +216,11 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment() {
|
||||
}
|
||||
binding.downloadsRecView.adapter = adapter
|
||||
|
||||
val itemTouchCallback =
|
||||
object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int = makeMovementFlags(0, ItemTouchHelper.LEFT)
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean = false
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
adapter.showDeleteDialog(
|
||||
requireContext(),
|
||||
viewHolder.absoluteAdapterPosition
|
||||
)
|
||||
// put the item back to the center, as it's currently out of the screen
|
||||
adapter.restoreItem(viewHolder.absoluteAdapterPosition)
|
||||
}
|
||||
}
|
||||
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.downloadsRecView)
|
||||
binding.downloadsRecView.setOnDismissListener { position ->
|
||||
adapter.showDeleteDialog(requireContext(), position)
|
||||
// put the item back to the center, as it's currently out of the screen
|
||||
adapter.restoreItem(position)
|
||||
}
|
||||
|
||||
binding.downloadsRecView.adapter?.registerAdapterDataObserver(
|
||||
object : RecyclerView.AdapterDataObserver() {
|
||||
|
@ -18,7 +18,6 @@ import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.PlaylistsHelper
|
||||
@ -33,6 +32,7 @@ import com.github.libretube.enums.PlaylistType
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.ceilHalf
|
||||
import com.github.libretube.extensions.dpToPx
|
||||
import com.github.libretube.extensions.setOnDismissListener
|
||||
import com.github.libretube.extensions.toastFromMainDispatcher
|
||||
import com.github.libretube.helpers.ImageHelper
|
||||
import com.github.libretube.helpers.NavigationHelper
|
||||
@ -290,8 +290,9 @@ class PlaylistFragment : DynamicLayoutManagerFragment() {
|
||||
if (!isBookmarked) return
|
||||
withContext(Dispatchers.IO) {
|
||||
// update the playlist thumbnail and title if bookmarked
|
||||
val playlistBookmark = DatabaseHolder.Database.playlistBookmarkDao().findById(playlistId)
|
||||
?: return@withContext
|
||||
val playlistBookmark =
|
||||
DatabaseHolder.Database.playlistBookmarkDao().findById(playlistId)
|
||||
?: return@withContext
|
||||
if (playlistBookmark.thumbnailUrl != playlist.thumbnailUrl ||
|
||||
playlistBookmark.playlistName != playlist.name ||
|
||||
playlistBookmark.videos != playlist.videos
|
||||
@ -363,28 +364,10 @@ class PlaylistFragment : DynamicLayoutManagerFragment() {
|
||||
|
||||
// listener for swiping to the left or right
|
||||
if (playlistType != PlaylistType.PUBLIC) {
|
||||
val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(
|
||||
0,
|
||||
ItemTouchHelper.LEFT
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
playlistAdapter!!.removeFromPlaylist(
|
||||
_binding?.root ?: return,
|
||||
viewHolder.absoluteAdapterPosition
|
||||
)
|
||||
}
|
||||
binding.playlistRecView.setOnDismissListener { position ->
|
||||
val rootView = _binding?.root ?: return@setOnDismissListener
|
||||
playlistAdapter!!.removeFromPlaylist(rootView, position)
|
||||
}
|
||||
|
||||
val itemTouchHelper = ItemTouchHelper(itemTouchCallback)
|
||||
itemTouchHelper.attachToRecyclerView(binding.playlistRecView)
|
||||
}
|
||||
|
||||
updatePlaylistDuration()
|
||||
|
@ -15,7 +15,6 @@ import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.room.withTransaction
|
||||
import com.github.libretube.R
|
||||
@ -27,6 +26,7 @@ import com.github.libretube.db.DatabaseHolder.Database
|
||||
import com.github.libretube.db.obj.WatchHistoryItem
|
||||
import com.github.libretube.extensions.ceilHalf
|
||||
import com.github.libretube.extensions.dpToPx
|
||||
import com.github.libretube.extensions.setOnDismissListener
|
||||
import com.github.libretube.helpers.NavigationHelper
|
||||
import com.github.libretube.helpers.PreferenceHelper
|
||||
import com.github.libretube.helpers.ProxyHelper
|
||||
@ -198,27 +198,10 @@ class WatchHistoryFragment : DynamicLayoutManagerFragment() {
|
||||
binding.historyEmpty.isGone = true
|
||||
binding.historyContainer.isVisible = true
|
||||
|
||||
val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(
|
||||
0,
|
||||
ItemTouchHelper.LEFT
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
val position = viewHolder.absoluteAdapterPosition
|
||||
watchHistoryAdapter.removeFromWatchHistory(position)
|
||||
}
|
||||
binding.watchHistoryRecView.setOnDismissListener { position ->
|
||||
watchHistoryAdapter.removeFromWatchHistory(position)
|
||||
}
|
||||
|
||||
val itemTouchHelper = ItemTouchHelper(itemTouchCallback)
|
||||
itemTouchHelper.attachToRecyclerView(binding.watchHistoryRecView)
|
||||
|
||||
// observe changes to indicate if the history is empty
|
||||
watchHistoryAdapter.registerAdapterDataObserver(object :
|
||||
RecyclerView.AdapterDataObserver() {
|
||||
|
@ -7,13 +7,12 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.databinding.DialogSubscriptionGroupsBinding
|
||||
import com.github.libretube.db.DatabaseHolder
|
||||
import com.github.libretube.db.obj.SubscriptionGroup
|
||||
import com.github.libretube.extensions.move
|
||||
import com.github.libretube.extensions.setOnDraggedListener
|
||||
import com.github.libretube.ui.adapters.SubscriptionGroupsAdapter
|
||||
import com.github.libretube.ui.models.EditChannelGroupsModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -56,28 +55,11 @@ class ChannelGroupsSheet : ExpandedBottomSheet() {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val callback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
|
||||
0
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
val from = viewHolder.absoluteAdapterPosition
|
||||
val to = target.absoluteAdapterPosition
|
||||
adapter.groups.move(from, to)
|
||||
adapter.notifyItemMoved(from, to)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
|
||||
binding.groupsRV.setOnDraggedListener { from, to ->
|
||||
adapter.groups.move(from, to)
|
||||
adapter.notifyItemMoved(from, to)
|
||||
}
|
||||
|
||||
val itemTouchHelper = ItemTouchHelper(callback)
|
||||
itemTouchHelper.attachToRecyclerView(binding.groupsRV)
|
||||
|
||||
return binding.root
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ import android.view.ViewGroup
|
||||
import androidx.media3.common.Player
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.databinding.QueueBottomSheetBinding
|
||||
import com.github.libretube.db.DatabaseHelper
|
||||
import com.github.libretube.db.DatabaseHolder
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.extensions.setActionListener
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.adapters.PlayingQueueAdapter
|
||||
import com.github.libretube.ui.dialogs.AddToPlaylistDialog
|
||||
@ -84,37 +84,23 @@ class PlayingQueueSheet : ExpandedBottomSheet() {
|
||||
showWatchPositionsOptions()
|
||||
}
|
||||
|
||||
val callback = object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
|
||||
ItemTouchHelper.LEFT
|
||||
) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
val from = viewHolder.absoluteAdapterPosition
|
||||
val to = target.absoluteAdapterPosition
|
||||
|
||||
PlayingQueue.move(from, to)
|
||||
adapter.notifyItemMoved(from, to)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
val position = viewHolder.absoluteAdapterPosition
|
||||
binding.optionsRecycler.setActionListener(
|
||||
swipeDirections = arrayOf(ItemTouchHelper.LEFT),
|
||||
dragDirections = arrayOf(ItemTouchHelper.UP, ItemTouchHelper.DOWN),
|
||||
onDismissedListener = { position ->
|
||||
if (position == PlayingQueue.currentIndex()) {
|
||||
adapter.notifyItemChanged(position)
|
||||
return
|
||||
return@setActionListener
|
||||
}
|
||||
PlayingQueue.remove(position)
|
||||
adapter.notifyItemRemoved(position)
|
||||
adapter.notifyItemRangeChanged(position, adapter.itemCount)
|
||||
},
|
||||
onDragListener = { from, to ->
|
||||
PlayingQueue.move(from, to)
|
||||
adapter.notifyItemMoved(from, to)
|
||||
}
|
||||
}
|
||||
|
||||
val itemTouchHelper = ItemTouchHelper(callback)
|
||||
itemTouchHelper.attachToRecyclerView(binding.optionsRecycler)
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateRepeatButton() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user