diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 01d178b6c..a53352c30 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -275,7 +275,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { */ private fun showBottomBar() { if (this::playerBinding.isInitialized && !binding.player.isPlayerLocked) { - playerBinding.exoBottomBar.visibility = View.VISIBLE + playerBinding.bottomBar.visibility = View.VISIBLE } handler.postDelayed(this::showBottomBar, 100) } @@ -817,11 +817,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { private fun prepareExoPlayerView() { exoPlayerView.apply { - setShowSubtitleButton(false) - setShowNextButton(false) - setShowPreviousButton(false) - // controllerShowTimeoutMs = 1500 - controllerHideOnTouch = true useController = false player = exoPlayer } @@ -851,7 +846,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { this, doubleTapOverlayBinding, playerGestureControlsViewBinding, - trackSelector + trackSelector, + viewModel, + viewLifecycleOwner ) binding.apply { @@ -1498,7 +1495,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { fun getPipParams(): PictureInPictureParams = PictureInPictureParams.Builder() .setActions(PlayerHelper.getPiPModeActions(requireActivity(), exoPlayer.isPlaying)) .apply { - if (SDK_INT >= Build.VERSION_CODES.S) { + if (SDK_INT >= Build.VERSION_CODES.S && PlayerHelper.pipEnabled) { setAutoEnterEnabled(true) } if (exoPlayer.isPlaying) { diff --git a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt index 4f2fe027e..9f35f5c5e 100644 --- a/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt +++ b/app/src/main/java/com/github/libretube/ui/views/CustomExoPlayerView.kt @@ -14,6 +14,7 @@ import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView import androidx.core.content.ContextCompat +import androidx.lifecycle.LifecycleOwner import com.github.libretube.R import com.github.libretube.constants.PreferenceKeys import com.github.libretube.databinding.DoubleTapOverlayBinding @@ -27,6 +28,7 @@ import com.github.libretube.ui.base.BaseActivity import com.github.libretube.ui.interfaces.OnlinePlayerOptions import com.github.libretube.ui.interfaces.PlayerGestureOptions import com.github.libretube.ui.interfaces.PlayerOptions +import com.github.libretube.ui.models.PlayerViewModel import com.github.libretube.ui.sheets.BaseBottomSheet import com.github.libretube.ui.sheets.PlaybackSpeedSheet import com.github.libretube.util.AudioHelper @@ -61,6 +63,7 @@ internal class CustomExoPlayerView( private lateinit var brightnessHelper: BrightnessHelper private lateinit var audioHelper: AudioHelper private var doubleTapOverlayBinding: DoubleTapOverlayBinding? = null + private var playerViewModel: PlayerViewModel? = null /** * Objects from the parent fragment @@ -79,6 +82,9 @@ internal class CustomExoPlayerView( private var resizeModePref = PlayerHelper.resizeModePref + private val windowHelper + get() = (context as? MainActivity)?.windowHelper + private val supportFragmentManager get() = (context as BaseActivity).supportFragmentManager @@ -89,16 +95,23 @@ internal class CustomExoPlayerView( // saved to only load the playback speed once (for the first video) private var playbackPrefSet = false + private val hideControllerRunnable = Runnable { + hideController() + } + fun initialize( playerViewInterface: OnlinePlayerOptions?, doubleTapOverlayBinding: DoubleTapOverlayBinding, playerGestureControlsViewBinding: PlayerGestureControlsViewBinding, - trackSelector: TrackSelector? + trackSelector: TrackSelector?, + playerViewModel: PlayerViewModel? = null, + viewLifecycleOwner: LifecycleOwner? = null ) { this.playerOptionsInterface = playerViewInterface this.doubleTapOverlayBinding = doubleTapOverlayBinding this.trackSelector = trackSelector this.gestureViewBinding = playerGestureControlsViewBinding + this.playerViewModel = playerViewModel this.playerGestureController = PlayerGestureController(context as BaseActivity, this) this.brightnessHelper = BrightnessHelper(context as Activity) this.audioHelper = AudioHelper(context) @@ -111,6 +124,9 @@ internal class CustomExoPlayerView( applyCaptionsStyle() initializeAdvancedOptions(context) + // don't let the player view hide its controls automatically + controllerShowTimeoutMs = -1 + if (!playbackPrefSet) { player?.playbackParameters = PlaybackParameters( PlayerHelper.playbackSpeed.toFloat(), @@ -179,6 +195,14 @@ internal class CustomExoPlayerView( } } }) + + playerViewModel?.isFullscreen?.observe(viewLifecycleOwner!!) { isFullscreen -> + if (isFullscreen) { + windowHelper?.setFullscreen() + } else { + windowHelper?.unsetFullscreen() + } + } } private fun updatePlayPauseButton() { @@ -195,11 +219,24 @@ internal class CustomExoPlayerView( } override fun hideController() { - if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { - // hide all the navigation bars that potentially could have been reopened manually ba the user - (context as? MainActivity)?.windowHelper?.setFullscreen() - } + // remove the callback to hide the controller + handler.removeCallbacks(hideControllerRunnable) super.hideController() + + // hide system bars if in fullscreen + playerViewModel?.let { + if (it.isFullscreen.value == true) { + windowHelper?.setFullscreen() + } + } + } + + override fun showController() { + // remove the previous callback from the queue to prevent a flashing behavior + handler.removeCallbacks(hideControllerRunnable) + // automatically hide the controller after 2 seconds + handler.postDelayed(hideControllerRunnable, 2000) + super.showController() } override fun onTouchEvent(event: MotionEvent): Boolean { @@ -327,7 +364,7 @@ internal class CustomExoPlayerView( binding.exoTopBarRight.visibility = visibility binding.exoCenterControls.visibility = visibility - binding.exoBottomBar.visibility = visibility + binding.bottomBar.visibility = visibility binding.closeImageButton.visibility = visibility binding.exoTitle.visibility = visibility binding.playPauseBTN.visibility = visibility @@ -554,27 +591,37 @@ internal class CustomExoPlayerView( it.layoutParams = params } - // add a margin to the top and the bottom bar in landscape mode for notches - val newMargin = if ( - newConfig?.orientation == Configuration.ORIENTATION_LANDSCAPE - ) { - LANDSCAPE_MARGIN_HORIZONTAL - } else { - 0 + // add padding to the top bar to not overlap the status bar + binding.topBar.let { + setPadding( + it.paddingLeft, + (if (newConfig?.orientation == Configuration.ORIENTATION_LANDSCAPE) 25 else 5).toPixel().toInt(), + it.paddingRight, + it.paddingBottom + ) } - listOf(binding.exoTopBar, binding.exoBottomBar).forEach { - val params = it.layoutParams as MarginLayoutParams - params.marginStart = newMargin - params.marginEnd = newMargin - it.layoutParams = params + // don't add extra padding if there's no cutout + if ((context as? MainActivity)?.windowHelper?.hasCutout() == false) return + + // add a margin to the top and the bottom bar in landscape mode for notches + val newMargin = when (newConfig?.orientation) { + Configuration.ORIENTATION_LANDSCAPE -> LANDSCAPE_MARGIN_HORIZONTAL + else -> 0 + } + + listOf(binding.topBar, binding.bottomBar).forEach { + it.layoutParams = (it.layoutParams as MarginLayoutParams).apply { + marginStart = newMargin + marginEnd = newMargin + } } } /** * Load the captions style according to the users preferences */ - fun applyCaptionsStyle() { + private fun applyCaptionsStyle() { val captionStyle = PlayerHelper.getCaptionStyle(context) subtitleView?.apply { setApplyEmbeddedFontSizes(false) @@ -662,6 +709,6 @@ internal class CustomExoPlayerView( companion object { private const val SUBTITLE_BOTTOM_PADDING_FRACTION = 0.158f private const val ANIMATION_DURATION = 100L - private val LANDSCAPE_MARGIN_HORIZONTAL = (30).toPixel().toInt() + private val LANDSCAPE_MARGIN_HORIZONTAL = (20).toPixel().toInt() } } diff --git a/app/src/main/java/com/github/libretube/util/WindowHelper.kt b/app/src/main/java/com/github/libretube/util/WindowHelper.kt index e75c6855d..cb8259c80 100644 --- a/app/src/main/java/com/github/libretube/util/WindowHelper.kt +++ b/app/src/main/java/com/github/libretube/util/WindowHelper.kt @@ -46,4 +46,12 @@ class WindowHelper(private val activity: BaseActivity) { window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) } + + fun hasCutout(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + activity.window.decorView.rootWindowInsets.displayCutout != null + } else { + return false + } + } } diff --git a/app/src/main/res/layout/exo_styled_player_control_view.xml b/app/src/main/res/layout/exo_styled_player_control_view.xml index 97d6bffed..a4fb1cced 100644 --- a/app/src/main/res/layout/exo_styled_player_control_view.xml +++ b/app/src/main/res/layout/exo_styled_player_control_view.xml @@ -10,7 +10,7 @@ android:background="@color/exo_black_opacity_60" /> Proměňte LibreTube v hudební přehrávač. Časovač spánku Přeskočit ticho + Nápověda + Často kladené dotazy \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 58508c9c9..875acfd73 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -446,4 +446,8 @@ Lanjutkan Unduhan selesai Unduhan berlangsungan maksimal + Pewaktu tidur + Lewati keheningan + Bantuan + SSD \ No newline at end of file diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index c706c0feb..391877bec 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -429,4 +429,25 @@ Spilleliste-nettadresse Pause ved avslutning Stokk om + Spol tilbake + Pause + Alternative BiB-kontroller + Vis kun lyd og hopp over kontroller i PiP istedenfor spoling tilbake og forover + Lydspiller + Modus for kun lyd + Ingen undertekst + Nedlasting pauset + Nedlasting fullført + Maks. samtidige nedlastinger + Utfører maks. antall samtidige nedlastinger + Ukjent + Fortsett + Spol forover + Gjør LibreTube til en musikkspiller. + Søvntidsur + Hopp over stillhet + Hjelp + O-S-S + Bokmerk + Fjern bokmerke \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 9812e2c15..3bc4ba29c 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -448,4 +448,6 @@ Tryb „tylko dźwięk” Wyłącz po czasie Pomiń cisze + Pomoc + Często zadawane pytania \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 2820776f4..610d80c7d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -446,4 +446,8 @@ Продолжить Режим только аудио Превратите LibreTube в музыкальный проигрыватель. + Таймер сна + Пропускать тишину + Помощь + FAQ \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index db9d842bc..745d5d64f 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -386,7 +386,7 @@ Bildirimden kuyruğu aç Trendler Öne Çıkanlar - Şu anda trend olan şey + Şu anda popüler Yer imleri Yer imi Yer imlerini temizle diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2f34a1c68..e176e1148 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -447,7 +447,7 @@ Завантаження завершено Продовжити Довідка - ЧаП + ЧаПи Таймер сну Пропускати тишу \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7b53dd164..4c052226e 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -446,4 +446,8 @@ 未知 恢复 仅音频模式 + 睡眠定时器 + 跳过静音 + 帮助 + 常见问题 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 15824d29d..01e43147d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ espresso = "3.5.1" workRuntime = "2.7.1" exoplayer = "2.18.2" retrofit = "2.9.0" -desugaring = "1.2.2" +desugaring = "2.0.0" cronetEmbedded = "108.5359.79" cronetOkHttp = "0.1.0" coil = "2.2.2"