diff --git a/app/lib/ui/providers/map_controller_provider.dart b/app/lib/ui/providers/map_controller_provider.dart index 858320d..8f2a9b5 100644 --- a/app/lib/ui/providers/map_controller_provider.dart +++ b/app/lib/ui/providers/map_controller_provider.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:latlong2/latlong.dart'; import '../../domain/waypoint/flat_waypoint_list.dart'; +import 'follow_drone_provider.dart'; /// Ein einziger, app-lebenslanger MapController statt einer pro /// PlanScreen-Mount neu erzeugten Instanz. @@ -54,5 +55,16 @@ void fitMapControllerToWaypoints(MapController controller, List waypoi /// ConsumerStatefulWidget mit [WidgetRef]) - geteilt zwischen dem manuellen /// Fit-Button (MapSearchControls/FlyMapControls) und den map-bezogenen /// Warnungs-Aktionen (Doku 3.10). -void fitMapToWaypoints(WidgetRef ref, List waypoints) => - fitMapControllerToWaypoints(ref.read(mapControllerProvider), waypoints); +/// +/// Beendet dabei immer auch den Kartenfolgemodus (followDroneProvider, +/// Doku 3.11) - dieser Fit bewegt die Kamera ueber denselben MapController +/// wie die Telemetrie-Nachfuehrung (source == mapController), FlyScreens +/// Abbruch bei manueller Karteninteraktion greift hier also nicht. Ohne +/// diesen expliziten Abbruch wuerde der naechste Telemetrie-Frame die +/// Kamera sofort wieder von der gerade eingestellten Uebersicht weg auf die +/// Drohne zurueckziehen. In Plan-Modus/Mock-Kontexten ohne aktiven +/// Folgemodus ist der Aufruf ein no-op. +void fitMapToWaypoints(WidgetRef ref, List waypoints) { + ref.read(followDroneProvider.notifier).set(false); + fitMapControllerToWaypoints(ref.read(mapControllerProvider), waypoints); +} diff --git a/app/lib/ui/providers/mission_meta_provider.dart b/app/lib/ui/providers/mission_meta_provider.dart index 2a82851..157f44d 100644 --- a/app/lib/ui/providers/mission_meta_provider.dart +++ b/app/lib/ui/providers/mission_meta_provider.dart @@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/waypoint/flat_waypoint_list.dart'; import 'current_mission_provider.dart'; import 'database_provider.dart'; +import 'follow_drone_provider.dart'; import 'map_controller_provider.dart'; /// Metadaten der aktuell in Bearbeitung befindlichen Mission - ergaenzt @@ -100,7 +101,13 @@ class CurrentMissionMetaNotifier extends Notifier { /// nutzt dieselbe Padding-Logik wie der manuelle Fit-Button /// (fitMapControllerToWaypoints), damit beide nicht wieder auseinander- /// laufen koennen. + /// + /// Beendet dabei ebenfalls den Kartenfolgemodus (followDroneProvider, + /// Doku 3.11, siehe fitMapToWaypoints in map_controller_provider.dart) - + /// das Laden einer anderen Mission waehrend des Verfolgens soll auf der + /// neuen Mission stehen bleiben, nicht sofort wieder zur Drohne springen. void _fitMapToWaypoints(List waypoints) { + ref.read(followDroneProvider.notifier).set(false); fitMapControllerToWaypoints(ref.read(mapControllerProvider), waypoints); } diff --git a/app/lib/ui/screens/fly/fly_screen.dart b/app/lib/ui/screens/fly/fly_screen.dart index 21c2b37..a2e4f1a 100644 --- a/app/lib/ui/screens/fly/fly_screen.dart +++ b/app/lib/ui/screens/fly/fly_screen.dart @@ -71,6 +71,11 @@ class _FlyScreenState extends ConsumerState { final waypoints = ref.read(currentMissionProvider); if (index < 0 || index >= waypoints.length) return; final wp = waypoints[index]; + // Programmatischer Sprung (source == mapController) - _onMapEvent + // erkennt das nicht als manuelle Geste, der Folgemodus muss also + // explizit beendet werden (sonst zieht der naechste Telemetrie-Frame + // die Kamera sofort wieder vom antippten Wegpunkt weg). + ref.read(followDroneProvider.notifier).set(false); _mapController.move(LatLng(wp.lat, wp.lon), _mapController.camera.zoom); } diff --git a/app/lib/ui/widgets/fly_map_controls.dart b/app/lib/ui/widgets/fly_map_controls.dart index 8ee70d9..82e14bd 100644 --- a/app/lib/ui/widgets/fly_map_controls.dart +++ b/app/lib/ui/widgets/fly_map_controls.dart @@ -43,14 +43,6 @@ class FlyMapControls extends ConsumerWidget { ref.read(followDroneProvider.notifier).set(true); } - /// Beendet den Folgemodus explizit, statt sich auf den Abbruch bei - /// manueller Karteninteraktion in FlyScreen zu verlassen (FlyScreen._ - /// onMapEvent) - fitMapToWaypoints() bewegt die Kamera ueber denselben - /// MapController (source == mapController), gilt dort also nicht als - /// manuelle Geste und wuerde den Folgemodus sonst aktiv lassen. Ohne - /// diesen Abbruch wuerde der naechste Telemetrie-Frame die Kamera sofort - /// wieder von der gerade eingestellten Missionsuebersicht weg auf die - /// Drohne zurueckziehen. void _onFitPressed(BuildContext context, WidgetRef ref) { final waypoints = ref.read(currentMissionProvider); if (waypoints.isEmpty) { @@ -58,7 +50,8 @@ class FlyMapControls extends ConsumerWidget { .showSnackBar(const SnackBar(content: Text('No waypoints to fit'))); return; } - ref.read(followDroneProvider.notifier).set(false); + // Beendet den Folgemodus mit (siehe fitMapToWaypoints-Doku in + // map_controller_provider.dart). fitMapToWaypoints(ref, waypoints); }