Compare commits
2 Commits
43bb7f4fa1
...
64f5dff30b
| Author | SHA1 | Date | |
|---|---|---|---|
| 64f5dff30b | |||
| 24bbeeffd3 |
2
RIPPR.md
2
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
|
`~/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.
|
bundle below is the only off-machine copy of its history.
|
||||||
|
|
||||||
**Snapshot taken at:** `46a0726` — "Document the whole project: README, architecture, v1 history, v3 backlog" (19 commits)
|
**Snapshot taken at:** `d418920` — "v3: add waypoint route planning; record that handlebar mounting changes the premise" (21 commits)
|
||||||
|
|
||||||
## What is here
|
## What is here
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -25,7 +25,7 @@ Kotlin 2.0.21 AGP 8.7.3 Gradle 8.11.1
|
|||||||
| Rename / delete / merge rides | Working |
|
| Rename / delete / merge rides | Working |
|
||||||
| GPX + GeoJSON export | Working, validated against an external parser |
|
| GPX + GeoJSON export | Working, validated against an external parser |
|
||||||
| Upload to a REST endpoint | Implemented, **no UI** — see below |
|
| 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 |
|
| Group ride view | Deferred to v3 |
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
@@ -79,11 +79,13 @@ polylines, and GPX `<trkseg>`.
|
|||||||
|
|
||||||
Full reasoning in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
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
|
**No live map while recording** — *superseded, see [docs/v3/BACKLOG.md](docs/v3/BACKLOG.md).*
|
||||||
map would burn battery on top of GPS and a wake lock for nothing. The map is a post-ride
|
v2 shipped without one because the phone rides in a pocket, so a live map would burn battery
|
||||||
artifact, gated behind a toggle, and `TrackingService` holds no reference to any map type.
|
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
|
**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
|
reachable via `Config.setUploadEndpoint()`. It has no server to talk to yet; the UI arrives
|
||||||
|
|||||||
@@ -64,19 +64,28 @@ brings hosting, privacy, and location-sharing consent into scope.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Live map — explicitly deferred, revisit deliberately
|
## 3. Live map on the recording screen — **decision reversed**
|
||||||
|
|
||||||
v2 has **no live map by design**, on Dylan's reasoning:
|
v2 deliberately shipped no live map, on the reasoning that the phone rides in a pocket.
|
||||||
|
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.
|
||||||
|
|
||||||
> "we hit start, put the phone in our pocket and then stop it after the ride. So having a
|
**The handlebar case changes the premise, not just the feature.** v1 and v2 were both built
|
||||||
> live map doesn't make sense at all honestly, we just wanna see the path render after."
|
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:
|
||||||
|
|
||||||
`TrackingService` holds no reference to any map type, and the map exists only inside the
|
- **Screen on for the whole ride** — battery goes from "a background service" to "a
|
||||||
detail screen's Compose lifecycle. That boundary is deliberate and worth preserving unless
|
service plus a lit screen plus continuous map rendering". Measure before committing.
|
||||||
there is a real reason to cross it.
|
- **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.
|
||||||
|
|
||||||
**Group riding is the one plausible reason** — seeing where the others are while stopped at
|
What still holds regardless:
|
||||||
a junction. If it happens, keep it screen-on-only and never let the service touch it.
|
|
||||||
|
- **`TrackingService` must never reference a map.** Rendering belongs to the Compose
|
||||||
|
lifecycle of a visible screen, not the service.
|
||||||
|
- **No tile fetch or redraw while backgrounded**, even in mounted mode.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -95,7 +104,48 @@ a junction. If it happens, keep it screen-on-only and never let the service touc
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Things that must not regress
|
## 5. Ideas
|
||||||
|
|
||||||
|
Terse on purpose. Unshaped, to be consolidated later.
|
||||||
|
|
||||||
|
- **Live map while recording.** More visually appealing than a numbers screen. Reverses the
|
||||||
|
v2 decision — see section 3 for the constraints that survive it.
|
||||||
|
- **Pick a real theme.** The current look is functional dark + safety orange, chosen to
|
||||||
|
match the icon. Decide on an actual visual identity and push the UI toward something
|
||||||
|
polished rather than merely clean.
|
||||||
|
- **User sign-up and accounts.** Register people, give their data somewhere to live.
|
||||||
|
Prerequisite for anything cloud-side, and pairs with the group-ride server in section 2.
|
||||||
|
- **Activity type per ride.** Motorcycle, bicycle, skateboard, running, other. The app is
|
||||||
|
not inherently motorcycle-only — the recording pipeline is activity-agnostic already.
|
||||||
|
Note: adds a column to `Trip`, so it needs a real `Migration` (the destructive fallback
|
||||||
|
is gone). Type could also drive sensible defaults — speed noise floor, map zoom,
|
||||||
|
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
|
||||||
|
|
||||||
|
Sign-up, cloud backup and group ride are one programme, not three: they all need a server,
|
||||||
|
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
|
||||||
|
|
||||||
Hard-won and easy to undo by accident. Each has a comment in the code explaining why.
|
Hard-won and easy to undo by accident. Each has a comment in the code explaining why.
|
||||||
|
|
||||||
@@ -116,7 +166,7 @@ Hard-won and easy to undo by accident. Each has a comment in the code explaining
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Reading order for picking this up cold
|
## 7. Reading order for picking this up cold
|
||||||
|
|
||||||
1. [../../README.md](../../README.md) — what the app is and its current state
|
1. [../../README.md](../../README.md) — what the app is and its current state
|
||||||
2. [../ARCHITECTURE.md](../ARCHITECTURE.md) — why it is built this way
|
2. [../ARCHITECTURE.md](../ARCHITECTURE.md) — why it is built this way
|
||||||
|
|||||||
Reference in New Issue
Block a user