diff --git a/app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt index c6235b855..f934b8db9 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/OfflinePlayerActivity.kt @@ -85,7 +85,7 @@ class OfflinePlayerActivity : BaseActivity() { super.onPlaybackStateChanged(playbackState) // setup seekbar preview if (playbackState == Player.STATE_READY) { - binding.player.binding.exoProgress.addListener( + binding.player.binding.exoProgress.addSeekBarListener( SeekbarPreviewListener( timeFrameReceiver ?: return, binding.player.binding, diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 40ec389fe..841cf54ec 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -948,8 +948,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { player = exoPlayer } - playerBinding.exoProgress.setPlayer(exoPlayer) - initializePlayerView() // don't continue playback when the fragment is re-created after Android killed it @@ -1095,7 +1093,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { playerBinding.seekbarPreview.isGone = true seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) } seekBarPreviewListener = createSeekbarPreviewListener().also { - playerBinding.exoProgress.addListener(it) + playerBinding.exoProgress.addSeekBarListener(it) } } 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 2910a9127..a9343c563 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 @@ -182,8 +182,9 @@ open class CustomExoPlayerView( } }) + player?.let { binding.exoProgress.setPlayer(it) } // prevent the controls from disappearing while scrubbing the time bar - binding.exoProgress.addListener(object : TimeBar.OnScrubListener { + binding.exoProgress.addSeekBarListener(object : TimeBar.OnScrubListener { override fun onScrubStart(timeBar: TimeBar, position: Long) { cancelHideControllerTask() } diff --git a/app/src/main/java/com/github/libretube/ui/views/DismissableTimeBar.kt b/app/src/main/java/com/github/libretube/ui/views/DismissableTimeBar.kt new file mode 100644 index 000000000..3eba4e291 --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/views/DismissableTimeBar.kt @@ -0,0 +1,66 @@ +package com.github.libretube.ui.views + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.media3.common.Player +import androidx.media3.common.util.UnstableApi +import androidx.media3.ui.DefaultTimeBar +import androidx.media3.ui.PlayerControlView +import androidx.media3.ui.TimeBar +import androidx.media3.ui.TimeBar.OnScrubListener +import com.github.libretube.extensions.dpToPx + +@UnstableApi +open class DismissableTimeBar( + context: Context, + attributeSet: AttributeSet? = null +): DefaultTimeBar(context, attributeSet) { + private var shouldAddListener = false + var exoPlayer: Player? = null + private var lastYPosition = 0f + + init { + addSeekBarListener(object : OnScrubListener { + override fun onScrubStart(timeBar: TimeBar, position: Long) = Unit + + override fun onScrubMove(timeBar: TimeBar, position: Long) = Unit + + override fun onScrubStop(timeBar: TimeBar, position: Long, canceled: Boolean) { + if (lastYPosition > MINIMUM_ACCEPTED_HEIGHT.dpToPx()) exoPlayer?.seekTo(position) + } + }) + } + + @SuppressLint("ClickableViewAccessibility") + override fun onTouchEvent(event: MotionEvent): Boolean { + lastYPosition = event.y + + return super.onTouchEvent(event) + } + + /** + * DO NOT CALL THIS METHOD DIRECTLY. Use [addSeekBarListener] instead! + */ + override fun addListener(listener: OnScrubListener) { + if (shouldAddListener) super.addListener(listener) + } + + /** + * Wrapper to circumvent adding the listener created by [PlayerControlView] + */ + fun addSeekBarListener(listener: OnScrubListener) { + shouldAddListener = true + addListener(listener) + shouldAddListener = false + } + + fun setPlayer(player: Player) { + this.exoPlayer = player + } + + companion object { + private const val MINIMUM_ACCEPTED_HEIGHT = -70f + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt b/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt index 5649c03a6..4b103b0a1 100644 --- a/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt +++ b/app/src/main/java/com/github/libretube/ui/views/MarkableTimeBar.kt @@ -7,9 +7,7 @@ import android.graphics.Rect import android.util.AttributeSet import android.view.View import androidx.core.view.marginLeft -import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi -import androidx.media3.ui.DefaultTimeBar import com.github.libretube.api.obj.Segment import com.github.libretube.extensions.dpToPx import com.github.libretube.helpers.PreferenceHelper @@ -23,10 +21,8 @@ import com.google.android.material.R class MarkableTimeBar( context: Context, attributeSet: AttributeSet? = null -) : DefaultTimeBar(context, attributeSet) { - +) : DismissableTimeBar(context, attributeSet) { private var segments = listOf() - private var player: Player? = null private var length: Int = 0 private val progressBarHeight = 2f.dpToPx() @@ -37,7 +33,7 @@ class MarkableTimeBar( } private fun drawSegments(canvas: Canvas) { - if (player == null) return + if (exoPlayer == null) return canvas.save() val horizontalOffset = (parent as View).marginLeft @@ -68,7 +64,7 @@ class MarkableTimeBar( } private fun Float.toLength(): Int { - return (this * 1000 / player!!.duration * length).toInt() + return (this * 1000 / exoPlayer!!.duration * length).toInt() } fun setSegments(segments: List) { @@ -78,8 +74,4 @@ class MarkableTimeBar( fun clearSegments() { segments = listOf() } - - fun setPlayer(player: Player) { - this.player = player - } }