mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 16:30:31 +05:30
[Audio player] Swipe listener
This commit is contained in:
parent
b734c69ea8
commit
38859c43f6
@ -1,5 +1,6 @@
|
|||||||
package com.github.libretube.ui.fragments
|
package com.github.libretube.ui.fragments
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -9,6 +10,7 @@ import android.os.Handler
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -18,21 +20,26 @@ import com.github.libretube.api.obj.StreamItem
|
|||||||
import com.github.libretube.databinding.FragmentAudioPlayerBinding
|
import com.github.libretube.databinding.FragmentAudioPlayerBinding
|
||||||
import com.github.libretube.enums.ShareObjectType
|
import com.github.libretube.enums.ShareObjectType
|
||||||
import com.github.libretube.extensions.toID
|
import com.github.libretube.extensions.toID
|
||||||
|
import com.github.libretube.helpers.AudioHelper
|
||||||
|
import com.github.libretube.helpers.BackgroundHelper
|
||||||
|
import com.github.libretube.helpers.ImageHelper
|
||||||
|
import com.github.libretube.helpers.NavigationHelper
|
||||||
import com.github.libretube.obj.ShareData
|
import com.github.libretube.obj.ShareData
|
||||||
import com.github.libretube.services.BackgroundMode
|
import com.github.libretube.services.BackgroundMode
|
||||||
import com.github.libretube.ui.activities.MainActivity
|
import com.github.libretube.ui.activities.MainActivity
|
||||||
import com.github.libretube.ui.base.BaseFragment
|
import com.github.libretube.ui.base.BaseFragment
|
||||||
import com.github.libretube.ui.dialogs.ShareDialog
|
import com.github.libretube.ui.dialogs.ShareDialog
|
||||||
|
import com.github.libretube.ui.interfaces.AudioPlayerOptions
|
||||||
|
import com.github.libretube.ui.listeners.AudioPlayerThumbnailListener
|
||||||
import com.github.libretube.ui.sheets.PlaybackOptionsSheet
|
import com.github.libretube.ui.sheets.PlaybackOptionsSheet
|
||||||
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
||||||
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
|
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
|
||||||
import com.github.libretube.helpers.BackgroundHelper
|
|
||||||
import com.github.libretube.helpers.ImageHelper
|
|
||||||
import com.github.libretube.helpers.NavigationHelper
|
|
||||||
import com.github.libretube.util.PlayingQueue
|
import com.github.libretube.util.PlayingQueue
|
||||||
|
|
||||||
class AudioPlayerFragment : BaseFragment() {
|
class AudioPlayerFragment : BaseFragment(), AudioPlayerOptions {
|
||||||
private lateinit var binding: FragmentAudioPlayerBinding
|
private lateinit var binding: FragmentAudioPlayerBinding
|
||||||
|
private lateinit var audioHelper: AudioHelper
|
||||||
|
|
||||||
private val onTrackChangeListener: (StreamItem) -> Unit = {
|
private val onTrackChangeListener: (StreamItem) -> Unit = {
|
||||||
updateStreamInfo()
|
updateStreamInfo()
|
||||||
}
|
}
|
||||||
@ -64,6 +71,7 @@ class AudioPlayerFragment : BaseFragment() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
audioHelper = AudioHelper(requireContext())
|
||||||
Intent(activity, BackgroundMode::class.java).also { intent ->
|
Intent(activity, BackgroundMode::class.java).also { intent ->
|
||||||
activity?.bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
activity?.bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||||
}
|
}
|
||||||
@ -78,6 +86,7 @@ class AudioPlayerFragment : BaseFragment() {
|
|||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
@ -129,13 +138,8 @@ class AudioPlayerFragment : BaseFragment() {
|
|||||||
).show(childFragmentManager, null)
|
).show(childFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.thumbnail.setOnClickListener {
|
val listener = AudioPlayerThumbnailListener(binding.thumbnail, this)
|
||||||
val current = PlayingQueue.getCurrent()
|
binding.thumbnail.setOnTouchListener(listener)
|
||||||
current?.let {
|
|
||||||
VideoOptionsBottomSheet(it.url!!.toID(), it.title!!)
|
|
||||||
.show(childFragmentManager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for track changes due to autoplay or the notification
|
// Listen for track changes due to autoplay or the notification
|
||||||
PlayingQueue.addOnTrackChangedListener(onTrackChangeListener)
|
PlayingQueue.addOnTrackChangedListener(onTrackChangeListener)
|
||||||
@ -232,4 +236,18 @@ class AudioPlayerFragment : BaseFragment() {
|
|||||||
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSingleTap() {
|
||||||
|
val current = PlayingQueue.getCurrent()
|
||||||
|
VideoOptionsBottomSheet(current?.url?.toID() ?: return, current.title ?: return)
|
||||||
|
.show(childFragmentManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipe(distanceY: Float) {
|
||||||
|
Log.e("swiping", distanceY.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwipeEnd() {
|
||||||
|
Log.e("ended", "ended")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.libretube.ui.interfaces
|
||||||
|
|
||||||
|
interface AudioPlayerOptions {
|
||||||
|
|
||||||
|
fun onSingleTap()
|
||||||
|
|
||||||
|
fun onSwipe(distanceY: Float)
|
||||||
|
|
||||||
|
fun onSwipeEnd()
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.github.libretube.ui.listeners
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.view.GestureDetector
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
|
import com.github.libretube.ui.interfaces.AudioPlayerOptions
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class AudioPlayerThumbnailListener(private val view: View, private val listener: AudioPlayerOptions) :
|
||||||
|
View.OnTouchListener {
|
||||||
|
|
||||||
|
private val width get() = view.width
|
||||||
|
private val height get() = view.height
|
||||||
|
|
||||||
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
|
private val gestureDetector: GestureDetector
|
||||||
|
|
||||||
|
private var isMoving = false
|
||||||
|
|
||||||
|
var wasClick = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
gestureDetector = GestureDetector(view.context, GestureListener(), handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||||
|
if (event.action == MotionEvent.ACTION_UP && isMoving) {
|
||||||
|
isMoving = false
|
||||||
|
listener.onSwipeEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
runCatching {
|
||||||
|
gestureDetector.onTouchEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
|
||||||
|
|
||||||
|
override fun onDown(e: MotionEvent): Boolean {
|
||||||
|
// Initially assume this event is for click
|
||||||
|
wasClick = true
|
||||||
|
if (isMoving) return false
|
||||||
|
|
||||||
|
handler.postDelayed(100) {
|
||||||
|
if (wasClick) listener.onSingleTap()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScroll(
|
||||||
|
e1: MotionEvent,
|
||||||
|
e2: MotionEvent,
|
||||||
|
distanceX: Float,
|
||||||
|
distanceY: Float
|
||||||
|
): Boolean {
|
||||||
|
val insideThreshHold = abs(e2.y - e1.y) <= MOVEMENT_THRESHOLD
|
||||||
|
|
||||||
|
// If the movement is inside threshold or scroll is horizontal then return false
|
||||||
|
if (!isMoving && (insideThreshHold || abs(distanceX) > abs(distanceY))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
isMoving = true
|
||||||
|
wasClick = false
|
||||||
|
|
||||||
|
listener.onSwipe(distanceY)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MOVEMENT_THRESHOLD = 10
|
||||||
|
}
|
||||||
|
}
|
@ -196,8 +196,10 @@ internal class CustomExoPlayerView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelHideControllerTask() {
|
private fun cancelHideControllerTask() {
|
||||||
|
runCatching {
|
||||||
handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN)
|
handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun hideController() {
|
override fun hideController() {
|
||||||
// remove the callback to hide the controller
|
// remove the callback to hide the controller
|
||||||
|
Loading…
x
Reference in New Issue
Block a user