fix: Prevent tap gesture handler from interfering with seek drag

The detectTapGestures and drag awaitEachGesture handlers competed for
pointer events, causing drag() to sometimes end prematurely and the
seek to not fire. A shared dragActive flag now gates tap/double-tap
callbacks so they are suppressed during active drags.
This commit is contained in:
2026-02-27 13:03:26 +01:00
parent 318b190061
commit cccb20312b

View File

@@ -8,6 +8,8 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
@@ -31,7 +33,8 @@ fun PlayerGesturesLayer(
) { ) {
val density = LocalDensity.current val density = LocalDensity.current
val horizontalThresholdPx = with(density) { HorizontalSeekGestureHelper.START_THRESHOLD.toPx() } val horizontalThresholdPx = with(density) { HorizontalSeekGestureHelper.START_THRESHOLD.toPx() }
val directionThresholdPx = with(density) { 20.dp.toPx() } // Threshold to determine drag direction val directionThresholdPx = with(density) { 20.dp.toPx() }
val dragActive = remember { mutableStateOf(false) }
Box( Box(
modifier = modifier modifier = modifier
@@ -39,8 +42,9 @@ fun PlayerGesturesLayer(
.fillMaxHeight(0.90f) .fillMaxHeight(0.90f)
.pointerInput(Unit) { .pointerInput(Unit) {
detectTapGestures( detectTapGestures(
onTap = { onTap() }, onTap = { if (!dragActive.value) onTap() },
onDoubleTap = { offset -> onDoubleTap = { offset ->
if (dragActive.value) return@detectTapGestures
val screenWidth = size.width val screenWidth = size.width
val oneThird = screenWidth / 3 val oneThird = screenWidth / 3
val secondThird = oneThird * 2 val secondThird = oneThird * 2
@@ -56,6 +60,7 @@ fun PlayerGesturesLayer(
awaitEachGesture { awaitEachGesture {
val down = awaitFirstDown(requireUnconsumed = false) val down = awaitFirstDown(requireUnconsumed = false)
val startX = down.position.x val startX = down.position.x
dragActive.value = false
var accumulatedDrag = Offset.Zero var accumulatedDrag = Offset.Zero
var dragDirection: DragDirection? = null var dragDirection: DragDirection? = null
@@ -63,12 +68,12 @@ fun PlayerGesturesLayer(
var isHorizontalDragActive = false var isHorizontalDragActive = false
var lastPreviewDelta: Long? = null var lastPreviewDelta: Long? = null
val dragResult = drag(down.id) { change -> drag(down.id) { change ->
val delta = change.positionChange() val delta = change.positionChange()
accumulatedDrag += delta accumulatedDrag += delta
// Determine direction if not yet determined
if (dragDirection == null && (abs(accumulatedDrag.x) > directionThresholdPx || abs(accumulatedDrag.y) > directionThresholdPx)) { if (dragDirection == null && (abs(accumulatedDrag.x) > directionThresholdPx || abs(accumulatedDrag.y) > directionThresholdPx)) {
dragActive.value = true
dragDirection = if (abs(accumulatedDrag.x) > abs(accumulatedDrag.y)) { dragDirection = if (abs(accumulatedDrag.x) > abs(accumulatedDrag.y)) {
DragDirection.HORIZONTAL DragDirection.HORIZONTAL
} else { } else {
@@ -76,7 +81,6 @@ fun PlayerGesturesLayer(
} }
} }
// Handle based on determined direction
when (dragDirection) { when (dragDirection) {
DragDirection.HORIZONTAL -> { DragDirection.HORIZONTAL -> {
accumulatedHorizontalDrag += delta.x accumulatedHorizontalDrag += delta.x
@@ -101,13 +105,10 @@ fun PlayerGesturesLayer(
onVerticalDragRight(delta.y) onVerticalDragRight(delta.y)
} }
} }
null -> { null -> {}
// Direction not determined yet, keep accumulating
}
} }
} }
// Handle drag end
if (dragDirection == DragDirection.HORIZONTAL && isHorizontalDragActive) { if (dragDirection == DragDirection.HORIZONTAL && isHorizontalDragActive) {
val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag) val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag)
if (deltaMs != 0L) { if (deltaMs != 0L) {