diff --git a/android/build.gradle.kts b/android/build.gradle.kts index a860043..60dbae3 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -7,7 +7,7 @@ plugins { dependencies { implementation(project(":reorderable")) - implementation("androidx.compose.runtime:runtime:1.8.1") + implementation("androidx.compose.runtime:runtime:1.8.2") implementation("androidx.compose.material3:material3:1.3.2") implementation("androidx.activity:activity-compose:1.10.1") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.9.0") diff --git a/build.gradle.kts b/build.gradle.kts index 4b813bb..6e53b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,9 +8,9 @@ plugins { } ext { - extra["compileSdkVersion"] = 35 + extra["compileSdkVersion"] = 36 extra["minSdkVersion"] = 21 - extra["targetSdkVersion"] = 35 + extra["targetSdkVersion"] = 36 } allprojects { diff --git a/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DetectReorder.kt b/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DetectReorder.kt index d73f341..fc94227 100644 --- a/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DetectReorder.kt +++ b/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DetectReorder.kt @@ -15,7 +15,9 @@ */ package org.burnoutcrew.reorderable +import androidx.compose.foundation.gestures.awaitEachGesture import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.foundation.gestures.awaitLongPressOrCancellation import androidx.compose.foundation.gestures.forEachGesture import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset @@ -25,20 +27,18 @@ import androidx.compose.ui.input.pointer.pointerInput fun Modifier.detectReorder(state: ReorderableState<*>) = this.then( Modifier.pointerInput(Unit) { - forEachGesture { - awaitPointerEventScope { - val down = awaitFirstDown(requireUnconsumed = false) - var drag: PointerInputChange? - var overSlop = Offset.Zero - do { - drag = awaitPointerSlopOrCancellation(down.id, down.type) { change, over -> - change.consume() - overSlop = over - } - } while (drag != null && !drag.isConsumed) - if (drag != null) { - state.interactions.trySend(StartDrag(down.id, overSlop)) + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false) + var drag: PointerInputChange? + var overSlop = Offset.Zero + do { + drag = awaitPointerSlopOrCancellation(down.id, down.type) { change, over -> + change.consume() + overSlop = over } + } while (drag != null && !drag.isConsumed) + if (drag != null) { + state.interactions.trySend(StartDrag(down.id, overSlop)) } } } @@ -48,11 +48,9 @@ fun Modifier.detectReorder(state: ReorderableState<*>) = fun Modifier.detectReorderAfterLongPress(state: ReorderableState<*>) = this.then( Modifier.pointerInput(Unit) { - forEachGesture { - val down = awaitPointerEventScope { - awaitFirstDown(requireUnconsumed = false) - } - awaitLongPressOrCancellation(down)?.also { + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false) + awaitLongPressOrCancellation(down.id).also { state.interactions.trySend(StartDrag(down.id)) } } diff --git a/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DragGesture.kt b/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DragGesture.kt index 24e90d9..ca81d00 100644 --- a/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DragGesture.kt +++ b/reorderable/src/commonMain/kotlin/org/burnoutcrew/reorderable/DragGesture.kt @@ -88,60 +88,6 @@ internal suspend fun AwaitPointerEventScope.awaitPointerSlopOrCancellation( } } -internal suspend fun PointerInputScope.awaitLongPressOrCancellation( - initialDown: PointerInputChange -): PointerInputChange? { - var longPress: PointerInputChange? = null - var currentDown = initialDown - val longPressTimeout = viewConfiguration.longPressTimeoutMillis - return try { - // wait for first tap up or long press - withTimeout(longPressTimeout) { - awaitPointerEventScope { - var finished = false - while (!finished) { - val event = awaitPointerEvent(PointerEventPass.Main) - if (event.changes.fastAll { it.changedToUpIgnoreConsumed() }) { - // All pointers are up - finished = true - } - - if ( - event.changes.fastAny { - it.isConsumed || it.isOutOfBounds(size, extendedTouchPadding) - } - ) { - finished = true // Canceled - } - - // Check for cancel by position consumption. We can look on the Final pass of - // the existing pointer event because it comes after the Main pass we checked - // above. - val consumeCheck = awaitPointerEvent(PointerEventPass.Final) - if (consumeCheck.changes.fastAny { it.isConsumed }) { - finished = true - } - if (!event.isPointerUp(currentDown.id)) { - longPress = event.changes.fastFirstOrNull { it.id == currentDown.id } - } else { - val newPressed = event.changes.fastFirstOrNull { it.pressed } - if (newPressed != null) { - currentDown = newPressed - longPress = currentDown - } else { - // should technically never happen as we checked it above - finished = true - } - } - } - } - } - null - } catch (_: TimeoutCancellationException) { - longPress ?: initialDown - } -} - private fun PointerEvent.isPointerUp(pointerId: PointerId): Boolean = changes.fastFirstOrNull { it.id == pointerId }?.pressed != true