feat: move subtitles when controls overlay are shown

This commit is contained in:
2026-04-26 12:47:28 +02:00
parent 522c8273d5
commit 01de2ca19c
2 changed files with 29 additions and 4 deletions

View File

@@ -49,6 +49,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import androidx.media3.ui.SubtitleView
import hu.bbara.purefin.player.viewmodel.ControlsAutoHideBlocker import hu.bbara.purefin.player.viewmodel.ControlsAutoHideBlocker
import hu.bbara.purefin.player.viewmodel.PlayerViewModel import hu.bbara.purefin.player.viewmodel.PlayerViewModel
import hu.bbara.purefin.ui.screen.player.components.TvIconButton 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 import kotlinx.coroutines.delay
private const val TV_CONTROLS_AUTO_HIDE_MS = 5_000L 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 TV_HIDDEN_STOP_FEEDBACK_MS = 1_200L
internal const val TvPlayerHiddenStopFeedbackTag = "tv_player_hidden_stop_feedback" 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) { BackHandler(enabled = true) {
when { when {
trackPanelType != null -> closeTrackPanel() trackPanelType != null -> closeTrackPanel()
@@ -254,16 +265,18 @@ fun TvPlayerScreen(
useController = false useController = false
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
player = viewModel.player player = viewModel.player
subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction)
} }
}, },
update = { it.player = viewModel.player }, update = {
it.player = viewModel.player
it.subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction)
},
modifier = Modifier modifier = Modifier
.fillMaxHeight() .fillMaxHeight()
.align(Alignment.Center) .align(Alignment.Center)
) )
val playerControlsVisible =
controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null
AnimatedVisibility( AnimatedVisibility(
visible = playerControlsVisible, visible = playerControlsVisible,
enter = fadeIn(), enter = fadeIn(),

View File

@@ -39,6 +39,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import androidx.media3.ui.SubtitleView
import hu.bbara.purefin.player.viewmodel.PlayerViewModel import hu.bbara.purefin.player.viewmodel.PlayerViewModel
import hu.bbara.purefin.ui.common.button.PurefinTextButton import hu.bbara.purefin.ui.common.button.PurefinTextButton
import hu.bbara.purefin.ui.common.visual.EmptyValueTimedVisibility 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.abs
import kotlin.math.roundToInt import kotlin.math.roundToInt
private const val CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION = 0.32f
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
@Composable @Composable
fun PlayerScreen( 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( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@@ -89,10 +100,12 @@ fun PlayerScreen(
useController = false useController = false
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
player = viewModel.player player = viewModel.player
subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction)
} }
}, },
update = { update = {
it.player = viewModel.player it.player = viewModel.player
it.subtitleView?.setBottomPaddingFraction(subtitleBottomPaddingFraction)
}, },
modifier = Modifier modifier = Modifier
.fillMaxHeight() .fillMaxHeight()
@@ -171,7 +184,6 @@ fun PlayerScreen(
) )
} }
val playerControlsVisible = controlsVisible || uiState.isEnded || uiState.error != null
AnimatedVisibility( AnimatedVisibility(
visible = playerControlsVisible, visible = playerControlsVisible,
enter = fadeIn(), enter = fadeIn(),