From 01de2ca19c8d71ad81ce9be1fa5ec80d5e0c345f Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Sun, 26 Apr 2026 12:47:28 +0200 Subject: [PATCH] feat: move subtitles when controls overlay are shown --- .../ui/screen/player/TvPlayerScreen.kt | 19 ++++++++++++++++--- .../purefin/ui/screen/player/PlayerScreen.kt | 14 +++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/player/TvPlayerScreen.kt b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/player/TvPlayerScreen.kt index 98c7f9c9..d4ca17d9 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/ui/screen/player/TvPlayerScreen.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/ui/screen/player/TvPlayerScreen.kt @@ -49,6 +49,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.media3.common.util.UnstableApi import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView +import androidx.media3.ui.SubtitleView import hu.bbara.purefin.player.viewmodel.ControlsAutoHideBlocker import hu.bbara.purefin.player.viewmodel.PlayerViewModel import hu.bbara.purefin.ui.screen.player.components.TvIconButton @@ -59,6 +60,7 @@ import hu.bbara.purefin.ui.screen.player.components.TvTrackSelectionPanel import kotlinx.coroutines.delay private const val TV_CONTROLS_AUTO_HIDE_MS = 5_000L +private const val CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION = 0.22f internal const val TV_HIDDEN_STOP_FEEDBACK_MS = 1_200L internal const val TvPlayerHiddenStopFeedbackTag = "tv_player_hidden_stop_feedback" @@ -215,6 +217,15 @@ fun TvPlayerScreen( } } + val playerControlsVisible = + controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null + val subtitleBottomPaddingFraction = + if (playerControlsVisible) { + CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION + } else { + SubtitleView.DEFAULT_BOTTOM_PADDING_FRACTION + } + BackHandler(enabled = true) { when { trackPanelType != null -> closeTrackPanel() @@ -254,16 +265,18 @@ fun TvPlayerScreen( useController = false resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT player = viewModel.player + subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) } }, - update = { it.player = viewModel.player }, + update = { + it.player = viewModel.player + it.subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) + }, modifier = Modifier .fillMaxHeight() .align(Alignment.Center) ) - val playerControlsVisible = - controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null AnimatedVisibility( visible = playerControlsVisible, enter = fadeIn(), diff --git a/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt b/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt index 89f456ee..1763c413 100644 --- a/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt +++ b/app/src/main/java/hu/bbara/purefin/ui/screen/player/PlayerScreen.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.viewinterop.AndroidView import androidx.media3.common.util.UnstableApi import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView +import androidx.media3.ui.SubtitleView import hu.bbara.purefin.player.viewmodel.PlayerViewModel import hu.bbara.purefin.ui.common.button.PurefinTextButton import hu.bbara.purefin.ui.common.visual.EmptyValueTimedVisibility @@ -53,6 +54,8 @@ import hu.bbara.purefin.ui.screen.player.components.rememberPersistentOverlayCon import kotlin.math.abs import kotlin.math.roundToInt +private const val CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION = 0.32f + @OptIn(UnstableApi::class) @Composable fun PlayerScreen( @@ -78,6 +81,14 @@ fun PlayerScreen( } } + val playerControlsVisible = controlsVisible || uiState.isEnded || uiState.error != null + val subtitleBottomPaddingFraction = + if (playerControlsVisible) { + CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION + } else { + SubtitleView.DEFAULT_BOTTOM_PADDING_FRACTION + } + Box( modifier = Modifier .fillMaxSize() @@ -89,10 +100,12 @@ fun PlayerScreen( useController = false resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT player = viewModel.player + subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) } }, update = { it.player = viewModel.player + it.subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction) }, modifier = Modifier .fillMaxHeight() @@ -171,7 +184,6 @@ fun PlayerScreen( ) } - val playerControlsVisible = controlsVisible || uiState.isEnded || uiState.error != null AnimatedVisibility( visible = playerControlsVisible, enter = fadeIn(),