Stats coverage maps + per-leg transport + more safe simplifications - #28
Merged
Merged
Conversation
More from the app-wide analysis — each type-checked and test-covered, no behavior change: - Shared helpers replace duplicated logic: `placeFlag` (trip flag emoji, was copied in three travel components), `nullableSanitized`/`optionalLabel` (Zod transforms in models.ts, were repeated 4×/3× — the generated JSON-Schema artifact is byte-identical), a generic `ts` accessor in sync/engine, and `partitionTombs`/`snapFor` in sync/runSync. - offline/tiles: one `defaultFetch`, one `prefetchDisabled()` guard, and one `runPrefetchPool()` replacing two near-identical 2-worker loops. - Dead code / tighter surface: drop the unused `MOMENT_GROUP_ORDER`, the write- only `BrowseRow.lat/lon`, the `PackPlace` type, the never-passed `hint` prop on the stats NameList; collapse `fullCitiesOptedIn`/`fullCitiesEnabled` into one; drop unreferenced i18n barrel re-exports and the `export` on `MAX_PACK_PLACES`. - Smaller reads: PassportScreen counts instead of allocating; PublishScreen reuses `passNorm`; importJson renames a shadowing loop var; guideNames gets its explicit return type; photoBlobs' decode is one loop. Gate: tsc clean, 459 unit tests (incl. schema-artifact + import-security), e2e green (trip-reconstruction, trip-routemap, offline, a11y).
Under each country card, the long "regions to visit / monuments to see" text lists are replaced by a static, non-interactive coverage map — far quicker to read at a glance: - The country's silhouette (bundled offline Natural Earth geometry, matched by numeric code), framed to the MAINLAND ring so a country with far-flung overseas territories (France, the US) doesn't zoom out to the whole globe. - Soft "still to explore" blobs over the regions you haven't visited (centroid + spread of each unvisited subdivision's cities). - A dot per city you've been. Pure SVG, computed lazily when the card opens (no MapLibre, nothing fetched beyond the shared, cached land geometry). It's a role=img with a descriptive label (region counts + what the marks mean), so it passes the axe WCAG 2.1 AA gate; the full, tappable region/monument lists still live on the country's own page (the "Open full page" link). Gate: tsc clean, 459 unit tests, e2e green — a new stats-covmap spec (render + axe) and stats-drill.
Reconstruct a journey that changes transport partway: fly Paris→Tokyo, then take the train Tokyo→Osaka. Each leg (stop i → i+1) has its own mode, and a run of the same mode reads as a sub-trip. - Composer: a compact transport picker sits on the connector between each pair of stops (replacing the single trip-level "How" select). New legs continue the previous leg's mode, so tapping stops in a row keeps one transport until you change it. Live arcs on the real map colour each leg by its own mode. - Data model: Trip.legModes (schema v12) — an optional per-leg array, saved ONLY when a leg actually differs from the trip's `mode`, so a uniform single-mode trip stays byte-identical to a pre-v12 file. A leg with no entry falls back to `mode`. Older apps reject a v12 file gracefully via the version guard. - travelTotals now splits distance PER LEG under that leg's transport, and counts a trip once per distinct mode it uses — so the stats travel breakdown is right for mixed journeys (single-mode trips are unchanged). - Pure chain helpers (appendStop/removeStopAt/moveStopTo/setLegMode/legModeAt) keep legModes in sync with the stops. Gate: tsc clean, 466 unit tests (new tripLegs spec: chain sync, per-leg arcs, per-leg totals; schema artifact regenerated), e2e green — a new trip-legmodes spec (set → save → reopen persists), trip-reconstruction, tripedit, trips, trip-routemap, and the composer a11y (axe WCAG 2.1 AA).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits.
Stats: a coverage map per country (replaces the to-do lists)
Under each country card, the long "regions to visit / monuments to see" text lists are replaced by a static, non-interactive coverage map — quicker to read at a glance:
Pure SVG, computed lazily when a card opens (no MapLibre; nothing fetched beyond the shared, cached land geometry). It's a
role="img"with a descriptive label, so it passes the axe gate; the full tappable lists still live on the country's own page.Travel: per-leg transport (mix modes in one journey)
Reconstruct a journey that changes transport partway — fly Paris→Tokyo, then train Tokyo→Osaka. A compact transport picker sits on the connector between each pair of stops; a run of one mode reads as a sub-trip. New data field
Trip.legModes(schema v12), saved only when a leg actually differs, so uniform single-mode trips stay byte-identical to pre-v12 files.travelTotalsnow splits distance per leg under its own mode, and the real map colours each leg by its transport.More safe simplifications
The second batch from the app-wide analysis (shared
placeFlag/nullableSanitized/optionalLabelhelpers,defaultFetch/prefetchDisabled/runPrefetchPoolin offline/tiles, dead-code and tighter-surface cleanups) — all type-checked and test-covered, no behavior change.Gate:
tscclean · 466 unit tests (newtripLegsspec; schema artifact regenerated) · e2e green — newstats-covmapandtrip-legmodesspecs, plus trip-reconstruction, trip-routemap, tripedit, trips, and a11y (axe WCAG 2.1 AA).🤖 Generated with Claude Code
https://claude.ai/code/session_014W6tgHRgLEugCsbKC9ccST
Generated by Claude Code