V3-04: live map on the recording screen

Feeds RideMap from watchPointsForTrip/watchSegmentsForTrip via autoDispose.family providers. RecordingEngine stays map-free (enforced by architecture_test.dart). RideMap gained lifecycle-aware tile teardown and follow-mode, both shared with the trip-detail map.
This commit is contained in:
2026-08-17 14:45:37 -05:00
parent 0267d0108c
commit f3c7e2d6b4
8 changed files with 239 additions and 13 deletions

View File

@@ -261,6 +261,15 @@ class AppDatabase extends _$AppDatabase {
return rows.map(_toSegment).toList();
}
/// Feeds the live map (V3-04): segment boundaries are what turn a pause into a visible
/// gap instead of a straight line drawn across the gap.
Stream<List<domain.Segment>> watchSegmentsForTrip(int tripId) =>
(select(segments)
..where((s) => s.tripId.equals(tripId))
..orderBy([(s) => OrderingTerm.asc(s.id)]))
.watch()
.map((rows) => rows.map(_toSegment).toList());
/// The segment currently being recorded into, if any.
Future<domain.Segment?> openSegment(int tripId) async {
final row =
@@ -343,6 +352,19 @@ class AppDatabase extends _$AppDatabase {
return rows.map(_toPoint).toList();
}
/// Feeds the live map (V3-04). Updates on each writer flush (~2 s), not per fix —
/// the stream is backed by the same table the batched writer flushes into, so there is
/// nothing extra to throttle.
Stream<List<domain.TrackPoint>> watchPointsForTrip(int tripId) =>
(select(trackPoints)
..where((p) => p.tripId.equals(tripId))
..orderBy([
(p) => OrderingTerm.asc(p.segmentId),
(p) => OrderingTerm.asc(p.id),
]))
.watch()
.map((rows) => rows.map(_toPoint).toList());
Future<List<domain.TrackPoint>> pointsForSegment(int segmentId) async {
final rows =
await (select(trackPoints)