Merge FB-10: fix map pan-recenter race
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# FB-10 — Manual map pan loses a race against the follow-recenter timer
|
||||
|
||||
**Depends on** — · **Size** M · **Status** Not started
|
||||
**Depends on** — · **Size** M · **Status** Done
|
||||
|
||||
## Goal
|
||||
The rider must be able to pan the map and have it stay where they put it. Today a pan
|
||||
@@ -189,3 +189,53 @@ Any change to how often ambient position ticks arrive (`_interval` in
|
||||
own needs (V3-04) and is not the bug; the bug is `RideMap` reacting to every tick with a
|
||||
camera move regardless of what the rider is doing. FB-11's Route Planner tile issue,
|
||||
tracked separately.
|
||||
|
||||
## Outcome
|
||||
Shipped exactly as designed, with no deviation.
|
||||
|
||||
`lib/src/ui/components/ride_map.dart` now has a `_gestureInProgress` field on
|
||||
`_RideMapState`. The `FlutterMap` is wrapped in a `Listener` that sets it `true` on
|
||||
`onPointerDown` and `false` on `onPointerUp`/`onPointerCancel`. The `Listener` only
|
||||
observes pointer events; it does not consume them, so `flutter_map`'s own drag and
|
||||
pinch-zoom recognizers still work untouched. Both `postFrameCallback` bodies in
|
||||
`didUpdateWidget` now check `if (_gestureInProgress) return;` right before the
|
||||
`_controller.move(...)` call, alongside the existing `mounted`/`_following` checks.
|
||||
`onPositionChanged` was left alone, as the design said.
|
||||
|
||||
Added one new widget test to `test/ride_map_test.dart`, in the "always-interactive
|
||||
map + recenter (FB-06)" group: `a real drag beats an ambient tick that lands
|
||||
mid-drag (FB-10)`. It starts a real pointer with `tester.startGesture`, holds it
|
||||
down, then rebuilds the widget with a changed `ambientPosition` to simulate a GPS
|
||||
tick landing mid-drag, and asserts right there — before any pointer movement — that
|
||||
the camera has not snapped to the ambient fix. It then moves and lifts the pointer
|
||||
and asserts the same thing again for the completed drag.
|
||||
|
||||
Getting this test to actually catch the bug took one extra iteration. The first
|
||||
version did the pointer-down, the mid-drag ambient tick, then a real move-and-lift,
|
||||
and only checked the camera position at the very end. That version passed even with
|
||||
the fix removed, because the final drag always overwrites the camera regardless of
|
||||
what the buggy recenter did in between — a drag is relative motion, so wherever the
|
||||
camera started, the drag moves it away from there, and the end position is never
|
||||
exactly equal to the ambient fix either way. The fix was to add the same assertion
|
||||
right after the mid-drag tick, before any pointer movement happens. At that point,
|
||||
with the pointer down but not yet moved, the old code snaps the camera to exactly
|
||||
the ambient position (confirmed by temporarily removing the two
|
||||
`_gestureInProgress` guards and re-running: the test failed with `Actual: <51.5>`,
|
||||
the exact ambient fix latitude); the fixed code leaves the camera where it was.
|
||||
Both the "old code fails, fixed code passes" checks were run and confirmed before
|
||||
finishing.
|
||||
|
||||
One unrelated flake showed up during a full `flutter test` run:
|
||||
`test/geo_test.dart`'s "douglas-peucker handles a full ride without stack overflow
|
||||
and stays fast" failed once, then passed on every subsequent run in isolation and in
|
||||
the full suite. It looks like a timing-sensitive performance assertion, not
|
||||
something this change touches -- `ride_map.dart` and `geo.dart` share no code path.
|
||||
|
||||
`flutter analyze` stayed clean: the same 4 pre-existing info-level issues in
|
||||
`crash_reporter.dart` and `map_connectivity.dart`, nothing new. `flutter test` went
|
||||
from 434 to 435 passing (the one new test), everything else green.
|
||||
|
||||
No Android emulator or `adb` was available in this environment, so the on-device
|
||||
check in Implementation step 5 was not attempted here. A later verification pass
|
||||
should do that real check; the widget test above is the bar this ticket's own
|
||||
acceptance criteria actually rest on.
|
||||
|
||||
Reference in New Issue
Block a user