refactor(player): improve EmptyValueTimedVisibility and ValueChangeTimedVisibility components

This commit is contained in:
2026-06-20 19:26:59 +02:00
parent 217ba5b6d9
commit 1910a0c144
2 changed files with 43 additions and 25 deletions

View File

@@ -192,30 +192,30 @@ fun PlayerScreen(
EmptyValueTimedVisibility( EmptyValueTimedVisibility(
value = horizontalSeekFeedback, value = horizontalSeekFeedback,
hideAfterMillis = 1_000 hideAfterMillis = 1_000,
modifier = Modifier
.align(Alignment.Center)
) { ) {
SeekAmountIndicator( SeekAmountIndicator(
deltaMs = it, deltaMs = it,
modifier = Modifier
.align(Alignment.Center)
) )
} }
EmptyValueTimedVisibility( EmptyValueTimedVisibility(
value = horizontalSeekPreviewPositionMs, value = horizontalSeekPreviewPositionMs,
hideAfterMillis = 1_000 hideAfterMillis = 1_000,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(horizontal = 24.dp, vertical = 28.dp)
) { previewPositionMs -> ) { previewPositionMs ->
if (controlsVisible) { if (!controlsVisible) {
HiddenSeekTimeline( HiddenSeekTimeline(
positionMs = previewPositionMs, positionMs = previewPositionMs,
durationMs = uiState.durationMs, durationMs = uiState.durationMs,
bufferedMs = uiState.bufferedMs, bufferedMs = uiState.bufferedMs,
chapterMarkers = uiState.chapters, chapterMarkers = uiState.chapters,
adMarkers = uiState.ads, adMarkers = uiState.ads,
isLive = uiState.isLive, isLive = uiState.isLive
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(horizontal = 24.dp, vertical = 28.dp)
) )
} }
} }

View File

@@ -8,29 +8,37 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
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.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable @Composable
fun <T> EmptyValueTimedVisibility( fun <T> EmptyValueTimedVisibility(
value: T?, value: T?,
hideAfterMillis: Long = 1_000, hideAfterMillis: Long = 1_000,
enterTransition: EnterTransition = EnterTransition.None,
exitTransition: ExitTransition = ExitTransition.None,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
content: @Composable (T) -> Unit content: @Composable (T) -> Unit
) { ) {
val shownValue = remember { mutableStateOf<T?>(null) } var displayedValue by remember { mutableStateOf(value) }
LaunchedEffect(value) { LaunchedEffect(value) {
if (value == null) { if (value != null) {
delay(hideAfterMillis) displayedValue = value
shownValue.value = null
} }
shownValue.value = value
} }
if (displayedValue != null) {
shownValue.value?.let { ValueChangeTimedVisibility(
content(it) value = displayedValue!!,
hideAfterMillis = hideAfterMillis,
enterTransition = enterTransition,
exitTransition = exitTransition,
modifier = modifier,
content = content
)
} }
} }
@@ -38,30 +46,40 @@ fun <T> EmptyValueTimedVisibility(
fun <T> ValueChangeTimedVisibility( fun <T> ValueChangeTimedVisibility(
value: T, value: T,
hideAfterMillis: Long = 1_000, hideAfterMillis: Long = 1_000,
enterTransition: EnterTransition = EnterTransition.None,
exitTransition: ExitTransition = ExitTransition.None,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
content: @Composable (T) -> Unit content: @Composable (T) -> Unit
) { ) {
var displayedValue by remember { mutableStateOf(value) } var displayedValue by remember { mutableStateOf(value) }
var isVisible by remember { mutableStateOf(false) }
var hasInitialValue by remember { mutableStateOf(false) } var hasInitialValue by remember { mutableStateOf(false) }
var isVisible by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
var hideJob: Job? by remember { mutableStateOf(null) }
fun restartHideJob() {
hideJob?.cancel()
hideJob = coroutineScope.launch {
delay(hideAfterMillis)
isVisible = false
}
}
LaunchedEffect(value) { LaunchedEffect(value) {
displayedValue = value
if (!hasInitialValue) { if (!hasInitialValue) {
hasInitialValue = true hasInitialValue = true
return@LaunchedEffect return@LaunchedEffect
} }
displayedValue = value
isVisible = true isVisible = true
delay(hideAfterMillis) restartHideJob()
isVisible = false
} }
AnimatedVisibility( AnimatedVisibility(
visible = isVisible, visible = isVisible,
modifier = modifier, modifier = modifier,
enter = EnterTransition.None, enter = enterTransition,
exit = ExitTransition.None exit = exitTransition
) { ) {
content(displayedValue) content(displayedValue)
} }