mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Fix side-effects when tapping on a link in the new renderer (#7906)
The case where we move the pointer once we've started the click on a link wasn't taken into account, so the click or long click gestures weren't canceled if the gesture ended up being a 'move' one. Simplify the handler and make it more idiomatic too.
This commit is contained in:
committed by
GitHub
parent
8a5c50d2b8
commit
241f8e67bd
+13
-28
@@ -15,6 +15,8 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||||
|
import androidx.compose.foundation.gestures.awaitLongPressOrCancellation
|
||||||
|
import androidx.compose.foundation.gestures.waitForUpOrCancellation
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -53,8 +55,7 @@ import androidx.compose.ui.graphics.drawOutline
|
|||||||
import androidx.compose.ui.graphics.drawscope.Fill
|
import androidx.compose.ui.graphics.drawscope.Fill
|
||||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||||
import androidx.compose.ui.graphics.drawscope.translate
|
import androidx.compose.ui.graphics.drawscope.translate
|
||||||
import androidx.compose.ui.input.pointer.PointerEventTimeoutCancellationException
|
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
|
||||||
import androidx.compose.ui.input.pointer.changedToUp
|
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.ClipEntry
|
import androidx.compose.ui.platform.ClipEntry
|
||||||
import androidx.compose.ui.platform.LocalClipboard
|
import androidx.compose.ui.platform.LocalClipboard
|
||||||
@@ -565,34 +566,18 @@ private fun Modifier.linkTapHandler(
|
|||||||
val (url, urlText) = layoutResult.value?.urlAt(down.position, text) ?: return@awaitEachGesture
|
val (url, urlText) = layoutResult.value?.urlAt(down.position, text) ?: return@awaitEachGesture
|
||||||
down.consume()
|
down.consume()
|
||||||
|
|
||||||
val longPressTimeout = viewConfiguration.longPressTimeoutMillis
|
// Returns a non-null change if the long press timeout elapsed, or null if the gesture was canceled by movement beyond touch slop or by an up event.
|
||||||
|
if (awaitLongPressOrCancellation(down.id) != null) {
|
||||||
// Try detecting a long press by waiting for the long press timeout and checking if we received an up event before that.
|
|
||||||
// If we did, it's a tap, otherwise it's a long press.
|
|
||||||
// This warning is a false positive.
|
|
||||||
@Suppress("KotlinConstantConditions")
|
|
||||||
val isLongPress = try {
|
|
||||||
withTimeout(longPressTimeout) {
|
|
||||||
var receivedUp = false
|
|
||||||
while (!receivedUp) {
|
|
||||||
val event = awaitPointerEvent()
|
|
||||||
val up = event.changes.firstOrNull { it.id == down.id && it.changedToUp() }
|
|
||||||
if (up != null) {
|
|
||||||
receivedUp = true
|
|
||||||
up.consume()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
!receivedUp
|
|
||||||
}
|
|
||||||
} catch (_: PointerEventTimeoutCancellationException) {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLongPress) {
|
|
||||||
context.onLinkLongClick(url, urlText)
|
context.onLinkLongClick(url, urlText)
|
||||||
|
// Swallow the rest of the gesture so parents don't react to the eventual release.
|
||||||
|
waitForUpOrCancellation()?.consume()
|
||||||
} else {
|
} else {
|
||||||
context.onLinkClick(url, urlText)
|
// Either a tap (the pointer was released) or a drag (the user probably wanted to scroll).
|
||||||
|
val up = currentEvent.changes.firstOrNull { it.id == down.id && it.changedToUpIgnoreConsumed() }
|
||||||
|
if (up != null) {
|
||||||
|
up.consume()
|
||||||
|
context.onLinkClick(url, urlText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user