mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 00:10:32 +05:30
Merge pull request #2908 from Isira-Seneviratne/postDelayed
Use Handler.postDelayed() extension function.
This commit is contained in:
commit
c7c9e4d47b
@ -31,6 +31,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
|
|||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.text.parseAsHtml
|
import androidx.core.text.parseAsHtml
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@ -210,9 +211,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
|||||||
PlayerEvent.Background -> {
|
PlayerEvent.Background -> {
|
||||||
playOnBackground()
|
playOnBackground()
|
||||||
// wait some time in order for the service to get started properly
|
// wait some time in order for the service to get started properly
|
||||||
handler.postDelayed({
|
handler.postDelayed(500) {
|
||||||
activity?.finish()
|
activity?.finish()
|
||||||
}, 500)
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
@ -476,10 +477,10 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
|||||||
channelId,
|
channelId,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
handler.postDelayed({
|
handler.postDelayed(500) {
|
||||||
NavigationHelper.startAudioPlayer(requireContext())
|
NavigationHelper.startAudioPlayer(requireContext())
|
||||||
killPlayerFragment()
|
killPlayerFragment()
|
||||||
}, 500)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setFullscreen() {
|
private fun setFullscreen() {
|
||||||
|
@ -6,6 +6,7 @@ import android.os.Looper
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
@ -144,7 +145,7 @@ class WatchHistoryFragment : BaseFragment() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// add a listener for scroll end, delay needed to prevent loading new ones the first time
|
// add a listener for scroll end, delay needed to prevent loading new ones the first time
|
||||||
Handler(Looper.getMainLooper()).postDelayed({
|
Handler(Looper.getMainLooper()).postDelayed(200) {
|
||||||
binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener {
|
binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener {
|
||||||
if (!binding.historyScrollView.canScrollVertically(1) && !isLoading) {
|
if (!binding.historyScrollView.canScrollVertically(1) && !isLoading) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
@ -152,6 +153,6 @@ class WatchHistoryFragment : BaseFragment() {
|
|||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 200)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package com.github.libretube.ui.tools
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.os.Process
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.github.libretube.constants.PreferenceKeys
|
import com.github.libretube.constants.PreferenceKeys
|
||||||
import com.github.libretube.ui.activities.MainActivity
|
import com.github.libretube.ui.activities.MainActivity
|
||||||
@ -25,38 +27,32 @@ object SleepTimer {
|
|||||||
""
|
""
|
||||||
).ifEmpty { return }
|
).ifEmpty { return }
|
||||||
|
|
||||||
handler.postDelayed(
|
handler.postDelayed(breakReminderPref.toLong() * 60 * 1000) {
|
||||||
{
|
var killApp = true
|
||||||
var killApp = true
|
val mainActivity = context as? MainActivity ?: return@postDelayed
|
||||||
val mainActivity = context as? MainActivity ?: return@postDelayed
|
val snackBar = Snackbar.make(
|
||||||
val snackBar = Snackbar.make(
|
mainActivity.binding.root,
|
||||||
mainActivity.binding.root,
|
R.string.take_a_break,
|
||||||
R.string.take_a_break,
|
Snackbar.LENGTH_INDEFINITE
|
||||||
Snackbar.LENGTH_INDEFINITE
|
)
|
||||||
)
|
.setAction(R.string.cancel) {
|
||||||
.setAction(R.string.cancel) {
|
killApp = false
|
||||||
killApp = false
|
|
||||||
}
|
|
||||||
snackBar.show()
|
|
||||||
(0..REACTION_INTERVAL).forEach {
|
|
||||||
handler.postDelayed({
|
|
||||||
val remainingTime = " (${REACTION_INTERVAL - it})"
|
|
||||||
snackBar.setText(context.getString(R.string.take_a_break) + remainingTime)
|
|
||||||
}, it * 1000)
|
|
||||||
}
|
}
|
||||||
handler.postDelayed(
|
snackBar.show()
|
||||||
killApp@{
|
for (i in 0..REACTION_INTERVAL) {
|
||||||
if (!killApp) return@killApp
|
handler.postDelayed(i * 1000) {
|
||||||
|
val remainingTime = " (${REACTION_INTERVAL - i})"
|
||||||
// kill the application
|
snackBar.setText(context.getString(R.string.take_a_break) + remainingTime)
|
||||||
mainActivity.finishAffinity()
|
}
|
||||||
mainActivity.finish()
|
}
|
||||||
android.os.Process.killProcess(android.os.Process.myPid())
|
handler.postDelayed(REACTION_INTERVAL * 1000) {
|
||||||
},
|
if (killApp) {
|
||||||
REACTION_INTERVAL * 1000
|
// kill the application
|
||||||
)
|
mainActivity.finishAffinity()
|
||||||
},
|
mainActivity.finish()
|
||||||
breakReminderPref.toLong() * 60 * 1000
|
Process.killProcess(Process.myPid())
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import android.widget.FrameLayout
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
@ -90,10 +91,6 @@ internal class CustomExoPlayerView(
|
|||||||
if (isControllerFullyVisible) hideController() else showController()
|
if (isControllerFullyVisible) hideController() else showController()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val hideControllerRunnable = Runnable {
|
|
||||||
hideController()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun initialize(
|
fun initialize(
|
||||||
playerViewInterface: OnlinePlayerOptions?,
|
playerViewInterface: OnlinePlayerOptions?,
|
||||||
doubleTapOverlayBinding: DoubleTapOverlayBinding,
|
doubleTapOverlayBinding: DoubleTapOverlayBinding,
|
||||||
@ -199,9 +196,7 @@ internal class CustomExoPlayerView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelHideControllerTask() {
|
private fun cancelHideControllerTask() {
|
||||||
runCatching {
|
handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN)
|
||||||
handler.removeCallbacks(hideControllerRunnable)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hideController() {
|
override fun hideController() {
|
||||||
@ -222,7 +217,9 @@ internal class CustomExoPlayerView(
|
|||||||
// remove the previous callback from the queue to prevent a flashing behavior
|
// remove the previous callback from the queue to prevent a flashing behavior
|
||||||
cancelHideControllerTask()
|
cancelHideControllerTask()
|
||||||
// automatically hide the controller after 2 seconds
|
// automatically hide the controller after 2 seconds
|
||||||
handler.postDelayed(hideControllerRunnable, AUTO_HIDE_CONTROLLER_DELAY)
|
handler.postDelayed(AUTO_HIDE_CONTROLLER_DELAY, HIDE_CONTROLLER_TOKEN) {
|
||||||
|
hideController()
|
||||||
|
}
|
||||||
super.showController()
|
super.showController()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,8 +377,10 @@ internal class CustomExoPlayerView(
|
|||||||
animateSeeking(rewindBTN, rewindIV, rewindTV, true)
|
animateSeeking(rewindBTN, rewindIV, rewindTV, true)
|
||||||
|
|
||||||
// start callback to hide the button
|
// start callback to hide the button
|
||||||
runnableHandler.removeCallbacks(hideRewindButtonRunnable)
|
runnableHandler.removeCallbacksAndMessages(HIDE_REWIND_BUTTON_TOKEN)
|
||||||
runnableHandler.postDelayed(hideRewindButtonRunnable, 700)
|
runnableHandler.postDelayed(700, HIDE_REWIND_BUTTON_TOKEN) {
|
||||||
|
rewindBTN.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,8 +392,10 @@ internal class CustomExoPlayerView(
|
|||||||
animateSeeking(forwardBTN, forwardIV, forwardTV, false)
|
animateSeeking(forwardBTN, forwardIV, forwardTV, false)
|
||||||
|
|
||||||
// start callback to hide the button
|
// start callback to hide the button
|
||||||
runnableHandler.removeCallbacks(hideForwardButtonRunnable)
|
runnableHandler.removeCallbacksAndMessages(HIDE_FORWARD_BUTTON_TOKEN)
|
||||||
runnableHandler.postDelayed(hideForwardButtonRunnable, 700)
|
runnableHandler.postDelayed(700, HIDE_FORWARD_BUTTON_TOKEN) {
|
||||||
|
forwardBTN.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,26 +439,15 @@ internal class CustomExoPlayerView(
|
|||||||
.setDuration((ANIMATION_DURATION * 1.5).toLong())
|
.setDuration((ANIMATION_DURATION * 1.5).toLong())
|
||||||
.withEndAction {
|
.withEndAction {
|
||||||
// move the text back into the button
|
// move the text back into the button
|
||||||
handler.postDelayed({
|
handler.postDelayed(100) {
|
||||||
textView.animate()
|
textView.animate()
|
||||||
.setDuration(ANIMATION_DURATION / 2)
|
.setDuration(ANIMATION_DURATION / 2)
|
||||||
.translationX(0f)
|
.translationX(0f)
|
||||||
.start()
|
.start()
|
||||||
}, 100)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val hideForwardButtonRunnable = Runnable {
|
|
||||||
doubleTapOverlayBinding?.forwardBTN?.apply {
|
|
||||||
this.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val hideRewindButtonRunnable = Runnable {
|
|
||||||
doubleTapOverlayBinding?.rewindBTN?.apply {
|
|
||||||
this.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initializeGestureProgress() {
|
private fun initializeGestureProgress() {
|
||||||
gestureViewBinding.brightnessProgressBar.let { bar ->
|
gestureViewBinding.brightnessProgressBar.let { bar ->
|
||||||
bar.progress =
|
bar.progress =
|
||||||
@ -701,12 +691,18 @@ internal class CustomExoPlayerView(
|
|||||||
// when a control is clicked, restart the countdown to hide the controller
|
// when a control is clicked, restart the countdown to hide the controller
|
||||||
if (isControllerFullyVisible) {
|
if (isControllerFullyVisible) {
|
||||||
cancelHideControllerTask()
|
cancelHideControllerTask()
|
||||||
handler.postDelayed(hideControllerRunnable, AUTO_HIDE_CONTROLLER_DELAY)
|
handler.postDelayed(AUTO_HIDE_CONTROLLER_DELAY, HIDE_CONTROLLER_TOKEN) {
|
||||||
|
hideController()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onInterceptTouchEvent(ev)
|
return super.onInterceptTouchEvent(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val HIDE_CONTROLLER_TOKEN = "hideController"
|
||||||
|
private const val HIDE_FORWARD_BUTTON_TOKEN = "hideForwardButton"
|
||||||
|
private const val HIDE_REWIND_BUTTON_TOKEN = "hideRewindButton"
|
||||||
|
|
||||||
private const val SUBTITLE_BOTTOM_PADDING_FRACTION = 0.158f
|
private const val SUBTITLE_BOTTOM_PADDING_FRACTION = 0.158f
|
||||||
private const val ANIMATION_DURATION = 100L
|
private const val ANIMATION_DURATION = 100L
|
||||||
private const val AUTO_HIDE_CONTROLLER_DELAY = 2000L
|
private const val AUTO_HIDE_CONTROLLER_DELAY = 2000L
|
||||||
|
@ -9,6 +9,7 @@ import android.os.Handler
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import com.github.libretube.R
|
import com.github.libretube.R
|
||||||
import com.github.libretube.constants.IntentData
|
import com.github.libretube.constants.IntentData
|
||||||
import com.github.libretube.constants.PreferenceKeys
|
import com.github.libretube.constants.PreferenceKeys
|
||||||
@ -74,9 +75,9 @@ object NavigationHelper {
|
|||||||
channelId,
|
channelId,
|
||||||
keepQueue
|
keepQueue
|
||||||
)
|
)
|
||||||
handler.postDelayed({
|
handler.postDelayed(500) {
|
||||||
startAudioPlayer(context)
|
startAudioPlayer(context)
|
||||||
}, 500)
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import android.view.MotionEvent
|
|||||||
import android.view.ScaleGestureDetector
|
import android.view.ScaleGestureDetector
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
import com.github.libretube.ui.base.BaseActivity
|
import com.github.libretube.ui.base.BaseActivity
|
||||||
import com.github.libretube.ui.interfaces.PlayerGestureOptions
|
import com.github.libretube.ui.interfaces.PlayerGestureOptions
|
||||||
import com.github.libretube.ui.models.PlayerViewModel
|
import com.github.libretube.ui.models.PlayerViewModel
|
||||||
@ -27,7 +28,7 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
|
|||||||
private val elapsedTime get() = SystemClock.elapsedRealtime()
|
private val elapsedTime get() = SystemClock.elapsedRealtime()
|
||||||
|
|
||||||
private val playerViewModel: PlayerViewModel by activity.viewModels()
|
private val playerViewModel: PlayerViewModel by activity.viewModels()
|
||||||
private val handler: Handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
private val gestureDetector: GestureDetector
|
private val gestureDetector: GestureDetector
|
||||||
private val scaleGestureDetector: ScaleGestureDetector
|
private val scaleGestureDetector: ScaleGestureDetector
|
||||||
@ -110,7 +111,7 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isEnabled && isSecondClick()) {
|
if (isEnabled && isSecondClick()) {
|
||||||
handler.removeCallbacks(runnable)
|
handler.removeCallbacksAndMessages(SINGLE_TAP_TOKEN)
|
||||||
lastDoubleClick = elapsedTime
|
lastDoubleClick = elapsedTime
|
||||||
val eventPositionPercentageX = e.x / width
|
val eventPositionPercentageX = e.x / width
|
||||||
|
|
||||||
@ -121,8 +122,12 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (recentDoubleClick()) return true
|
if (recentDoubleClick()) return true
|
||||||
handler.removeCallbacks(runnable)
|
handler.removeCallbacksAndMessages(SINGLE_TAP_TOKEN)
|
||||||
handler.postDelayed(runnable, MAX_TIME_DIFF)
|
handler.postDelayed(MAX_TIME_DIFF, SINGLE_TAP_TOKEN) {
|
||||||
|
// If the last event was for scroll or pinch then avoid single tap call
|
||||||
|
if (!wasClick || isSecondClick()) return@postDelayed
|
||||||
|
listener.onSingleTap()
|
||||||
|
}
|
||||||
lastClick = elapsedTime
|
lastClick = elapsedTime
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -155,12 +160,6 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private val runnable = Runnable {
|
|
||||||
// If the last event was for scroll or pinch then avoid single tap call
|
|
||||||
if (!wasClick || isSecondClick()) return@Runnable
|
|
||||||
listener.onSingleTap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isSecondClick(): Boolean {
|
private fun isSecondClick(): Boolean {
|
||||||
return elapsedTime - lastClick < MAX_TIME_DIFF
|
return elapsedTime - lastClick < MAX_TIME_DIFF
|
||||||
}
|
}
|
||||||
@ -171,6 +170,8 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val SINGLE_TAP_TOKEN = "singleTap"
|
||||||
|
|
||||||
private const val MAX_TIME_DIFF = 400L
|
private const val MAX_TIME_DIFF = 400L
|
||||||
private const val MOVEMENT_THRESHOLD = 30
|
private const val MOVEMENT_THRESHOLD = 30
|
||||||
private const val BORDER_THRESHOLD = 90
|
private const val BORDER_THRESHOLD = 90
|
||||||
|
Loading…
x
Reference in New Issue
Block a user