Commit graph

10 commits

Author SHA1 Message Date
977008d6bd Fit route bounds to visible map area above open mobile panel
fitBounds was fitting to the full viewport height, placing half the route
behind the panel. Add panel-aware padding (65vh at bottom) on mobile so
the entire route is visible in the uncovered portion of the map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 11:16:08 +00:00
13beaf21ed Auto-open panel on mobile when no route is loaded
Shows the form immediately instead of an empty world map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 11:06:37 +00:00
ceea5706b3 Fix mobile panel visibility with floating button and iOS CSS fixes
Replace the unreliable peek-strip approach with a floating '☰ Controls'
button on the map. The button is always clearly visible, hides when the
panel is open, and reappears when the panel closes.

Also fix two iOS Safari issues that were hiding the sidebar entirely:
- overflow:hidden on body clips position:fixed elements in mobile Safari;
  reset to overflow:visible in the mobile media query
- Add viewport-fit=cover and env(safe-area-inset-bottom) padding so the
  sidebar clears the home indicator / browser toolbar
- Use 100dvh instead of 100vh to avoid iOS address-bar overflow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:22:53 +00:00
6927efca54 Add mobile bottom-sheet layout
On narrow screens the sidebar collapses to a 48px handle strip at the
bottom of the screen. Tapping the handle slides the panel up to 65vh,
revealing the full stop list and controls. The map takes the full
viewport width when the panel is closed or peek-visible.

The handle label updates dynamically to show the loaded route name.
The panel auto-opens when a route or route_master finishes loading.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:02:14 +00:00
7a4cdfcca7 Include route name in page title
Update document.title to "<route name> – OSM Public Transport → GeoJSON"
when a route or route_master is loaded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 20:58:10 +00:00
17df83d043 Use url_for() for all internal URLs; fix ProxyPass compatibility
All hardcoded paths (/load, /docs, /, /api/route/ etc.) are replaced
with url_for() in templates, so Flask's APPLICATION_ROOT and
ProxyFix generate correct URLs regardless of mount path.

For app.js (a static file), inject a URLS object from the template
alongside RELATION_ID:
  URLS.routeApi, .segmentApi, .routeMasterApi, .routePage
Each is generated with url_for(..., relation_id=0)[:-1] to give a
prefix that JS appends relation IDs to. The popstate handler now
strips the URLS.routePage prefix instead of matching a hardcoded
leading slash.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 20:31:01 +00:00
3a158c189c Add OSM website links for route and route_master panels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 19:23:24 +00:00
9b5a510d02 Handle browser back/forward for in-page route navigation
Listen for popstate events and reload the relation from the URL path,
so the back button correctly returns to the route_master view after
navigating to an individual route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 19:21:31 +00:00
f6dd68ed75 Avoid map zoom-out when navigating between routes
Route links (route_master list, other directions) now intercept clicks
and call loadRoute() + history.pushState() instead of doing a full page
reload, so the map stays at its current position and zooms smoothly into
the new route. Ctrl/cmd/middle-click still opens in a new tab via href.

Introduce currentRelationId (mutable) to track the loaded relation so
loadSegment() uses the correct ID after in-page navigation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 19:18:05 +00:00
e0ade9e5ab Add web frontend and refactor core to use OsmError
- Refactor core.py: replace sys.exit() calls with OsmError exceptions
  so the library is safe to use from Flask and other callers
- Add fetch_sibling_routes and fetch_route_master_routes to core.py
- Add Flask web frontend (web/app.py, templates, static assets):
  - Map view with Leaflet; full route drawn in grey on load
  - Sidebar stop list; active-slot UX for From/To selection
  - Segment preview and download (full route or selected segment)
  - Include-stops toggle applied client-side
  - Bookmarkable URLs: GET /<relation_id>
  - Clear selection button
  - Other directions panel (sibling routes from same route_master)
  - route_master handling: draws all member routes in colour on map
    with links to each individual direction
- Add SVG favicon
- Add py.typed marker; add .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:59:21 +00:00