Add Rippr source snapshot and full-history bundle
Two copies for two jobs. rippr-src/ is a browsable git archive export of the tracked tree at 2f76983 - no build outputs, no local.properties, no nested .git - which is convenient to read in gitea but carries no history and will drift. rippr-full-history.bundle is the real backup: all 18 commits, verified as "records a complete history" and test-cloned before committing. This matters because ~/dojo/rippr has no git remote and otherwise exists only on one machine. rippr-src/SNAPSHOT.md explains the difference and how to restore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
89
rippr-src/docs/v2/10-trips-list.md
Normal file
89
rippr-src/docs/v2/10-trips-list.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# T10 — Trips list screen
|
||||
|
||||
**Phase** 4 · **Depends on** T02, T08 · **Status** Done
|
||||
|
||||
## Goal
|
||||
|
||||
A scrollable list of completed rides, each showing enough to identify it, tapping through
|
||||
to detail. Done when past rides are browsable and the list updates reactively as rides
|
||||
complete.
|
||||
|
||||
## Context
|
||||
|
||||
There is currently no way to see a past ride at all — v1 has one screen showing lifetime
|
||||
totals. This is the first place trips become visible as objects.
|
||||
|
||||
`TripDao.observeCompletedTrips()` from T02 provides the data, ordered `startedAt DESC`.
|
||||
All displayed values are already persisted on the `Trip` row by T07, so **this screen
|
||||
runs no computation** — no loading points, no statistics. That keeps it fast with
|
||||
hundreds of rides.
|
||||
|
||||
## Design
|
||||
|
||||
One row per trip:
|
||||
|
||||
```
|
||||
Sat 9 Aug · 14:32 47.2 km
|
||||
1h 12m moving · max 118 km/h ▸
|
||||
```
|
||||
|
||||
- Name if set, otherwise a date-derived label ("Sat 9 Aug · 14:32")
|
||||
- Distance as the right-aligned prominent figure
|
||||
- Moving time and max speed as the secondary line
|
||||
- Monospace with `tabular-nums` for the figures so columns align down the list
|
||||
|
||||
**Empty state** matters here — a new install has no trips, and an empty screen with no
|
||||
explanation reads as broken. Show a short line pointing at the Record tab.
|
||||
|
||||
**An in-progress trip is excluded** (`endedAt IS NULL`). A half-finished ride in the
|
||||
history list with a growing distance would be confusing; the Record screen owns that.
|
||||
|
||||
Grouping by month is tempting but premature. Revisit when there are enough rides to
|
||||
justify it.
|
||||
|
||||
## Implementation
|
||||
|
||||
1. `TripsViewModel` exposing `observeCompletedTrips()` as state.
|
||||
2. `LazyColumn` of `TripRow`.
|
||||
3. Date formatting via `java.time` with the device locale and zone — **not** hardcoded
|
||||
patterns. Ride timestamps come from `Location.time`, which is UTC epoch millis.
|
||||
4. Reuse `Telemetry.formatDuration`.
|
||||
5. Distance formatting helper — km with one decimal; metres below 1 km.
|
||||
6. Tap navigates to `trip/{tripId}`.
|
||||
7. Empty state.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [x] Completed trips listed newest first
|
||||
- [x] Active trip excluded
|
||||
- [x] Empty state shown on a fresh install
|
||||
- [x] Tap opens the right trip
|
||||
- [ ] List updates when a ride completes, without manual refresh
|
||||
- [x] No point-table reads — the screen uses only `Trip` rows
|
||||
|
||||
> **Not verified.** The unchecked items above, and the Compose UI tests below, were
|
||||
> not done. Verification for T08–T11 was manual on the emulator (screenshots through
|
||||
> the full flow) plus the existing unit and instrumented suites. Compose UI tests are
|
||||
> outstanding — tracked in T18.
|
||||
|
||||
## Tests
|
||||
|
||||
Compose UI tests:
|
||||
- Empty state on no data
|
||||
- Rows render in the right order
|
||||
- Tap emits the right navigation event
|
||||
- Active trip absent from the list
|
||||
|
||||
Instrumented DAO test for ordering and the `endedAt IS NULL` exclusion.
|
||||
|
||||
## Risks / gotchas
|
||||
|
||||
- **Timezone.** `Location.time` is UTC. Format in the device zone or a ride at 21:00
|
||||
local shows as tomorrow.
|
||||
- **Do not compute stats here.** If a value is missing from the `Trip` row, fix T07
|
||||
rather than loading points in the list — that path leads to a screen that janks after
|
||||
fifty rides.
|
||||
|
||||
## Out of scope
|
||||
|
||||
Rename/delete/merge (T12); detail content (T11).
|
||||
Reference in New Issue
Block a user