V3-07: route drawing (pins and straight lines)

Route plans are their own entity (RoutePlan/Waypoint, schema v3), never joined into ride totals or the rides list. RoutePlanRepository recomputes straight-line distance after every waypoint mutation. RoutePlannerScreen supports tap-to-add, tap-to-delete, and hand-rolled drag-to-move via MapCamera's screen/latlng conversions.

Fixed a real bug found by testing: FlutterMap's initialCenter/initialZoom are read once at construction, so building the map before the waypoints stream's first emission froze the camera on null-island. Also documents a genuine ten-minute test hang traced to Stream.first on a Drift watch() query inside testWidgets, which needs a pump-driven Timer that flutter_test's fake zone never advances on its own.
This commit is contained in:
2026-08-17 19:15:18 -05:00
parent 5013b7002f
commit a14f5b0134
15 changed files with 2694 additions and 5 deletions

View File

@@ -14,6 +14,7 @@ import '../config/config.dart';
import '../data/database.dart';
import '../data/trip_repository.dart';
import '../domain/models.dart';
import '../data/route_plan_repository.dart';
import '../notification/ride_notification_controller.dart';
import '../notification/ride_notification_coordinator.dart';
import '../recording/geolocator_location_source.dart';
@@ -153,3 +154,21 @@ final livePointsProvider = StreamProvider.autoDispose.family<List<TrackPoint>, i
final liveSegmentsProvider = StreamProvider.autoDispose.family<List<Segment>, int>(
(ref, tripId) => ref.watch(databaseProvider).watchSegmentsForTrip(tripId),
);
// --- Route plans (V3-07) -----------------------------------------------------
final routePlanRepositoryProvider = Provider<RoutePlanRepository>(
(ref) => RoutePlanRepository(ref.watch(databaseProvider)),
);
final routePlansProvider = StreamProvider<List<RoutePlan>>(
(ref) => ref.watch(routePlanRepositoryProvider).watchRoutePlans(),
);
final routePlanProvider = StreamProvider.autoDispose.family<RoutePlan?, int>(
(ref, id) => ref.watch(routePlanRepositoryProvider).watchRoutePlan(id),
);
final routeWaypointsProvider = StreamProvider.autoDispose.family<List<Waypoint>, int>(
(ref, routeId) => ref.watch(routePlanRepositoryProvider).watchWaypoints(routeId),
);