diff --git a/lib/frontend/screens/chats/chat_screen.dart b/lib/frontend/screens/chats/chat_screen.dart index 216c7c9..d82a6be 100644 --- a/lib/frontend/screens/chats/chat_screen.dart +++ b/lib/frontend/screens/chats/chat_screen.dart @@ -1705,6 +1705,7 @@ class _LongPressBubble extends StatefulWidget { class _LongPressBubbleState extends State<_LongPressBubble> { final GlobalKey _boundaryKey = GlobalKey(); MessageActionsController? _controller; + int? _lastPointerId; @override void dispose() { @@ -1714,6 +1715,9 @@ class _LongPressBubbleState extends State<_LongPressBubble> { } void _onLongPressStart(LongPressStartDetails details) { + final pointerId = _lastPointerId; + if (pointerId == null) return; + final ctx = _boundaryKey.currentContext; if (ctx == null) return; final renderObject = ctx.findRenderObject(); @@ -1734,7 +1738,7 @@ class _LongPressBubbleState extends State<_LongPressBubble> { Haptics.medium(); final controller = MessageActionsController(); - controller.updatePointer(details.globalPosition); + controller.attach(pointerId, details.globalPosition); _controller = controller; Navigator.of(ctx) @@ -1760,15 +1764,7 @@ class _LongPressBubbleState extends State<_LongPressBubble> { Widget build(BuildContext context) { return Listener( behavior: HitTestBehavior.deferToChild, - onPointerMove: (event) { - _controller?.updatePointer(event.position); - }, - onPointerUp: (event) { - _controller?.commit(); - }, - onPointerCancel: (event) { - _controller?.commit(); - }, + onPointerDown: (event) => _lastPointerId = event.pointer, child: GestureDetector( behavior: HitTestBehavior.deferToChild, onLongPressStart: _onLongPressStart, diff --git a/lib/frontend/widgets/message_actions_overlay.dart b/lib/frontend/widgets/message_actions_overlay.dart index c3e7b66..39c4d5d 100644 --- a/lib/frontend/widgets/message_actions_overlay.dart +++ b/lib/frontend/widgets/message_actions_overlay.dart @@ -9,18 +9,34 @@ import '../../core/utils/haptics.dart'; import 'custom_notification.dart'; class MessageActionsController extends ChangeNotifier { + int? _pointerId; Offset? pointer; Offset? initialPointer; bool committed = false; bool movedSignificantly = false; - void updatePointer(Offset p) { - initialPointer ??= p; - pointer = p; - if (!movedSignificantly && (p - initialPointer!).distance > 18) { - movedSignificantly = true; + void attach(int pointerId, Offset initial) { + if (_pointerId != null) return; + _pointerId = pointerId; + initialPointer = initial; + pointer = initial; + GestureBinding.instance.pointerRouter + .addRoute(pointerId, _onPointerEvent); + } + + void _onPointerEvent(PointerEvent event) { + if (committed) return; + if (event is PointerMoveEvent) { + pointer = event.position; + if (initialPointer != null && + !movedSignificantly && + (event.position - initialPointer!).distance > 18) { + movedSignificantly = true; + } + notifyListeners(); + } else if (event is PointerUpEvent || event is PointerCancelEvent) { + commit(); } - notifyListeners(); } void commit() { @@ -28,6 +44,17 @@ class MessageActionsController extends ChangeNotifier { committed = true; notifyListeners(); } + + @override + void dispose() { + final id = _pointerId; + if (id != null) { + GestureBinding.instance.pointerRouter + .removeRoute(id, _onPointerEvent); + _pointerId = null; + } + super.dispose(); + } } class MessageActionsRoute extends PageRouteBuilder {