Commit Graph
4 Commits
Author SHA1 Message Date
randy 67585cd99a Gate GNSS (turning it on and its position) behind login
CI / check (push) Successful in 48s
CI / deploy (push) Successful in 23s
GET /api/gnss/position now requires login (app.rb) -- it reveals
where the receiver physically is, not something to leave open to
anyone with the URL. GnssControl's sidebar icon is hidden entirely
when logged out (same pattern as the tree UI's write controls) rather
than shown and failing to ever get a fix.

LocateControl needs no changes: it only ever reaches GNSS through
GnssControl#isEnabled(), which can't turn true for a logged-out
visitor if the toggle is never on the page to click. Its
browser-geolocation fallback stays open to everyone -- a visitor's
own device asking for their own location isn't something to gate.

Extracted isLoggedIn() out of gpx.js into a shared public/js/auth.js
(gnss.js needed the same check) rather than duplicating it.

Verified: /api/gnss/position returns 401 logged out; the sidebar icon
is actually hidden (computed display: none, not just present-but-
unstyled -- checked properly this time after almost repeating the
same present-vs-visible test mistake the .gpx-panel__action bug
already taught).
2026-09-08 14:06:29 +02:00
randy d9879bad60 Switch to GNSS immediately if it turns on mid-track
CI / check (push) Successful in 47s
CI / deploy (push) Successful in 18s
If Locate was already tracking via the browser-geolocation fallback
(GNSS was off when clicked) and GNSS then gets turned on via the
sidebar, it kept using the browser position until the button was
clicked again -- the browser's own (often less accurate) position had
no business still being used once the app's own receiver had a fix.

GnssControl#onEnabledChange (a small internal callback list) notifies
LocateControl the moment the sidebar toggle changes; if it's actively
tracking via the browser at that point, it stops that and jumps to
GNSS's position instead.

Caught a real bug while verifying this: the automatic handoff reused
the same jump-to-GNSS helper a deliberate click uses, which alerts if
GNSS has no fix yet -- but GNSS only just turned on and almost
certainly hasn't gotten its first poll response back yet at the exact
moment the handoff fires, so this popped a blocking window.alert()
(which halts the whole page until dismissed) on every single enable.
A test hung on exactly this before I noticed. Fixed with an
alertIfNoFix option, true only for the deliberate-click path.

Verified end to end (simulating the "already tracking" state directly
since headless geolocation isn't reliable enough to trust as the
trigger): toggling GNSS mid-track removes the blue browser marker,
shows the green GNSS one once its poll lands, and no dialog appears.
2026-09-08 08:50:43 +02:00
randy 6e5676c890 Make "find my location" actually follow GNSS, gated on the sidebar toggle
CI / check (push) Successful in 44s
CI / deploy (push) Successful in 18s
Two fixes based on feedback after the last commit:

1. The map wasn't following the position at all -- only the first fix
   recentered, later updates just moved the marker. Now every fix
   recenters (easeTo, not flyTo, after the first one, so it doesn't
   repeat that zoom swoop on every update) -- matches how
   GeolocateControl's own trackUserLocation always behaved.

2. GNSS should only be used when explicitly turned on via the sidebar
   "GNSS" icon, not whenever a receiver happens to have a fix --
   simpler to test against the simulator that way, and puts the
   visitor in control of whether GNSS is engaged at all. GnssControl
   now owns following the map on its own (same flyTo-once/easeTo-after
   pattern) whenever it's enabled; LocateControl checks
   GnssControl#isEnabled() and, when true, just jumps to
   #getPosition()'s current fix and reuses its existing .gnss-marker
   instead of polling/marking on its own. Only falls back to the
   browser's own geolocation when GNSS is off.

Verified end to end with the GNSS simulator: enabling sidebar GNSS
recenters immediately and keeps following over several polls;
clicking Locate while GNSS is on jumps to the same position without
creating a second marker or touching its own active state; turning
GNSS back off and clicking Locate correctly falls through to the
browser geolocation path instead.
2026-09-08 00:56:25 +02:00
randy 87df90f75c Redesign UI as an OsmAnd-style sidebar, add live GNSS position via gpsd
Restructure the map controls from MapLibre corner buttons into a left
sidebar of icons with flyouts/panels (radar, GPX, GNSS), matching
OsmAnd's layout more closely:

- Base map and GPX selection are now full-height side panels docked
  next to the sidebar (not small dropdown flyouts or a right-docked
  panel), opening/closing exclusively via a small shared event bus
  (panels.js) so only one is ever open at a time.
- The GPX panel's upload/new-folder controls are now icon buttons in
  the header instead of an always-visible dropzone and form; dragging
  a GPX file onto the tree, a specific folder, or straight onto the
  map itself all upload it.
- New: Maptool::GpsdClient (lib/maptool/gpsd_client.rb) streams live
  GNSS fixes from a local gpsd daemon over Server-Sent Events
  (/api/gnss/stream) to a marker on the map (public/js/gnss.js) — one
  background gpsd connection shared by every browser tab.
- The online map style (public/js/osmand-style.js) is now styled to
  resemble OsmAnd's own rendering, applied to both the online and
  offline (PMTiles) styles.

Also adds a GeolocateControl (browser geolocation) next to the zoom
controls.
2026-08-25 19:39:13 +02:00