T19/T21: map and export, completing Phase 4

flutter_map with the same OSM tiles and no-API-key reasoning that chose osmdroid.
All four load-bearing behaviours ported and, unlike the native app's map, tested:
one polyline per segment so a pause is a real gap, render-only decimation, the
zoom clamp at OSM's max tile zoom with a short-ride fallback, and a real user
agent. Speed colouring is bucketed per run rather than per-vertex, since neither
osmdroid nor flutter_map makes per-vertex paint reasonable.

Export via share_plus, which also handles the iPad popover anchor a naive port
forgets. It passes the raw stored points, never the map's decimated path.

164 tests passing, analyze clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 16:27:42 -05:00
parent bcc12b314f
commit d501528e69
20 changed files with 1085 additions and 478 deletions

View File

@@ -31,9 +31,9 @@ class _RipprAppState extends ConsumerState<RipprApp> {
@override
Widget build(BuildContext context) => MaterialApp.router(
title: 'Rippr',
debugShowCheckedModeBanner: false,
theme: ripprTheme(),
routerConfig: _router,
);
title: 'Rippr',
debugShowCheckedModeBanner: false,
theme: ripprTheme(),
routerConfig: _router,
);
}