refactor(player): replace manual stop feedback visibility with ValueChangeTimedVisibility

This commit is contained in:
2026-06-19 11:14:48 +00:00
parent 50bbf5b81f
commit a07f9dd6e4

View File

@@ -23,6 +23,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Pause import androidx.compose.material.icons.outlined.Pause
import androidx.compose.material.icons.outlined.PlayArrow
import androidx.compose.material.icons.outlined.SkipNext import androidx.compose.material.icons.outlined.SkipNext
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -30,7 +31,6 @@ 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
@@ -61,6 +61,7 @@ import androidx.media3.ui.PlayerView
import androidx.media3.ui.SubtitleView import androidx.media3.ui.SubtitleView
import hu.bbara.purefin.core.player.model.TimedMarker import hu.bbara.purefin.core.player.model.TimedMarker
import hu.bbara.purefin.core.player.viewmodel.PlayerViewModel import hu.bbara.purefin.core.player.viewmodel.PlayerViewModel
import hu.bbara.purefin.ui.common.visual.ValueChangeTimedVisibility
import hu.bbara.purefin.ui.screen.player.components.PlayerSeekBarTrack import hu.bbara.purefin.ui.screen.player.components.PlayerSeekBarTrack
import hu.bbara.purefin.ui.screen.player.components.TvIconButton import hu.bbara.purefin.ui.screen.player.components.TvIconButton
import hu.bbara.purefin.ui.screen.player.components.TvNextEpisodeOverlay import hu.bbara.purefin.ui.screen.player.components.TvNextEpisodeOverlay
@@ -98,10 +99,7 @@ fun TvPlayerScreen(
var trackPanelType by remember { mutableStateOf<TvTrackPanelType?>(null) } var trackPanelType by remember { mutableStateOf<TvTrackPanelType?>(null) }
// TODO why this is needed??? // TODO why this is needed???
var pendingTrackButtonFocus by remember { mutableStateOf<TvTrackPanelType?>(null) } var pendingTrackButtonFocus by remember { mutableStateOf<TvTrackPanelType?>(null) }
var stopFeedbackVisible by remember { mutableStateOf(false) }
var stopFeedbackRequestId by remember { mutableIntStateOf(0) }
var hiddenSeekPreviewPositionMs by remember { mutableStateOf<Long?>(null) } var hiddenSeekPreviewPositionMs by remember { mutableStateOf<Long?>(null) }
var hiddenSeekRequestId by remember { mutableIntStateOf(0) }
val context = LocalContext.current val context = LocalContext.current
@@ -212,22 +210,9 @@ fun TvPlayerScreen(
pendingTrackButtonFocus = null pendingTrackButtonFocus = null
} }
// TODO: use animated visibility for this type of feedback that is already implemented // TODO check if neccessary
LaunchedEffect(stopFeedbackRequestId) {
if (stopFeedbackRequestId == 0) return@LaunchedEffect
delay(TV_HIDDEN_STOP_FEEDBACK_MS)
stopFeedbackVisible = false
}
LaunchedEffect(hiddenSeekRequestId) {
if (hiddenSeekRequestId == 0) return@LaunchedEffect
delay(TV_HIDDEN_STOP_FEEDBACK_MS)
hiddenSeekPreviewPositionMs = null
}
LaunchedEffect(controlsVisible, isPlaylistExpanded, trackPanelType, uiState.isEnded, uiState.error) { LaunchedEffect(controlsVisible, isPlaylistExpanded, trackPanelType, uiState.isEnded, uiState.error) {
if (controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null) { if (controlsVisible || isPlaylistExpanded || trackPanelType != null || uiState.isEnded || uiState.error != null) {
stopFeedbackVisible = false
hiddenSeekPreviewPositionMs = null hiddenSeekPreviewPositionMs = null
} }
} }
@@ -405,12 +390,11 @@ fun TvPlayerScreen(
onDismissError = { viewModel.clearError() } onDismissError = { viewModel.clearError() }
) )
// TODO: use TimedVisibility ValueChangeTimedVisibility(
AnimatedVisibility( value = uiState.isPlaying,
visible = stopFeedbackVisible,
modifier = Modifier.align(Alignment.Center) modifier = Modifier.align(Alignment.Center)
) { ) { value ->
TvPlayerHiddenStopFeedback() TvPlayerResumeStopFeedback(resume = value)
} }
AnimatedVisibility( AnimatedVisibility(
@@ -550,7 +534,8 @@ internal fun handleTvPlayerRootKeyEvent(
} }
@Composable @Composable
internal fun TvPlayerHiddenStopFeedback( internal fun TvPlayerResumeStopFeedback(
resume: Boolean,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Box( Box(
@@ -562,8 +547,8 @@ internal fun TvPlayerHiddenStopFeedback(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Icon( Icon(
imageVector = Icons.Outlined.Pause, imageVector = if (resume) Icons.Outlined.PlayArrow else Icons.Outlined.Pause,
contentDescription = "Pause playback", contentDescription = "Play/Pause playback",
tint = MaterialTheme.colorScheme.onSurface, tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(72.dp) modifier = Modifier.size(72.dp)
) )