diff --git a/app/src/main/java/hu/bbara/purefin/player/helper/HorizontalSeekGestureHelper.kt b/app/src/main/java/hu/bbara/purefin/player/helper/HorizontalSeekGestureHelper.kt index 74d6fe0..7eedbd8 100644 --- a/app/src/main/java/hu/bbara/purefin/player/helper/HorizontalSeekGestureHelper.kt +++ b/app/src/main/java/hu/bbara/purefin/player/helper/HorizontalSeekGestureHelper.kt @@ -5,10 +5,10 @@ import kotlin.math.abs import kotlin.math.pow internal object HorizontalSeekGestureHelper { - val START_THRESHOLD = 24.dp - private const val COEFFICIENT = 1.3f - const val EXPONENT = 1.8f - private const val MAX_DELTA_MS = 300_000L + val START_THRESHOLD = 12.dp + private const val COEFFICIENT = 3.1f + const val EXPONENT = 1.7f + private const val MAX_DELTA_MS = 12_000_000L fun deltaMs(rawDelta: Float): Long { val magnitude = abs(rawDelta) diff --git a/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerGesturesLayer.kt b/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerGesturesLayer.kt index c5d279d..63cf563 100644 --- a/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerGesturesLayer.kt +++ b/app/src/main/java/hu/bbara/purefin/player/ui/components/PlayerGesturesLayer.kt @@ -1,21 +1,22 @@ package hu.bbara.purefin.player.ui.components -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.gestures.detectDragGestures -import androidx.compose.foundation.gestures.detectHorizontalDragGestures +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.gestures.drag import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.pointer.PointerInputChange import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.input.pointer.positionChange import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import hu.bbara.purefin.player.helper.HorizontalSeekGestureHelper +import kotlin.math.abs @Composable fun PlayerGesturesLayer( @@ -31,85 +32,96 @@ fun PlayerGesturesLayer( ) { val density = LocalDensity.current val horizontalThresholdPx = with(density) { HorizontalSeekGestureHelper.START_THRESHOLD.toPx() } + val directionThresholdPx = with(density) { 20.dp.toPx() } // Threshold to determine drag direction Box( modifier = modifier .fillMaxWidth(0.90f) .fillMaxHeight(0.70f) -// .background(Color(2f, 2f, 2f, 0.3f)) .pointerInput(Unit) { detectTapGestures( onTap = { onTap() }, onDoubleTap = { offset -> - // TODO extract it into an enum val screenWidth = size.width val oneThird = screenWidth / 3 val secondThird = oneThird * 2 - if (offset.x < oneThird) { - onDoubleTapLeft() - } else if (offset.x >= oneThird && offset.x <= secondThird) { - onDoubleTapCenter() - } else { - onDoubleTapRight() + when { + offset.x < oneThird -> onDoubleTapLeft() + offset.x <= secondThird -> onDoubleTapCenter() + else -> onDoubleTapRight() } } ) } .pointerInput(Unit) { - detectDragGestures { change, dragAmount -> - val horizontalThreshold = size.width / 2 - if (change.position.x < horizontalThreshold) { - onVerticalDragLeft(dragAmount.y) - } else { - onVerticalDragRight(dragAmount.y) + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false) + val startX = down.position.x + + var accumulatedDrag = Offset.Zero + var dragDirection: DragDirection? = null + var accumulatedHorizontalDrag = 0f + var isHorizontalDragActive = false + var lastPreviewDelta: Long? = null + + val dragResult = drag(down.id) { change -> + val delta = change.positionChange() + accumulatedDrag += delta + + // Determine direction if not yet determined + if (dragDirection == null && (abs(accumulatedDrag.x) > directionThresholdPx || abs(accumulatedDrag.y) > directionThresholdPx)) { + dragDirection = if (abs(accumulatedDrag.x) > abs(accumulatedDrag.y)) { + DragDirection.HORIZONTAL + } else { + DragDirection.VERTICAL + } + } + + // Handle based on determined direction + when (dragDirection) { + DragDirection.HORIZONTAL -> { + accumulatedHorizontalDrag += delta.x + if (!isHorizontalDragActive && abs(accumulatedHorizontalDrag) >= horizontalThresholdPx) { + isHorizontalDragActive = true + } + if (isHorizontalDragActive) { + change.consume() + val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag) + if (deltaMs != 0L && deltaMs != lastPreviewDelta) { + lastPreviewDelta = deltaMs + onHorizontalDragPreview(deltaMs) + } + } + } + DragDirection.VERTICAL -> { + val isLeftSide = startX < size.width / 2 + if (isLeftSide) { + onVerticalDragLeft(delta.y) + } else { + onVerticalDragRight(delta.y) + } + } + null -> { + // Direction not determined yet, keep accumulating + } + } } + + // Handle drag end + if (dragDirection == DragDirection.HORIZONTAL && isHorizontalDragActive) { + val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag) + if (deltaMs != 0L) { + onHorizontalDrag(deltaMs) + onHorizontalDragPreview(deltaMs) + } + } + onHorizontalDragPreview(null) } } - .pointerInput(Unit) { - var accumulatedHorizontalDrag = 0f - var isHorizontalDragActive = false - var lastPreviewDelta: Long? = null - detectHorizontalDragGestures( - onDragStart = { - accumulatedHorizontalDrag = 0f - isHorizontalDragActive = false - lastPreviewDelta = null - onHorizontalDragPreview(null) - }, - onHorizontalDrag = { change, dragAmount -> - accumulatedHorizontalDrag += dragAmount - if (!isHorizontalDragActive && kotlin.math.abs(accumulatedHorizontalDrag) >= horizontalThresholdPx) { - isHorizontalDragActive = true - } - if (isHorizontalDragActive) { - change.consume() - val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag) - if (deltaMs != 0L && deltaMs != lastPreviewDelta) { - lastPreviewDelta = deltaMs - onHorizontalDragPreview(deltaMs) - } - } - }, - onDragEnd = { - if (isHorizontalDragActive) { - val deltaMs = HorizontalSeekGestureHelper.deltaMs(accumulatedHorizontalDrag) - if (deltaMs != 0L) { - onHorizontalDrag(deltaMs) - onHorizontalDragPreview(deltaMs) - } - } - accumulatedHorizontalDrag = 0f - isHorizontalDragActive = false - lastPreviewDelta = null - onHorizontalDragPreview(null) - }, - onDragCancel = { - accumulatedHorizontalDrag = 0f - isHorizontalDragActive = false - lastPreviewDelta = null - onHorizontalDragPreview(null) - } - ) - } ) } + +private enum class DragDirection { + HORIZONTAL, + VERTICAL +}