diff --git a/app/src/main/java/org/mosad/teapod/PlayerActivity.kt b/app/src/main/java/org/mosad/teapod/PlayerActivity.kt index a13392f..b919fc2 100644 --- a/app/src/main/java/org/mosad/teapod/PlayerActivity.kt +++ b/app/src/main/java/org/mosad/teapod/PlayerActivity.kt @@ -11,7 +11,6 @@ import android.view.* import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GestureDetectorCompat import androidx.core.view.isVisible -import androidx.core.view.postDelayed import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.Player @@ -23,7 +22,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory import com.google.android.exoplayer2.util.Util import kotlinx.android.synthetic.main.activity_player.* import kotlinx.android.synthetic.main.player_controls.* -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.ui.fragments.MediaFragment @@ -34,7 +36,6 @@ import java.util.* import java.util.concurrent.TimeUnit import kotlin.concurrent.scheduleAtFixedRate - class PlayerActivity : AppCompatActivity() { private lateinit var player: SimpleExoPlayer @@ -257,12 +258,52 @@ class PlayerActivity : AppCompatActivity() { Log.d(javaClass.name, "Released player") } + /** + * TODO set position of rewind/fast forward indicators programmatically + */ + private fun rewind() { player.seekTo(player.currentPosition - rwdTime) + + // hide/show needed components + exo_double_tap_indicator.visibility = View.VISIBLE + ffwd_10_indicator.visibility = View.INVISIBLE + ffwd_10.visibility = View.INVISIBLE + + rwd_10_indicator.onAnimationEndCallback = { + exo_double_tap_indicator.visibility = View.GONE + ffwd_10_indicator.visibility = View.VISIBLE + ffwd_10.visibility = View.VISIBLE + } + + // run animation + rwd_10_indicator.runOnClickAnimation() } private fun forward() { player.seekTo(player.currentPosition + fwdTime) + + // hide/show needed components + exo_double_tap_indicator.visibility = View.VISIBLE + rwd_10_indicator.visibility = View.INVISIBLE + ffwd_10.visibility = View.INVISIBLE + + ffwd_10_indicator.onAnimationEndCallback = { + exo_double_tap_indicator.visibility = View.GONE + rwd_10_indicator.visibility = View.VISIBLE + ffwd_10.visibility = View.VISIBLE + } + + // run animation + ffwd_10_indicator.runOnClickAnimation() + } + + private fun togglePausePlay() { + if (player.isPlaying) { + player.pause() + } else { + player.play() + } } private fun playNextEpisode() { @@ -282,7 +323,7 @@ class PlayerActivity : AppCompatActivity() { // watchedCallback for next ep currentEpisode = nextEp // set current ep to next ep episodeId = nextEp.id - MediaFragment.instance.updateWatchedState(nextEp) // TODO i don't like this + MediaFragment.instance.updateWatchedState(nextEp) nextEpisode = selectNextEpisode() } @@ -362,15 +403,14 @@ class PlayerActivity : AppCompatActivity() { button_next_ep.animate() .alpha(0.0f) .setListener(object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator?) { - super.onAnimationEnd(animation) - button_next_ep.visibility = View.GONE - } - }) + override fun onAnimationEnd(animation: Animator?) { + super.onAnimationEnd(animation) + button_next_ep.visibility = View.GONE + } + }) } - inner class PlayerGestureListener : GestureDetector.SimpleOnGestureListener() { /** @@ -386,22 +426,7 @@ class PlayerActivity : AppCompatActivity() { */ override fun onDoubleTap(e: MotionEvent?): Boolean { val eventPosX = e?.x?.toInt() ?: 0 - val eventPosY = e?.y?.toInt() ?: 0 val viewCenterX = video_view.measuredWidth / 2 - val viewCenterY = video_view.measuredHeight / 2 - - // Show ripple effect (Jellyfin Android App) TODO replace this with a netflix player like animation? - video_view.foreground?.apply { - val left = if (eventPosX < viewCenterX) 0 else viewCenterX - val right = if (eventPosX < viewCenterX) viewCenterX else video_view.measuredWidth - - setBounds(left, viewCenterY - viewCenterX / 2, right, viewCenterY + viewCenterX / 2) - setHotspot(eventPosX.toFloat(), eventPosY.toFloat()) - state = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed) - video_view.postDelayed(100) { - state = IntArray(0) - } - } // if the event position is on the left side rewind, if it's on the right forward if (eventPosX < viewCenterX) { @@ -420,6 +445,10 @@ class PlayerActivity : AppCompatActivity() { return true } + override fun onLongPress(e: MotionEvent?) { + togglePausePlay() + } + } } diff --git a/app/src/main/java/org/mosad/teapod/ui/components/FastForwardButton.kt b/app/src/main/java/org/mosad/teapod/ui/components/FastForwardButton.kt index 74f282a..cabe34a 100644 --- a/app/src/main/java/org/mosad/teapod/ui/components/FastForwardButton.kt +++ b/app/src/main/java/org/mosad/teapod/ui/components/FastForwardButton.kt @@ -10,24 +10,18 @@ import android.widget.FrameLayout import kotlinx.android.synthetic.main.button_fast_forward.view.* import org.mosad.teapod.R -class FastForwardButton(context: Context, attrs: AttributeSet): FrameLayout(context, attrs) { +class FastForwardButton(context: Context, attrs: AttributeSet?): FrameLayout(context, attrs) { private val animationDuration: Long = 800 + private val buttonAnimation: ObjectAnimator + private val labelAnimation: ObjectAnimator + + var onAnimationEndCallback: (() -> Unit)? = null init { inflate(context, R.layout.button_fast_forward, this) - } - fun setOnButtonClickListener(func: FastForwardButton.() -> Unit) { - imageButton.setOnClickListener { - func() - runOnClickAnimation() - } - } - - fun runOnClickAnimation() { - // run button animation - ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, 50f).apply { + buttonAnimation = ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, 50f).apply { duration = animationDuration / 4 repeatCount = 1 repeatMode = ObjectAnimator.REVERSE @@ -36,29 +30,39 @@ class FastForwardButton(context: Context, attrs: AttributeSet): FrameLayout(cont imageButton.isEnabled = false // disable button imageButton.setBackgroundResource(R.drawable.ic_baseline_forward_24) } - override fun onAnimationEnd(animation: Animator?) { - imageButton.isEnabled = true // enable button - } }) - start() } - // run lbl animation - textView.visibility = View.VISIBLE - ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, 35f).apply { + labelAnimation = ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, 35f).apply { duration = animationDuration addListener(object : AnimatorListenerAdapter() { + // the label animation takes longer then the button animation, reset stuff in here override fun onAnimationEnd(animation: Animator?) { imageButton.isEnabled = true // enable button imageButton.setBackgroundResource(R.drawable.ic_baseline_forward_10_24) textView.visibility = View.GONE textView.animate().translationX(0f) + + onAnimationEndCallback?.invoke() } }) - start() } + } + fun setOnButtonClickListener(func: FastForwardButton.() -> Unit) { + imageButton.setOnClickListener { + func() + } + } + + fun runOnClickAnimation() { + // run button animation + buttonAnimation.start() + + // run lbl animation + textView.visibility = View.VISIBLE + labelAnimation.start() } } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/ui/components/RewindButton.kt b/app/src/main/java/org/mosad/teapod/ui/components/RewindButton.kt index 41f7064..a72ec74 100644 --- a/app/src/main/java/org/mosad/teapod/ui/components/RewindButton.kt +++ b/app/src/main/java/org/mosad/teapod/ui/components/RewindButton.kt @@ -13,21 +13,15 @@ import org.mosad.teapod.R class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context, attrs) { private val animationDuration: Long = 800 + private val buttonAnimation: ObjectAnimator + private val labelAnimation: ObjectAnimator + + var onAnimationEndCallback: (() -> Unit)? = null init { inflate(context, R.layout.button_rewind, this) - } - fun setOnButtonClickListener(func: RewindButton.() -> Unit) { - imageButton.setOnClickListener { - func() - runOnClickAnimation() - } - } - - fun runOnClickAnimation() { - // run button animation - ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, -50f).apply { + buttonAnimation = ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, -50f).apply { duration = animationDuration / 4 repeatCount = 1 repeatMode = ObjectAnimator.REVERSE @@ -36,16 +30,10 @@ class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context, imageButton.isEnabled = false // disable button imageButton.setBackgroundResource(R.drawable.ic_baseline_rewind_24) } - override fun onAnimationEnd(animation: Animator?) { - imageButton.isEnabled = true // enable button - } }) - start() } - // run lbl animation - textView.visibility = View.VISIBLE - ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, -35f).apply { + labelAnimation = ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, -35f).apply { duration = animationDuration addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { @@ -54,11 +42,26 @@ class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context, textView.visibility = View.GONE textView.animate().translationX(0f) + + onAnimationEndCallback?.invoke() } }) - start() } + } + fun setOnButtonClickListener(func: RewindButton.() -> Unit) { + imageButton.setOnClickListener { + func() + } + } + + fun runOnClickAnimation() { + // run button animation + buttonAnimation.start() + + // run lbl animation + textView.visibility = View.VISIBLE + labelAnimation.start() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_player.xml b/app/src/main/res/layout/activity_player.xml index a8be9bf..cca2cc3 100644 --- a/app/src/main/res/layout/activity_player.xml +++ b/app/src/main/res/layout/activity_player.xml @@ -2,10 +2,11 @@ + app:rewind_increment="10000" /> + + + + + + + + + + + + + + + + +