Skip to content

feat(web): map gestures, dropped-pin actions and swipe-away place cards on mobile - #740

Merged
Medformatik merged 1 commit into
mainfrom
feat/mobile-gestures-and-status-bar
Nov 2, 2026
Merged

Medformatik merged 1 commit into
mainfrom
feat/mobile-gestures-and-status-bar

Conversation

@Medformatik

@Medformatik Medformatik commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

What changed and why

Follow-up to #739, aimed at making the map feel like a native map app on a phone.

Tap and long-press on the map (touch only; mouse behaviour is unchanged)

  • Before: every tap on empty map dropped a gray pin, even when the user only wanted to put a card away, and there was no touch way to reach the desktop context menu's actions.
  • Now a tap on empty map puts away the dropped pin, or else the open place, and drops nothing.
  • A long-press (500 ms; panning or a second finger cancels it) drops the gray pin with a light haptic tick. Parking/crowd-report pickers, the measuring and travel-time tools, and active guidance still take precedence, as they do for taps.

Dropped-pin card on phones

  • The card now carries the right-click menu's actions as a row within thumb reach: Directions, From here, Share, Save parking, Copy, Details.
  • The card and the menu share the route, details and share logic in lib/locationActions.ts.
  • The card rests above an open sheet or the map footer, so the map credits stay readable.
  • Desktop keeps the compact card.

Swipe a place away

  • A place card, or a standalone place panel, closes when its sheet is swiped down from its lowest detent. This uses the sheet library's swipe-to-dismiss snap point, turned into an onDismiss callback because our sheets aren't dialogs.
  • The closing position exists only while the sheet rests at its lowest detent. Otherwise a quick flick from the middle would carry it straight past the lowest detent and close it. Now that flick lowers it, and a second swipe closes it.
  • Lists and directions keep their lowest detent as the floor and close explicitly (X or Back).

Status bar colour

  • The theme-color tags followed only the system colour scheme. With Dark chosen in settings on a phone set to light, the app had a bright green bar above a dark UI.
  • ThemeColorSync now points both tags at the chosen theme and restores them when System is chosen again.

Smaller

  • lib/closeSurfaces.ts now holds the "close the place / close the panel" steps. Back restore, tap-to-dismiss and swipe-to-dismiss all use it.
  • Haptics skip vibrating before the page's first tap, which Chrome refuses and logs.
  • iOS callout and text selection are disabled on the map canvas, so a long-press doesn't select anything.
  • The place and parking user docs describe the phone gestures.

Verification

  • New tests:
    • lib/mapTouch (long-press timing, jitter tolerance, cancellation, markers, the post-long-press click, touch detection);
    • MapClickHandler (mouse click drops a pin; touch tap dismisses; long-press drops; pickers and guidance win);
    • the phone card's actions;
    • sheet swipe-to-close (only from the lowest detent, not before first rest, not while covered);
    • themeColor.
  • pnpm exec vitest run --project web: 5752 passed. The 8 failures in useNavJunctions.test.tsx and CategoryResultMarkers.test.tsx also fail on an unmodified checkout in this environment.
  • tsc --noEmit passes for web and tsconfig.integrations.json. biome check . --diagnostic-level=error, Prettier on the changed docs and pnpm check-translations pass (no new strings). pnpm check-dead-code reports nothing in apps/web.
  • Browser check with Playwright on next dev, 390×844, real touch events sent through the Chrome DevTools protocol, no API backend:
    • a tap dropped no pin;
    • a long-press dropped the pin and showed the card with all six actions;
    • a tap removed it;
    • "From here" opened directions with the pin as the start, and Back closed them;
    • choosing Dark in settings set both theme-color tags to #1c1c1c, and System restored them;
    • on a standalone place, a quick 160 px flick from the middle stopped at the lowest detent, and a second swipe closed the place.
  • Not verified: a real Android or iOS device (feel of the 500 ms long-press, haptics, iOS callout suppression), and flows that need the API (reverse-geocoded pin titles, saving parking for a signed-in user).

Release and upgrade impact

No migration or operator action. On touch screens a tap on the map no longer drops a pin; a long-press does.

…ds on mobile

On a phone, every tap on empty map dropped a gray pin, even when the user only
wanted to put a card away, and there was no touch way to reach the desktop
context menu's actions.

- Touch: a tap on empty map only puts the dropped pin or the open place away;
  a long-press (500 ms, cancelled by panning or a second finger) drops the pin.
  Pickers, map tools and active guidance still take precedence. Mouse clicks
  are unchanged.
- The dropped-pin card on phones carries the context menu's actions as a row:
  Directions, From here, Share, Save parking, Copy, Details. Both share the
  route, details and share logic in lib/locationActions. The card rests above
  an open sheet or the map footer, so the map credits stay readable.
- A place (card or standalone panel) closes when its sheet is swiped down from
  its lowest detent. The closing snap point only exists while the sheet rests
  there, so a quick flick from higher up lowers it instead of closing it. Lists
  and directions keep their lowest detent as the floor.
- The theme-color tags (status bar) follow the theme chosen in settings, not
  only the system scheme.
- Haptics skip vibration before the page's first tap, which Chrome refuses.
@Medformatik
Medformatik enabled auto-merge (squash) November 2, 2026 11:27
@Medformatik
Medformatik merged commit 7825076 into main Nov 2, 2026
26 of 41 checks passed
@Medformatik
Medformatik deleted the feat/mobile-gestures-and-status-bar branch November 2, 2026 11:30
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant