From 38859c43f6ba009f8a0cca103855778bcb849a14 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 31 Jan 2023 17:34:40 +0100 Subject: [PATCH] [Audio player] Swipe listener --- .../ui/fragments/AudioPlayerFragment.kt | 40 ++++++--- .../ui/interfaces/AudioPlayerOptions.kt | 10 +++ .../listeners/AudioPlayerThumbnailListener.kt | 83 +++++++++++++++++++ .../libretube/ui/views/CustomExoPlayerView.kt | 4 +- 4 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/com/github/libretube/ui/interfaces/AudioPlayerOptions.kt create mode 100644 app/src/main/java/com/github/libretube/ui/listeners/AudioPlayerThumbnailListener.kt diff --git a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt index 93a6a39b9..375308c6c 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/AudioPlayerFragment.kt @@ -1,5 +1,6 @@ package com.github.libretube.ui.fragments +import android.annotation.SuppressLint import android.content.ComponentName import android.content.Context import android.content.Intent @@ -9,6 +10,7 @@ import android.os.Handler import android.os.IBinder import android.os.Looper import android.text.format.DateUtils +import android.util.Log import android.view.LayoutInflater import android.view.View 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.enums.ShareObjectType 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.services.BackgroundMode import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.base.BaseFragment 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.PlayingQueueSheet 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 -class AudioPlayerFragment : BaseFragment() { +class AudioPlayerFragment : BaseFragment(), AudioPlayerOptions { private lateinit var binding: FragmentAudioPlayerBinding + private lateinit var audioHelper: AudioHelper + private val onTrackChangeListener: (StreamItem) -> Unit = { updateStreamInfo() } @@ -64,6 +71,7 @@ class AudioPlayerFragment : BaseFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + audioHelper = AudioHelper(requireContext()) Intent(activity, BackgroundMode::class.java).also { intent -> activity?.bindService(intent, connection, Context.BIND_AUTO_CREATE) } @@ -78,6 +86,7 @@ class AudioPlayerFragment : BaseFragment() { return binding.root } + @SuppressLint("ClickableViewAccessibility") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -129,13 +138,8 @@ class AudioPlayerFragment : BaseFragment() { ).show(childFragmentManager, null) } - binding.thumbnail.setOnClickListener { - val current = PlayingQueue.getCurrent() - current?.let { - VideoOptionsBottomSheet(it.url!!.toID(), it.title!!) - .show(childFragmentManager) - } - } + val listener = AudioPlayerThumbnailListener(binding.thumbnail, this) + binding.thumbnail.setOnTouchListener(listener) // Listen for track changes due to autoplay or the notification PlayingQueue.addOnTrackChangedListener(onTrackChangeListener) @@ -232,4 +236,18 @@ class AudioPlayerFragment : BaseFragment() { 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") + } } diff --git a/app/src/main/java/com/github/libretube/ui/interfaces/AudioPlayerOptions.kt b/app/src/main/java/com/github/libretube/ui/interfaces/AudioPlayerOptions.kt new file mode 100644 index 000000000..eddb6387b --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/interfaces/AudioPlayerOptions.kt @@ -0,0 +1,10 @@ +package com.github.libretube.ui.interfaces + +interface AudioPlayerOptions { + + fun onSingleTap() + + fun onSwipe(distanceY: Float) + + fun onSwipeEnd() +} diff --git a/app/src/main/java/com/github/libretube/ui/listeners/AudioPlayerThumbnailListener.kt b/app/src/main/java/com/github/libretube/ui/listeners/AudioPlayerThumbnailListener.kt new file mode 100644 index 000000000..ba82efdfc --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/listeners/AudioPlayerThumbnailListener.kt @@ -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 + } +} diff --git a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt index 7b5d65c5a..f6681d921 100644 --- a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt +++ b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt @@ -196,7 +196,9 @@ internal class CustomExoPlayerView( } private fun cancelHideControllerTask() { - handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN) + runCatching { + handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN) + } } override fun hideController() {