[Audio player] Swipe listener

This commit is contained in:
Bnyro 2023-01-31 17:34:40 +01:00
parent b734c69ea8
commit 38859c43f6
4 changed files with 125 additions and 12 deletions

View File

@ -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")
}
} }

View File

@ -0,0 +1,10 @@
package com.github.libretube.ui.interfaces
interface AudioPlayerOptions {
fun onSingleTap()
fun onSwipe(distanceY: Float)
fun onSwipeEnd()
}

View File

@ -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
}
}

View File

@ -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