mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
refactor(player): replace manual hidden UI visibility with ValueChangeTimedVisibility counters
- Replace hiddenSeekPreviewPositionMs with hiddenSeek counter for ValueChangeTimedVisibility - Add resumeStopFeedbackCounter to decouple feedback visibility from isPlaying state - Consolidate onPausePlayback/onResumePlayback into single onTogglePlayback - Increase right D-pad seek from 10s to 30s - Remove obsolete LaunchedEffect resetting hidden seek state
This commit is contained in:
@@ -31,6 +31,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
@@ -97,12 +98,16 @@ fun TvPlayerScreen(
|
|||||||
var controlsVisible by remember { mutableStateOf(true) }
|
var controlsVisible by remember { mutableStateOf(true) }
|
||||||
var isPlaylistExpanded by remember { mutableStateOf(false) }
|
var isPlaylistExpanded by remember { mutableStateOf(false) }
|
||||||
var trackPanelType by remember { mutableStateOf<TvTrackPanelType?>(null) }
|
var trackPanelType by remember { mutableStateOf<TvTrackPanelType?>(null) }
|
||||||
// TODO why this is needed???
|
|
||||||
var pendingTrackButtonFocus by remember { mutableStateOf<TvTrackPanelType?>(null) }
|
var pendingTrackButtonFocus by remember { mutableStateOf<TvTrackPanelType?>(null) }
|
||||||
var hiddenSeekPreviewPositionMs by remember { mutableStateOf<Long?>(null) }
|
|
||||||
|
// This is a hack for timed visibility.
|
||||||
|
var resumeStopFeedbackCounter by remember { mutableIntStateOf(0) }
|
||||||
|
var hiddenSeekCounter by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
|
||||||
val backgroundFocusRequester = remember { FocusRequester() }
|
val backgroundFocusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
// Main section focus requesters
|
// Main section focus requesters
|
||||||
@@ -180,7 +185,6 @@ fun TvPlayerScreen(
|
|||||||
&& uiState.durationMs > 0L
|
&& uiState.durationMs > 0L
|
||||||
&& (uiState.durationMs - uiState.positionMs) <= 60_000L
|
&& (uiState.durationMs - uiState.positionMs) <= 60_000L
|
||||||
&& !uiState.isEnded
|
&& !uiState.isEnded
|
||||||
val showHiddenSeekPreview = !controlsVisible && hiddenSeekPreviewPositionMs != null
|
|
||||||
LaunchedEffect(showSkipIntroButton, showNextEpisodeOverlay) {
|
LaunchedEffect(showSkipIntroButton, showNextEpisodeOverlay) {
|
||||||
rootFocusRequester = when {
|
rootFocusRequester = when {
|
||||||
showSkipIntroButton -> {
|
showSkipIntroButton -> {
|
||||||
@@ -210,13 +214,6 @@ fun TvPlayerScreen(
|
|||||||
pendingTrackButtonFocus = null
|
pendingTrackButtonFocus = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check if neccessary
|
|
||||||
LaunchedEffect(controlsVisible, isPlaylistExpanded, trackPanelType, uiState.isEnded, uiState.error) {
|
|
||||||
if (controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null) {
|
|
||||||
hiddenSeekPreviewPositionMs = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val subtitleBottomPaddingFraction =
|
val subtitleBottomPaddingFraction =
|
||||||
if (controlsVisible) {
|
if (controlsVisible) {
|
||||||
CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION
|
CONTROLS_VISIBLE_SUBTITLE_BOTTOM_PADDING_FRACTION
|
||||||
@@ -254,9 +251,16 @@ fun TvPlayerScreen(
|
|||||||
onCloseTrackPanel = closeTrackPanel,
|
onCloseTrackPanel = closeTrackPanel,
|
||||||
onCollapsePlaylist = {},
|
onCollapsePlaylist = {},
|
||||||
onHideControls = ::hideControls,
|
onHideControls = ::hideControls,
|
||||||
onPausePlayback = { viewModel.pausePlayback() },
|
onTogglePlayback = {
|
||||||
onResumePlayback = { viewModel.resumePlayback() },
|
// This is a hack to trigger the ValueChangeTimedVisibility to show the hidden resume/stop feedback.
|
||||||
onSeekRelative = { viewModel.seekBy(it) },
|
resumeStopFeedbackCounter++
|
||||||
|
viewModel.togglePlayPause()
|
||||||
|
},
|
||||||
|
onSeekRelative = {
|
||||||
|
// This is a hack to trigger the ValueChangeTimedVisibility to show the hidden seek timeline.
|
||||||
|
hiddenSeekCounter++
|
||||||
|
viewModel.seekBy(it)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if (event.type == KeyEventType.KeyDown) {
|
if (event.type == KeyEventType.KeyDown) {
|
||||||
hideControlsWithTimeout()
|
hideControlsWithTimeout()
|
||||||
@@ -331,7 +335,7 @@ fun TvPlayerScreen(
|
|||||||
.align(Alignment.BottomEnd)
|
.align(Alignment.BottomEnd)
|
||||||
.padding(
|
.padding(
|
||||||
end = 24.dp,
|
end = 24.dp,
|
||||||
bottom = if (hiddenSeekPreviewPositionMs != null) 104.dp else 24.dp
|
bottom = 24.dp
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
TvIconButton(
|
TvIconButton(
|
||||||
@@ -362,15 +366,15 @@ fun TvPlayerScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use TimedVisibility
|
ValueChangeTimedVisibility(
|
||||||
AnimatedVisibility(
|
value = hiddenSeekCounter,
|
||||||
visible = showHiddenSeekPreview,
|
hideAfterMillis = 2500L,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomCenter)
|
.align(Alignment.BottomCenter)
|
||||||
.padding(horizontal = 32.dp, vertical = 28.dp)
|
.padding(horizontal = 32.dp, vertical = 28.dp)
|
||||||
) {
|
) {
|
||||||
HiddenTvSeekTimeline(
|
HiddenTvSeekTimeline(
|
||||||
positionMs = hiddenSeekPreviewPositionMs ?: uiState.positionMs,
|
positionMs = uiState.positionMs,
|
||||||
durationMs = uiState.durationMs,
|
durationMs = uiState.durationMs,
|
||||||
bufferedMs = uiState.bufferedMs,
|
bufferedMs = uiState.bufferedMs,
|
||||||
chapterMarkers = uiState.chapters,
|
chapterMarkers = uiState.chapters,
|
||||||
@@ -391,10 +395,11 @@ fun TvPlayerScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ValueChangeTimedVisibility(
|
ValueChangeTimedVisibility(
|
||||||
value = uiState.isPlaying,
|
value = resumeStopFeedbackCounter,
|
||||||
|
hideAfterMillis = TV_HIDDEN_STOP_FEEDBACK_MS,
|
||||||
modifier = Modifier.align(Alignment.Center)
|
modifier = Modifier.align(Alignment.Center)
|
||||||
) { value ->
|
) {
|
||||||
TvPlayerResumeStopFeedback(resume = value)
|
TvPlayerResumeStopFeedback(resume = uiState.isPlaying)
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
@@ -468,8 +473,7 @@ internal fun handleTvPlayerRootKeyEvent(
|
|||||||
onCloseTrackPanel: () -> Unit,
|
onCloseTrackPanel: () -> Unit,
|
||||||
onCollapsePlaylist: () -> Unit,
|
onCollapsePlaylist: () -> Unit,
|
||||||
onHideControls: () -> Unit,
|
onHideControls: () -> Unit,
|
||||||
onPausePlayback: () -> Unit,
|
onTogglePlayback: () -> Unit,
|
||||||
onResumePlayback: () -> Unit,
|
|
||||||
onSeekRelative: (Long) -> Unit,
|
onSeekRelative: (Long) -> Unit,
|
||||||
onShowControls: () -> Unit,
|
onShowControls: () -> Unit,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
@@ -504,7 +508,7 @@ internal fun handleTvPlayerRootKeyEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Key.DirectionRight -> {
|
Key.DirectionRight -> {
|
||||||
onSeekRelative(10_000)
|
onSeekRelative(30_000)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,11 +521,8 @@ internal fun handleTvPlayerRootKeyEvent(
|
|||||||
if (popupVisible) {
|
if (popupVisible) {
|
||||||
// Do nothing because the focused component is not he root, but an overlay
|
// Do nothing because the focused component is not he root, but an overlay
|
||||||
false
|
false
|
||||||
} else if (isPlaying) {
|
|
||||||
onPausePlayback()
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
onResumePlayback()
|
onTogglePlayback()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user