Files
samplez/rippr-src/docs/v2/10-trips-list.md
uhryniuk 280fd7f988 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>
2026-08-11 08:30:25 -05:00

90 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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).