diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index e9ad5cb3d..ee43cd1b5 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -20,10 +20,7 @@ import android.support.v4.media.session.MediaSessionCompat import android.text.Html import android.text.TextUtils import android.util.Log -import android.view.GestureDetector -import android.view.GestureDetector.SimpleOnGestureListener import android.view.LayoutInflater -import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.Toast @@ -63,6 +60,7 @@ import com.github.libretube.util.BackgroundHelper import com.github.libretube.util.ConnectionHelper import com.github.libretube.util.CronetHelper import com.github.libretube.util.DescriptionAdapter +import com.github.libretube.util.OnCustomEventListener import com.github.libretube.util.PlayerHelper import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.formatShort @@ -1096,50 +1094,17 @@ class PlayerFragment : Fragment() { val seekIncrementText = (seekIncrement / 1000).toString() doubleTapOverlayBinding.rewindTV.text = seekIncrementText doubleTapOverlayBinding.forwardTV.text = seekIncrementText - - // enable rewind button - val rewindGestureDetector = GestureDetector( - context, - object : SimpleOnGestureListener() { - override fun onDoubleTap(e: MotionEvent): Boolean { - rewind() - return super.onDoubleTap(e) - } - - override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { - toggleController() - return super.onSingleTapConfirmed(e) + binding.player.setOnDoubleTapListener( + object : OnCustomEventListener { + override fun onEvent(x: Float) { + val width = exoPlayerView.width + when { + width * 0.45 > x -> rewind() + width * 0.55 < x -> forward() + } } } ) - - doubleTapOverlayBinding.rewindFL.setOnTouchListener { view, event -> - rewindGestureDetector.onTouchEvent(event) - view.performClick() - true - } - - // enable forward button - val forwardGestureDetector = GestureDetector( - context, - object : SimpleOnGestureListener() { - override fun onDoubleTap(e: MotionEvent): Boolean { - forward() - return super.onDoubleTap(e) - } - - override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { - toggleController() - return super.onSingleTapConfirmed(e) - } - } - ) - - doubleTapOverlayBinding.forwardFL.setOnTouchListener { view, event -> - forwardGestureDetector.onTouchEvent(event) - view.performClick() - true - } } private fun rewind() { @@ -1555,10 +1520,10 @@ class PlayerFragment : Fragment() { // disable double tap to seek when the player is locked if (isLocked) { // enable fast forward and rewind by double tapping - binding.doubleTapOverlay.visibility = View.VISIBLE + enableDoubleTapToSeek() } else { // disable fast forward and rewind by double tapping - binding.doubleTapOverlay.visibility = View.GONE + binding.player.setOnDoubleTapListener(null) } } diff --git a/app/src/main/java/com/github/libretube/util/DoubleTapListener.kt b/app/src/main/java/com/github/libretube/util/DoubleTapListener.kt new file mode 100644 index 000000000..4374b9597 --- /dev/null +++ b/app/src/main/java/com/github/libretube/util/DoubleTapListener.kt @@ -0,0 +1,45 @@ +package com.github.libretube.util + +import android.os.Handler +import android.os.Looper +import android.os.SystemClock +import android.view.View + +abstract class DoubleTapListener : View.OnClickListener { + + private var isSingleEvent = false + private val doubleClickQualificationSpanInMillis: Long + private var timestampLastClick: Long + private val handler: Handler + private val runnable: Runnable + + override fun onClick(v: View?) { + if (SystemClock.elapsedRealtime() - timestampLastClick < doubleClickQualificationSpanInMillis) { + isSingleEvent = false + handler.removeCallbacks(runnable) + onDoubleClick() + return + } + isSingleEvent = true + handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN) + timestampLastClick = SystemClock.elapsedRealtime() + } + + abstract fun onDoubleClick() + abstract fun onSingleClick() + + companion object { + private const val DEFAULT_QUALIFICATION_SPAN: Long = 200 + } + + init { + doubleClickQualificationSpanInMillis = DEFAULT_QUALIFICATION_SPAN + timestampLastClick = 0 + handler = Handler(Looper.getMainLooper()) + runnable = Runnable { + if (isSingleEvent) { + onSingleClick() + } + } + } +} diff --git a/app/src/main/java/com/github/libretube/util/OnCustomEventListener.kt b/app/src/main/java/com/github/libretube/util/OnCustomEventListener.kt new file mode 100644 index 000000000..8884b00f1 --- /dev/null +++ b/app/src/main/java/com/github/libretube/util/OnCustomEventListener.kt @@ -0,0 +1,5 @@ +package com.github.libretube.util + +interface OnCustomEventListener { + fun onEvent(x: Float) +} diff --git a/app/src/main/java/com/github/libretube/views/CustomExoPlayerView.kt b/app/src/main/java/com/github/libretube/views/CustomExoPlayerView.kt index 386c528bc..dbcbae23e 100644 --- a/app/src/main/java/com/github/libretube/views/CustomExoPlayerView.kt +++ b/app/src/main/java/com/github/libretube/views/CustomExoPlayerView.kt @@ -7,8 +7,11 @@ import android.view.MotionEvent import android.view.View import com.github.libretube.R import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding +import com.github.libretube.util.DoubleTapListener +import com.github.libretube.util.OnCustomEventListener import com.google.android.exoplayer2.ui.StyledPlayerView +@SuppressLint("ClickableViewAccessibility") internal class CustomExoPlayerView( context: Context, attributeSet: AttributeSet? = null @@ -16,12 +19,39 @@ internal class CustomExoPlayerView( val TAG = "CustomExoPlayerView" val binding: ExoStyledPlayerControlViewBinding = ExoStyledPlayerControlViewBinding.bind(this) + var doubleTapListener: OnCustomEventListener? = null + + var lastToggled: Long? = null + var xPos = 0F + + fun setOnDoubleTapListener( + eventListener: OnCustomEventListener? + ) { + doubleTapListener = eventListener + } + + private fun toggleController() { + lastToggled = System.currentTimeMillis() + if (isControllerFullyVisible) hideController() else showController() + } + + val doubleTouchListener = object : DoubleTapListener() { + override fun onDoubleClick() { + doubleTapListener?.onEvent(xPos) + } + + override fun onSingleClick() { + toggleController() + } + } + init { setControllerVisibilityListener { // hide the advanced options binding.toggleOptions.animate().rotation(0F).setDuration(250).start() binding.advancedOptions.visibility = View.GONE } + setOnClickListener(doubleTouchListener) } override fun hideController() { @@ -44,17 +74,9 @@ internal class CustomExoPlayerView( doubleTapOverlay.layoutParams = params } - @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean { - when (event.action) { - MotionEvent.ACTION_DOWN -> { - if (isControllerFullyVisible) { - hideController() - } else { - showController() - } - } - } + xPos = event.x + doubleTouchListener.onClick(this) return false } } diff --git a/app/src/main/res/layout/double_tap_overlay.xml b/app/src/main/res/layout/double_tap_overlay.xml index 4bd49b822..e15dc5a15 100644 --- a/app/src/main/res/layout/double_tap_overlay.xml +++ b/app/src/main/res/layout/double_tap_overlay.xml @@ -1,6 +1,5 @@ - + android:layout_weight=".40" + android:clickable="false" + android:focusable="false"> + android:layout_weight=".40" + android:clickable="false" + android:focusable="false">