From 64f5dff30b0b90520a923b097271cbd5b992b39a Mon Sep 17 00:00:00 2001 From: uhryniuk Date: Tue, 11 Aug 2026 12:09:35 -0500 Subject: [PATCH] Refresh Rippr snapshot: waypointing and handlebar-mount notes Re-exported at d418920. Co-Authored-By: Claude Opus 5 --- RIPPR.md | 2 +- rippr-full-history.bundle | Bin 511930 -> 502767 bytes rippr-src/README.md | 12 +++++++----- rippr-src/docs/v3/BACKLOG.md | 32 ++++++++++++++++++++++++++++---- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/RIPPR.md b/RIPPR.md index d9c6147..ad2bd47 100644 --- a/RIPPR.md +++ b/RIPPR.md @@ -4,7 +4,7 @@ Rippr is a native Android GPS ride recorder for motorcycles. Its canonical repo `~/dojo/rippr`, which **has no git remote** — it exists only on that machine, so the bundle below is the only off-machine copy of its history. -**Snapshot taken at:** `957392f` — "v3: add Ideas section, reverse the no-live-map decision" (20 commits) +**Snapshot taken at:** `d418920` — "v3: add waypoint route planning; record that handlebar mounting changes the premise" (21 commits) ## What is here diff --git a/rippr-full-history.bundle b/rippr-full-history.bundle index ea73d73a8954ec0143916eee3d5f13336c1b53da..2112fd0a19aea6c4b744b0cde3505c36f028e3ee 100644 GIT binary patch delta 11257 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 diff --git a/rippr-src/README.md b/rippr-src/README.md index 7f5e088..bd49dfd 100644 --- a/rippr-src/README.md +++ b/rippr-src/README.md @@ -25,7 +25,7 @@ Kotlin 2.0.21 AGP 8.7.3 Gradle 8.11.1 | Rename / delete / merge rides | Working | | GPX + GeoJSON export | Working, validated against an external parser | | Upload to a REST endpoint | Implemented, **no UI** — see below | -| Live map during recording | Deliberately absent — see below | +| Live map during recording | Absent in v2; planned for v3 | | Group ride view | Deferred to v3 | ## Quick start @@ -79,11 +79,13 @@ polylines, and GPX ``. Full reasoning in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). -## Two deliberate absences +## Deliberate absences -**No live map while recording.** The phone is in a pocket; nobody is looking at it. A live -map would burn battery on top of GPS and a wake lock for nothing. The map is a post-ride -artifact, gated behind a toggle, and `TrackingService` holds no reference to any map type. +**No live map while recording** — *superseded, see [docs/v3/BACKLOG.md](docs/v3/BACKLOG.md).* +v2 shipped without one because the phone rides in a pocket, so a live map would burn battery +for something nobody is looking at. That premise no longer holds: handlebar mounting is now +a wanted use case. The constraint that survives is architectural — `TrackingService` holds +no reference to any map type, and rendering belongs to a visible screen's Compose lifecycle. **No UI for the upload endpoint.** The REST uploader works and is tested, but is only reachable via `Config.setUploadEndpoint()`. It has no server to talk to yet; the UI arrives diff --git a/rippr-src/docs/v3/BACKLOG.md b/rippr-src/docs/v3/BACKLOG.md index 2db2a05..79c882a 100644 --- a/rippr-src/docs/v3/BACKLOG.md +++ b/rippr-src/docs/v3/BACKLOG.md @@ -67,14 +67,25 @@ brings hosting, privacy, and location-sharing consent into scope. ## 3. Live map on the recording screen — **decision reversed** v2 deliberately shipped no live map, on the reasoning that the phone rides in a pocket. -Dylan has since asked for one anyway, for visual appeal. Treat the v2 stance as superseded. +Dylan has since asked for one — for visual appeal, and because **people may mount the phone +on the handlebars** to watch the route live. Treat the v2 stance as superseded. -What still holds and should not be given up: +**The handlebar case changes the premise, not just the feature.** v1 and v2 were both built +around "start it, pocket it, stop it". A mounted phone is a different product with different +constraints, and it is worth deciding explicitly whether that becomes a first-class mode: + +- **Screen on for the whole ride** — battery goes from "a background service" to "a + service plus a lit screen plus continuous map rendering". Measure before committing. +- **Sunlight legibility** — the current dark theme is chosen for glanceability, but daylight + behind a visor is a different problem. +- **Glove-sized targets** — already partly handled (72dp buttons); a map needs the same care. +- **Keep-screen-awake** handling, and what happens on a call or notification. + +What still holds regardless: - **`TrackingService` must never reference a map.** Rendering belongs to the Compose lifecycle of a visible screen, not the service. -- **Screen-on only.** No tile fetch or redraw while backgrounded. -- Battery cost sits on top of GPS and a wake lock — worth measuring before and after. +- **No tile fetch or redraw while backgrounded**, even in mounted mode. --- @@ -111,6 +122,14 @@ Terse on purpose. Unshaped, to be consolidated later. elevation smoothing. - **Paid cloud backup.** Ongoing storage of rides over time. Needs accounts first, plus a decision on hosting, pricing, and what happens to data when someone stops paying. +- **Waypoint route planning.** Drop a series of pins on the map to "draw" a route, get + distance and estimates back, and save it to ride later. This is *pre*-ride planning — + a genuinely new mode alongside recording, not an extension of it. Needs its own entity + (`Route` + `Waypoint`), separate from `Trip`, since a plan is not a recording. + Straight-line pin-to-pin distance is easy and reuses `Geo.haversineMeters`; snapping to + actual roads needs a routing service (OSRM, GraphHopper, Valhalla — self-hostable) and is + a much larger step. Natural follow-ons: follow a planned route on the live map, and + compare a recorded ride against the plan afterwards. ### Threads running through these @@ -119,6 +138,11 @@ identity, and a privacy stance. Worth scoping together rather than separately. Activity type and theming are independent and much cheaper — either could ship alone. +Live map, handlebar mounting and waypoint following also cluster: all three assume a +visible screen during the ride, and all three want the same map component. Route planning +is the odd one out — it needs no ride in progress at all and could be built entirely +standalone. + --- ## 6. Things that must not regress