From 59e5829b2a83d10b9070832fa3f9861c0e0502b8 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Sun, 27 Sep 2026 18:47:29 +0700 Subject: [PATCH] feat(directions): make the route dialog usable as guidance, not just a preview Answering 'are we giving the best navigation experience?': no, it was a preview with dead ends. Fixes the concrete gaps: - ETA: 'arrive ~08:10 PM' alongside the duration. - Mode memory: the last travel mode is remembered (skatespots:route-mode), so cyclists/drivers aren't reset to Skate/Walk every trip. - Tappable steps: each step pans the map and highlights; added a 'Whole route' re-fit button to zoom back out. - Taller route map on desktop (h-64 sm:h-80). - min-h-0 on step rows: the app-wide 44px mobile touch-target rule was making every step a 44px slab (rows now 29px). Still out of scope (documented, not faked): live turn-by-turn following, voice guidance and offline routing. --- AGENTS.md | 9 +++- release-notes.txt | 5 +- src/components/RouteDialog.tsx | 93 +++++++++++++++++++++++++++++----- 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2e173b7..9a35c62 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -201,7 +201,14 @@ session with **no other memory of this project**. So: last-resort fallback and its result is flagged `approximate` ("driving estimate") so we never pass driving numbers off as walking. Moto≈car is labelled honestly; the foot summary also shows a ~10 km/h `skateTime` cruise - estimate ("~6 min on a board") next to the walking time. **Transit** mode uses **Transitous** (`api.transitous.org`, + estimate ("~6 min on a board") next to the walking time. The dialog also + remembers the last mode (`localStorage: skatespots:route-mode`), shows an ETA + ("arrive ~08:10 PM"), and each step row is **tappable** (pans the map + highlights) + with a "Whole route" re-fit button. + - ⚠️ `index.css` has a global mobile rule `button, [role=button] { min-height: + 44px; min-width: 44px }` for touch targets. Any dense list of ` + )} {/* Summary bar */} @@ -434,6 +486,7 @@ export function RouteDialog({
{formatDuration(route.durationS)} + · arrive ~{etaClock(route.durationS)} {TRAVEL_MODES.find((m) => m.mode === mode)?.approximate && ( · uses driving roads )} @@ -468,16 +521,32 @@ export function RouteDialog({
    {route.steps.map((s, i) => ( -
  1. - - {i + 1} - - {s.instruction} - {s.distanceM >= 10 && ( - - {formatDistance(s.distanceM / 1000)} +
  2. +
  3. ))}