mirror of
https://github.com/jellyfin/jellyfin-android.git
synced 2026-10-22 07:41:58 +02:00
Move player screen lock handling to extra class
This commit is contained in:
committed by
Niels van Velzen
parent
91e40076e5
commit
6fc4e00a32
@@ -47,7 +47,7 @@ class PlaybackMenus(
|
||||
fragment.onSkipToNext()
|
||||
}
|
||||
lockScreenButton.setOnClickListener {
|
||||
fragment.lockScreen()
|
||||
fragment.playerLockScreenHelper.lockScreen()
|
||||
}
|
||||
audioStreamsButton.setOnClickListener {
|
||||
fragment.suppressControllerAutoHide(true)
|
||||
|
||||
@@ -59,16 +59,13 @@ import org.jellyfin.mobile.utils.SmartOrientationListener
|
||||
import org.jellyfin.mobile.utils.dip
|
||||
import org.jellyfin.mobile.utils.disableFullscreen
|
||||
import org.jellyfin.mobile.utils.enableFullscreen
|
||||
import org.jellyfin.mobile.utils.isAutoRotateOn
|
||||
import org.jellyfin.mobile.utils.isFullscreen
|
||||
import org.jellyfin.mobile.utils.lockOrientation
|
||||
import org.jellyfin.mobile.utils.toast
|
||||
import org.jellyfin.sdk.model.api.MediaStream
|
||||
import org.koin.android.ext.android.inject
|
||||
import kotlin.math.abs
|
||||
|
||||
class PlayerFragment : Fragment() {
|
||||
|
||||
private val appPreferences: AppPreferences by inject()
|
||||
private val viewModel: PlayerViewModel by viewModels()
|
||||
private var _playerBinding: FragmentPlayerBinding? = null
|
||||
@@ -76,7 +73,6 @@ class PlayerFragment : Fragment() {
|
||||
private val playerView: PlayerView get() = playerBinding.playerView
|
||||
private val playerOverlay: View get() = playerBinding.playerOverlay
|
||||
private val loadingIndicator: View get() = playerBinding.loadingIndicator
|
||||
private val unlockScreenButton: ImageButton get() = playerBinding.unlockScreenButton
|
||||
private val gestureIndicatorOverlayLayout: LinearLayout get() = playerBinding.gestureOverlayLayout
|
||||
private val gestureIndicatorOverlayImage: ImageView get() = playerBinding.gestureOverlayImage
|
||||
private val gestureIndicatorOverlayProgress: ProgressBar get() = playerBinding.gestureOverlayProgress
|
||||
@@ -88,6 +84,8 @@ class PlayerFragment : Fragment() {
|
||||
private var playbackMenus: PlaybackMenus? = null
|
||||
private val audioManager: AudioManager by lazy { requireContext().getSystemService()!! }
|
||||
|
||||
lateinit var playerLockScreenHelper: PlayerLockScreenHelper
|
||||
|
||||
private val currentVideoStream: MediaStream?
|
||||
get() = viewModel.mediaSourceOrNull?.selectedVideoStream
|
||||
|
||||
@@ -110,15 +108,6 @@ class PlayerFragment : Fragment() {
|
||||
*/
|
||||
private val orientationListener: OrientationEventListener by lazy { SmartOrientationListener(requireActivity()) }
|
||||
|
||||
/**
|
||||
* Runnable that hides the unlock screen button, used by [peekUnlockButton]
|
||||
*/
|
||||
private val hideUnlockButtonAction = Runnable {
|
||||
if (_playerBinding != null) {
|
||||
unlockScreenButton.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runnable that hides [playerView] controller
|
||||
*/
|
||||
@@ -220,6 +209,8 @@ class PlayerFragment : Fragment() {
|
||||
// Set controller timeout
|
||||
suppressControllerAutoHide(false)
|
||||
|
||||
playerLockScreenHelper = PlayerLockScreenHelper(this, playerBinding, orientationListener)
|
||||
|
||||
// Setup gesture handling
|
||||
setupGestureDetector()
|
||||
|
||||
@@ -241,12 +232,6 @@ class PlayerFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle unlock action
|
||||
unlockScreenButton.setOnClickListener {
|
||||
unlockScreenButton.isVisible = false
|
||||
unlockScreen()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@@ -263,26 +248,6 @@ class PlayerFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
fun lockScreen() {
|
||||
playerView.useController = false
|
||||
orientationListener.disable()
|
||||
requireActivity().lockOrientation()
|
||||
peekUnlockButton()
|
||||
}
|
||||
|
||||
private fun unlockScreen() {
|
||||
if (requireActivity().isAutoRotateOn()) {
|
||||
requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
}
|
||||
orientationListener.enable()
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !requireActivity().isInPictureInPictureMode) {
|
||||
playerView.useController = true
|
||||
playerView.apply {
|
||||
if (!isControllerVisible) showController()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle current orientation and update fullscreen state and switcher icon
|
||||
*/
|
||||
@@ -324,18 +289,12 @@ class PlayerFragment : Fragment() {
|
||||
playerView.controllerShowTimeoutMs = if (suppress) -1 else DEFAULT_CONTROLS_TIMEOUT_MS
|
||||
}
|
||||
|
||||
private fun peekUnlockButton() {
|
||||
playerView.removeCallbacks(hideUnlockButtonAction)
|
||||
unlockScreenButton.isVisible = true
|
||||
playerView.postDelayed(hideUnlockButtonAction, DEFAULT_CONTROLS_TIMEOUT_MS.toLong())
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupGestureDetector() {
|
||||
// Handles taps when controls are locked
|
||||
val unlockDetector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
|
||||
peekUnlockButton()
|
||||
playerLockScreenHelper.peekUnlockButton()
|
||||
return true
|
||||
}
|
||||
})
|
||||
@@ -548,7 +507,7 @@ class PlayerFragment : Fragment() {
|
||||
playerView.useController = !isInPictureInPictureMode
|
||||
if (isInPictureInPictureMode) {
|
||||
playbackMenus?.dismissPlaybackInfo()
|
||||
hideUnlockButtonAction.run()
|
||||
playerLockScreenHelper.hideUnlockButton()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.jellyfin.mobile.player
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.os.Build
|
||||
import android.view.OrientationEventListener
|
||||
import android.widget.ImageButton
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.exoplayer2.ui.PlayerView
|
||||
import org.jellyfin.mobile.databinding.FragmentPlayerBinding
|
||||
import org.jellyfin.mobile.utils.Constants
|
||||
import org.jellyfin.mobile.utils.isAutoRotateOn
|
||||
import org.jellyfin.mobile.utils.lockOrientation
|
||||
|
||||
class PlayerLockScreenHelper(
|
||||
private val playerFragment: PlayerFragment,
|
||||
private val playerBinding: FragmentPlayerBinding,
|
||||
private val orientationListener: OrientationEventListener,
|
||||
) {
|
||||
private val playerView: PlayerView by playerBinding::playerView
|
||||
private val unlockScreenButton: ImageButton by playerBinding::unlockScreenButton
|
||||
|
||||
/**
|
||||
* Runnable that hides the unlock screen button, used by [peekUnlockButton]
|
||||
*/
|
||||
private val hideUnlockButtonAction = Runnable {
|
||||
hideUnlockButton()
|
||||
}
|
||||
|
||||
init {
|
||||
// Handle unlock action
|
||||
unlockScreenButton.setOnClickListener {
|
||||
unlockScreen()
|
||||
}
|
||||
}
|
||||
|
||||
fun lockScreen() {
|
||||
playerView.useController = false
|
||||
orientationListener.disable()
|
||||
playerFragment.requireActivity().lockOrientation()
|
||||
peekUnlockButton()
|
||||
}
|
||||
|
||||
private fun unlockScreen() {
|
||||
hideUnlockButton()
|
||||
val activity = playerFragment.requireActivity()
|
||||
if (activity.isAutoRotateOn()) {
|
||||
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
}
|
||||
orientationListener.enable()
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || !activity.isInPictureInPictureMode) {
|
||||
playerView.useController = true
|
||||
playerView.apply {
|
||||
if (!isControllerVisible) showController()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun peekUnlockButton() {
|
||||
playerView.removeCallbacks(hideUnlockButtonAction)
|
||||
unlockScreenButton.isVisible = true
|
||||
playerView.postDelayed(hideUnlockButtonAction, Constants.DEFAULT_CONTROLS_TIMEOUT_MS.toLong())
|
||||
}
|
||||
|
||||
fun hideUnlockButton() {
|
||||
unlockScreenButton.isVisible = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user