Repository navigation
fix(android): preserve camera updates during long presses - #4358
RobJacobson wants to merge 4 commits into
Conversation
mfazekas
left a comment
There was a problem hiding this comment.
Thanks for digging into #2738, it's a real problem and the analysis is thorough. Before we can review it properly, could you rework it a bit:
- Please rebase onto main. #4371 added
OnCameraWillMoveMapListener/RNMBXMapView.cameraWillMoveMap(), which is called whenever Camera is about to move the map. That's the natural single place to end the long press, so the separate calls inCameraUpdateQueue,moveByandscaleByshouldn't be needed. - Please keep the PR to the Android native fix and a small unit test. The Long Press Camera example is fine if you want to keep it. Please drop the iOS XCUITest suite, the Xcode project/scheme changes, the Python touch script and the CONTRIBUTING section. iOS code is unchanged, and we'd rather not maintain a separate test harness for this.
- Instead of overriding
dispatchTouchEventand injecting a syntheticACTION_CANCEL, could you try the SDK's gesture API? AnOnMoveListener(mapView.gestures.addOnMoveListener) that returnstruefromonMovewhile a camera command started during the long press is running should stop the drift. It avoids fake touch events and is less likely to interfere with other long-press users such as draggablePointAnnotation. If it doesn't work, a short note on why would be great.
- Cancel native long-press gestures before queued camera updates - Consume remaining touch events until release and restore panning on new touches - Add regression tests for gesture ownership and camera-update ordering
- Cancel active map long presses before moveBy and scaleBy - Add a native touch regression covering camera motion and gesture cleanup - Add the long-press camera example and regenerate its documentation links
- Add a permanent native UI suite for all five long-press camera modes - Verify relative camera destinations, zoom, release stability, and the next pan - Add the LongPressCamera Xcode scheme and contributor run instructions
- Route long-press camera takeover through the shared camera hook. - Suppress only the held touch through the Mapbox move listener. - Remove the separate iOS and Python test harnesses and keep focused Android coverage.
be20e5f to
1bf9d19
Compare
|
Thanks for the review. I rebased onto current
On the Android emulator, held-finger drift passed |
|
Thanks, this is much closer to what we wanted. I could reproduce #2738 on main (flyTo/easeTo/moveBy/scaleBy all get cancelled by the held finger) and your change fixes all of them on the emulator. A few small things before merge:
Note also that #4197 touches the same move listener and always ignores movement after a long press (iOS behaviour); we'll need to reconcile the two. |
Summary
MapView.onLongPressfires while the finger is still down. On Android, a continuing move gesture can compete with a camera command started by that callback (#2738).This revision rebases onto current
mainand uses #4371's shared camera hook. It removes the calls inCameraUpdateQueue,moveBy, andscaleBy, along with the syntheticACTION_CANCELanddispatchTouchEventoverride. A small Android unit test covers the suppression state. The Camera > Long Press Camera example remains; the iOS XCUITest/Xcode changes, Python touch runner, and CONTRIBUTING section are removed. The annotation-drag early return remains in place.Evidence
scaleBystayed at zoom 16 instead of reaching 17.flyTo, eased and immediatesetCamera,moveBy, andscaleBy. The completed camera center stayed stable through release;scaleByreached zoom 17. A long press without a camera command still panned, and a fresh touch panned after each camera command. Dragging the example's draggablePointAnnotationmoved the marker while the map stayed in place.yarn testpassed repository lint and all 167 JavaScript tests.yarn generatecompleted without additional generated changes.To check manually: run the example, open Camera > Long Press Camera, select a mode, long-press away from center and drift the held finger; then lift and pan again.
Merge Danger
Door: Two-way
Blast Radius: Android map gestures. Suppression is limited to move events from the touch that produced a long press and only after a Camera command. A later touch is distinguished by Android's touch
downTime. No public JavaScript API or iOS implementation changes.