refactor: use a dialog for playing video in fullscreen

This commit is contained in:
Bnyro 2023-10-19 21:08:33 +02:00
parent ca2d5625f9
commit cfdae3e6b1
8 changed files with 40 additions and 28 deletions

View File

@ -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
) )

View File

@ -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)
} }
} }

View File

@ -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

View File

@ -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)

View File

@ -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() {

View File

@ -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
) )

View File

@ -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 {

View File

@ -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()
} }