refactor: enhance PlayerSeekBar with custom progress indicator and improved layout

This commit is contained in:
2026-01-26 19:45:29 +01:00
parent 6604c727bf
commit a2d73e1a54

View File

@@ -10,6 +10,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults import androidx.compose.material3.SliderDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
@@ -35,29 +36,47 @@ fun PlayerSeekBar(
val position = positionMs.coerceIn(0, safeDuration) val position = positionMs.coerceIn(0, safeDuration)
val bufferRatio = (bufferedMs.toFloat() / safeDuration).coerceIn(0f, 1f) val bufferRatio = (bufferedMs.toFloat() / safeDuration).coerceIn(0f, 1f)
val combinedMarkers = chapterMarkers.map { it.copy(type = MarkerType.CHAPTER) } + adMarkers.map { it.copy(type = MarkerType.AD) } val combinedMarkers = chapterMarkers.map { it.copy(type = MarkerType.CHAPTER) } + adMarkers.map { it.copy(type = MarkerType.AD) }
val progressRatio = (position.toFloat() / safeDuration).coerceIn(0f, 1f)
Box( Box(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 8.dp) .padding(horizontal = 8.dp)
.height(32.dp) .height(32.dp),
contentAlignment = Alignment.Center
) { ) {
Canvas( Canvas(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(horizontal = 2.dp, vertical = 10.dp) .padding(horizontal = 2.dp, vertical = 10.dp)
) { ) {
val trackHeight = 4f
val trackTop = size.height / 2 - trackHeight / 2
// Buffered bar // Buffered bar
val bufferWidth = bufferRatio * size.width val bufferWidth = bufferRatio * size.width
drawRect( drawRect(
color = scheme.onSurface.copy(alpha = 0.2f), color = scheme.onSurface.copy(alpha = 0.2f),
size = Size(width = size.width, height = 4f), size = Size(width = size.width, height = trackHeight),
topLeft = Offset(0f, size.height / 2 - 2f) topLeft = Offset(0f, trackTop)
) )
drawRect( drawRect(
color = scheme.onSurface.copy(alpha = 0.4f), color = scheme.onSurface.copy(alpha = 0.4f),
size = Size(width = bufferWidth, height = 4f), size = Size(width = bufferWidth, height = trackHeight),
topLeft = Offset(0f, size.height / 2 - 2f) topLeft = Offset(0f, trackTop)
)
// Primary progress sits on top of the buffer line to match its width
val progressWidth = progressRatio * size.width
drawRect(
color = scheme.primary,
size = Size(width = progressWidth, height = trackHeight),
topLeft = Offset(0f, trackTop)
)
// Draw a compact dot indicator instead of the default thumb
val thumbRadius = 6.dp.toPx()
drawCircle(
color = scheme.primary,
radius = thumbRadius,
center = Offset(progressWidth.coerceIn(0f, size.width), size.height / 2)
) )
// Markers // Markers
combinedMarkers.forEach { marker -> combinedMarkers.forEach { marker ->
@@ -79,8 +98,8 @@ fun PlayerSeekBar(
onValueChangeFinished = onScrubFinished, onValueChangeFinished = onScrubFinished,
valueRange = 0f..safeDuration.toFloat(), valueRange = 0f..safeDuration.toFloat(),
colors = SliderDefaults.colors( colors = SliderDefaults.colors(
thumbColor = scheme.primary, thumbColor = Color.Transparent,
activeTrackColor = scheme.primary, activeTrackColor = Color.Transparent,
inactiveTrackColor = Color.Transparent inactiveTrackColor = Color.Transparent
), ),
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()