mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
refactor: use a dialog for playing video in fullscreen
This commit is contained in:
parent
ca2d5625f9
commit
cfdae3e6b1
@ -1,15 +1,14 @@
|
|||||||
package com.github.libretube.helpers
|
package com.github.libretube.helpers
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.view.Window
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.github.libretube.ui.extensions.toggleSystemBars
|
import com.github.libretube.ui.extensions.toggleSystemBars
|
||||||
|
|
||||||
object WindowHelper {
|
object WindowHelper {
|
||||||
fun toggleFullscreen(activity: Activity, isFullscreen: Boolean) {
|
fun toggleFullscreen(window: Window, isFullscreen: Boolean) {
|
||||||
val window = activity.window
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
window.attributes.layoutInDisplayCutoutMode = if (isFullscreen) {
|
window.attributes.layoutInDisplayCutoutMode = if (isFullscreen) {
|
||||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||||
@ -30,7 +29,7 @@ object WindowHelper {
|
|||||||
// Show the system bars when it is not fullscreen and hide them when it is fullscreen
|
// Show the system bars when it is not fullscreen and hide them when it is fullscreen
|
||||||
// System bars means status bar and the navigation bar
|
// System bars means status bar and the navigation bar
|
||||||
// See: https://developer.android.com/training/system-ui/immersive#kotlin
|
// See: https://developer.android.com/training/system-ui/immersive#kotlin
|
||||||
activity.toggleSystemBars(
|
window.toggleSystemBars(
|
||||||
types = WindowInsetsCompat.Type.systemBars(),
|
types = WindowInsetsCompat.Type.systemBars(),
|
||||||
showBars = !isFullscreen
|
showBars = !isFullscreen
|
||||||
)
|
)
|
||||||
|
@ -486,8 +486,8 @@ class MainActivity : BaseActivity() {
|
|||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
|
|
||||||
when (newConfig.orientation) {
|
when (newConfig.orientation) {
|
||||||
Configuration.ORIENTATION_PORTRAIT -> WindowHelper.toggleFullscreen(this, false)
|
Configuration.ORIENTATION_PORTRAIT -> WindowHelper.toggleFullscreen(window, false)
|
||||||
Configuration.ORIENTATION_LANDSCAPE -> WindowHelper.toggleFullscreen(this, true)
|
Configuration.ORIENTATION_LANDSCAPE -> WindowHelper.toggleFullscreen(window, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class OfflinePlayerActivity : BaseActivity() {
|
|||||||
private val playerViewModel: PlayerViewModel by viewModels()
|
private val playerViewModel: PlayerViewModel by viewModels()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
WindowHelper.toggleFullscreen(this, true)
|
WindowHelper.toggleFullscreen(window, true)
|
||||||
|
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package com.github.libretube.ui.extensions
|
package com.github.libretube.ui.extensions
|
||||||
|
|
||||||
import android.app.Activity
|
import android.view.Window
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat.Type.InsetsType
|
import androidx.core.view.WindowInsetsCompat.Type.InsetsType
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
|
|
||||||
fun Activity.toggleSystemBars(@InsetsType types: Int, showBars: Boolean) {
|
fun Window.toggleSystemBars(@InsetsType types: Int, showBars: Boolean) {
|
||||||
WindowCompat.getInsetsController(window, window.decorView).apply {
|
WindowCompat.getInsetsController(this, decorView).apply {
|
||||||
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
if (showBars) {
|
if (showBars) {
|
||||||
show(types)
|
show(types)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.github.libretube.ui.fragments
|
package com.github.libretube.ui.fragments
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Dialog
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -18,6 +19,7 @@ import android.util.Log
|
|||||||
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 android.view.ViewGroup.LayoutParams
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||||
import androidx.constraintlayout.motion.widget.TransitionAdapter
|
import androidx.constraintlayout.motion.widget.TransitionAdapter
|
||||||
@ -29,6 +31,7 @@ import androidx.core.net.toUri
|
|||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.core.os.postDelayed
|
import androidx.core.os.postDelayed
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
@ -89,6 +92,7 @@ import com.github.libretube.helpers.PlayerHelper.getVideoStats
|
|||||||
import com.github.libretube.helpers.PlayerHelper.isInSegment
|
import com.github.libretube.helpers.PlayerHelper.isInSegment
|
||||||
import com.github.libretube.helpers.PreferenceHelper
|
import com.github.libretube.helpers.PreferenceHelper
|
||||||
import com.github.libretube.helpers.ProxyHelper
|
import com.github.libretube.helpers.ProxyHelper
|
||||||
|
import com.github.libretube.helpers.WindowHelper
|
||||||
import com.github.libretube.obj.PlayerNotificationData
|
import com.github.libretube.obj.PlayerNotificationData
|
||||||
import com.github.libretube.obj.ShareData
|
import com.github.libretube.obj.ShareData
|
||||||
import com.github.libretube.obj.VideoResolution
|
import com.github.libretube.obj.VideoResolution
|
||||||
@ -100,6 +104,7 @@ import com.github.libretube.ui.dialogs.AddToPlaylistDialog
|
|||||||
import com.github.libretube.ui.dialogs.DownloadDialog
|
import com.github.libretube.ui.dialogs.DownloadDialog
|
||||||
import com.github.libretube.ui.dialogs.ShareDialog
|
import com.github.libretube.ui.dialogs.ShareDialog
|
||||||
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
||||||
|
import com.github.libretube.ui.extensions.toggleSystemBars
|
||||||
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
import com.github.libretube.ui.interfaces.OnlinePlayerOptions
|
||||||
import com.github.libretube.ui.listeners.SeekbarPreviewListener
|
import com.github.libretube.ui.listeners.SeekbarPreviewListener
|
||||||
import com.github.libretube.ui.models.CommentsViewModel
|
import com.github.libretube.ui.models.CommentsViewModel
|
||||||
@ -193,6 +198,15 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
private var scrubbingTimeBar = false
|
private var scrubbingTimeBar = false
|
||||||
private var chaptersBottomSheet: ChaptersBottomSheet? = null
|
private var chaptersBottomSheet: ChaptersBottomSheet? = null
|
||||||
|
|
||||||
|
private val fullscreenDialog by lazy {
|
||||||
|
object: Dialog(requireContext(), android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
|
||||||
|
override fun onBackPressed() {
|
||||||
|
super.onBackPressed()
|
||||||
|
unsetFullscreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receiver for all actions in the PiP mode
|
* Receiver for all actions in the PiP mode
|
||||||
*/
|
*/
|
||||||
@ -513,13 +527,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
// set status bar icon color to white
|
// set status bar icon color to white
|
||||||
windowInsetsControllerCompat.isAppearanceLightStatusBars = false
|
windowInsetsControllerCompat.isAppearanceLightStatusBars = false
|
||||||
|
|
||||||
binding.mainContainer.isClickable = true
|
|
||||||
binding.linLayout.isGone = true
|
|
||||||
|
|
||||||
binding.player.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
|
||||||
endToEnd = binding.playerMotionLayout.id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainActivity.screenOrientationPref == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT) {
|
if (mainActivity.screenOrientationPref == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT) {
|
||||||
val height = streams.videoStreams.firstOrNull()?.height ?: exoPlayer.videoSize.height
|
val height = streams.videoStreams.firstOrNull()?.height ?: exoPlayer.videoSize.height
|
||||||
val width = streams.videoStreams.firstOrNull()?.width ?: exoPlayer.videoSize.width
|
val width = streams.videoStreams.firstOrNull()?.width ?: exoPlayer.videoSize.width
|
||||||
@ -534,11 +541,16 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
viewModel.isFullscreen.value = true
|
viewModel.isFullscreen.value = true
|
||||||
|
|
||||||
updateResolutionOnFullscreenChange(true)
|
updateResolutionOnFullscreenChange(true)
|
||||||
|
|
||||||
|
val playerView = binding.player
|
||||||
|
(binding.player.parent as ViewGroup).removeView(playerView)
|
||||||
|
fullscreenDialog.addContentView(binding.player, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
|
||||||
|
fullscreenDialog.show()
|
||||||
|
WindowHelper.toggleFullscreen(fullscreenDialog.window!!, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SourceLockedOrientationActivity")
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
fun unsetFullscreen() {
|
fun unsetFullscreen() {
|
||||||
// leave fullscreen mode
|
|
||||||
with(binding.playerMotionLayout) {
|
with(binding.playerMotionLayout) {
|
||||||
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
|
||||||
enableTransition(R.id.yt_transition, true)
|
enableTransition(R.id.yt_transition, true)
|
||||||
@ -552,10 +564,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.mainContainer.isClickable = false
|
|
||||||
binding.linLayout.isVisible = true
|
|
||||||
binding.relatedContainer?.isVisible = true
|
|
||||||
|
|
||||||
if (mainActivity.screenOrientationPref == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT) {
|
if (mainActivity.screenOrientationPref == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT) {
|
||||||
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
||||||
}
|
}
|
||||||
@ -565,6 +573,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
|
|
||||||
viewModel.isFullscreen.value = false
|
viewModel.isFullscreen.value = false
|
||||||
updateResolutionOnFullscreenChange(false)
|
updateResolutionOnFullscreenChange(false)
|
||||||
|
|
||||||
|
val playerView = binding.player
|
||||||
|
(playerView.parent as ViewGroup).removeView(playerView)
|
||||||
|
binding.playerMotionLayout.addView(playerView)
|
||||||
|
fullscreenDialog.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
@ -144,7 +144,7 @@ open class CustomExoPlayerView(
|
|||||||
// change locked status
|
// change locked status
|
||||||
isPlayerLocked = !isPlayerLocked
|
isPlayerLocked = !isPlayerLocked
|
||||||
|
|
||||||
activity.toggleSystemBars(
|
activity.window.toggleSystemBars(
|
||||||
types = WindowInsetsCompat.Type.statusBars(),
|
types = WindowInsetsCompat.Type.statusBars(),
|
||||||
showBars = !isPlayerLocked
|
showBars = !isPlayerLocked
|
||||||
)
|
)
|
||||||
|
@ -13,13 +13,13 @@ class OfflinePlayerView(
|
|||||||
override fun hideController() {
|
override fun hideController() {
|
||||||
super.hideController()
|
super.hideController()
|
||||||
// hide the status bars when continuing to watch video
|
// hide the status bars when continuing to watch video
|
||||||
activity.toggleSystemBars(WindowInsetsCompat.Type.systemBars(), false)
|
activity.window.toggleSystemBars(WindowInsetsCompat.Type.systemBars(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showController() {
|
override fun showController() {
|
||||||
super.showController()
|
super.showController()
|
||||||
// show status bar when showing player options
|
// show status bar when showing player options
|
||||||
activity.toggleSystemBars(WindowInsetsCompat.Type.statusBars(), true)
|
activity.window.toggleSystemBars(WindowInsetsCompat.Type.statusBars(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTopBarMarginDp(): Int {
|
override fun getTopBarMarginDp(): Int {
|
||||||
|
@ -145,7 +145,7 @@ class OnlinePlayerView(
|
|||||||
this.playerOptions = playerOptions
|
this.playerOptions = playerOptions
|
||||||
|
|
||||||
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
|
playerViewModel.isFullscreen.observe(viewLifecycleOwner) { isFullscreen ->
|
||||||
WindowHelper.toggleFullscreen(activity, isFullscreen)
|
WindowHelper.toggleFullscreen(activity.window, isFullscreen)
|
||||||
updateTopBarMargin()
|
updateTopBarMargin()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ class OnlinePlayerView(
|
|||||||
playerViewModel.isFullscreen.value?.let { isFullscreen ->
|
playerViewModel.isFullscreen.value?.let { isFullscreen ->
|
||||||
if (!isFullscreen) return@let
|
if (!isFullscreen) return@let
|
||||||
// Show status bar only not navigation bar if the player controls are visible and hide it otherwise
|
// Show status bar only not navigation bar if the player controls are visible and hide it otherwise
|
||||||
activity.toggleSystemBars(
|
activity.window.toggleSystemBars(
|
||||||
types = WindowInsetsCompat.Type.statusBars(),
|
types = WindowInsetsCompat.Type.statusBars(),
|
||||||
showBars = visibility == View.VISIBLE && !isPlayerLocked
|
showBars = visibility == View.VISIBLE && !isPlayerLocked
|
||||||
)
|
)
|
||||||
@ -189,7 +189,7 @@ class OnlinePlayerView(
|
|||||||
super.hideController()
|
super.hideController()
|
||||||
|
|
||||||
if (playerViewModel?.isFullscreen?.value == true) {
|
if (playerViewModel?.isFullscreen?.value == true) {
|
||||||
WindowHelper.toggleFullscreen(activity, true)
|
WindowHelper.toggleFullscreen(activity.window, true)
|
||||||
}
|
}
|
||||||
updateTopBarMargin()
|
updateTopBarMargin()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user