Commit Graph
12 Commits
Author SHA1 Message Date
randy 0ee98d8f07 Summarize LiveTrack sessions and prune stale ones
CI / check (push) Successful in 48s
CI / deploy (push) Successful in 23s
Fetching a session's track now also grabs its summary (name, activity
type, distance, duration) from the same page and stores it — sessions
the panel has actually shown replace their raw UUID with that summary,
and are kept indefinitely regardless of age. A session nobody ever
opened (no summary) is more likely test/dead data than something worth
keeping, so it's dropped automatically after 48h.
2026-09-06 22:18:25 +02:00
randy f4b5237f01 Render a session's track on the map
CI / check (push) Successful in 47s
CI / deploy (push) Successful in 19s
Clicking a LiveTrack session now fetches and draws its track (line +
latest position). Garmin's own API 403s any plain server-side request
(Cloudflare bot protection), so LiveTrackClient fetches the session
page instead and pulls the track out of the server-rendered data
embedded in it. The webhook now captures the session's token too,
since the id alone isn't enough to fetch anything.
2026-09-06 22:07:13 +02:00
randy f9ddf860ea Add Garmin LiveTrack session tracking
CI / check (push) Successful in 6m49s
CI / deploy (push) Successful in 23s
A Gmail-watching Apps Script (documented in docs/deployment.adoc) posts
the session ID from each LiveTrack email to a new webhook, which stores
it in data/livetrack.json; a new sidebar panel lists what's been
received.
2026-09-06 21:05:35 +02:00
randy e13d1a1e97 Require Gitea login to write GPX data; IPv6-capable bind
CI / check (push) Successful in 6m28s
CI / deploy (push) Successful in 13s
Upload/delete/move/create-folder now require logging in via Gitea
OAuth2 (only MAPTOOL_ALLOWED_GITEA_USER is granted write access);
reading stays public. Deploy secrets (session secret, OAuth2 client
credentials, allowed user) are written to .env from Gitea Actions
repo secrets on every deploy instead of living on the server by hand.

Also switch the container's bind address to "[::]" (dual-stack) so
the app is reachable over IPv6, not just IPv4.
2026-08-27 18:02:37 +02:00
randy 0887ccbfe7 Drop the OsmAnd-recolor map theme, add offline labels and a lighter palette nudge
Remove osmand-style.js (the per-layer color-patching approach) and its
docs entirely — back to the plain OpenFreeMap "liberty" style online,
and protomaps-themes-base's stock theme offline as the base.

Offline maps previously had no text labels at all: the
protomaps-themes-base layers() call never passed a lang option, which
is required to include its label layers. Fixed, backed by vendored
Noto Sans Regular/Italic/Medium glyph PBFs (ranges 0-255 and 256-511
only — Basic Latin + Latin-1 Supplement + Latin Extended-A, enough for
accented Central European place names; other scripts won't render
offline). Verified against the actual offline.pmtiles vector layer
schema that the name/name:en/script fields this expects are present.

Also nudge a handful of OFFLINE_THEME color roles (background, water,
wood, buildings, the two road-importance tiers) towards the online
style's actual palette (sampled from its style JSON) so switching
Online/Offline doesn't look like two different apps — deliberately
partial, not the removed full recolor.
2026-08-25 22:38:56 +02:00
randy 06ea8ea141 Add file-kind icons to the GPX tree, fix drop into an empty panel
Each tree entry now shows a small waypoint/track icon based on a
cheap substring check for <wpt>/<trk> (Maptool::Gpx.kinds) rather than
a full REXML parse, since re-parsing a several-thousand-waypoint file
on every tree fetch would make the panel noticeably slower to open.

Also fix a real drop-target bug: .gpx-tree had no flex:1, so a
short/empty tree left blank panel space below it that wasn't part of
the drag & drop target — dropping a file there silently did nothing.
2026-08-25 22:38:41 +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
randy 008e034932 Add geolocate control to the map
Lets the user center the map on their current location, with an
accuracy circle and continuous tracking.
2026-08-25 15:18:55 +02:00
randy d813dd0b20 Add GPX drag & drop, folder management, delete, and folder-first sort
Uploading is now drag & drop (or click to browse) instead of a form;
folders can be created any time, not just during upload; files can be
dragged onto a folder to move them, or dropped elsewhere in the tree
to move back to the top level; files and folders can be deleted. Both
drag sources (an OS file drag and dragging an existing tree entry)
land on the same drop targets, told apart by a custom drag payload
type versus the browser's own "Files" type.

Also sort folders before files in the tree (previously interleaved
alphabetically).
2026-08-25 15:14:09 +02:00
randy 4e0d2abbd0 Add GPX upload with hierarchical folders and map display
Upload GPX files into a folder hierarchy (traversal-safe path
resolution against the store root), browse them in a tree panel, and
toggle each one's waypoints/tracks on the map. Waypoints render as
clickable points showing name, description and time; bare URLs in the
description are turned into safe links. GPX layers survive switching
between the Online/Offline base map, same as the radar overlay.

Adds rexml as an explicit dependency — it moved to a bundled gem in
this Ruby version and isn't picked up by Bundler otherwise.
2026-08-25 14:05:39 +02:00
randy 5afb130c45 Switch to vector maps (MapLibre GL JS + PMTiles) and add RainViewer radar
Replace Leaflet/raster tiles with MapLibre GL JS: an online OpenFreeMap
style and an offline style built from a local PMTiles archive via
pmtiles.js and protomaps-themes-base (no glyphs/labels offline by
design, see docs/architecture.adoc). Frontend libraries are vendored
locally rather than loaded from a CDN so the app keeps working with no
internet access.

Also add an animated RainViewer precipitation radar overlay (toggle,
play/pause, scrub slider), matching the default time window of the
weather-radar-card Home Assistant integration.
2026-08-25 01:18:36 +02:00
randy 7329497e95 Initial scaffold: Sinatra map app with Tauri desktop shell
Sinatra backend serving a basic Leaflet map, wrapped in a Tauri
desktop shell that starts the same server in a native window.
2026-08-24 22:57:03 +02:00