disabled auto connect when switching to fly mode and no disconnect when leavin fly mode, race condition fix for connectionType ( now telemetry not working anymore), UI optimizations: centered speed and alt, zoom to mission uses full screen

This commit is contained in:
Constantin Leue
2026-08-02 21:45:46 +02:00
parent 35c4129eb7
commit 0649ae4507
7 changed files with 94 additions and 66 deletions
+44 -16
View File
@@ -2,6 +2,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../transport/connection_type.dart';
import '../../transport/flight_controller_link.dart';
import '../../transport/link_transport.dart';
import '../../transport/mock/mock_flight_controller_link.dart';
import '../../transport/msp/msp_flight_controller_link.dart';
import 'connection_settings_provider.dart';
@@ -15,20 +16,29 @@ import 'wifi_connection_provider.dart';
/// (Doku Kommunikationsschicht v2, Abschnitt 1), 5G/USB sind noch nicht
/// umgesetzt.
///
/// connectionType wird bewusst per ref.read() einmalig beim Eintritt in den
/// Fly-Modus gelesen, nicht reaktiv beobachtet - sonst wuerde jede
/// Einstellungsaenderung waehrend des Flugs (z.B. Tippen im
/// SSID-Praefix-Feld, das ueberall im Settings-Screen ein
/// `ref.invalidate(connectionSettingsProvider)` ausloest) einen Neuaufbau
/// dieses Providers samt Trennen/Neuverbinden des Transports ausloesen.
/// connectionType wird reaktiv beobachtet (ref.watch), nicht nur einmalig
/// gelesen - beim ersten App-Start ist connectionSettingsProvider oft noch
/// nicht aus der DB geladen (AsyncLoading, value == null), was ohne Watch
/// dauerhaft auf den Mock-Fallback festgenagelt haette (siehe unten, "nicht
/// autoDispose"): sobald die Einstellungen nachladen oder der Nutzer die
/// Verbindungsart in den Settings aendert, baut dieser Provider sich korrekt
/// neu auf (alter Link wird dabei via ref.onDispose sauber getrennt). Das
/// ist inzwischen unkritisch haeufig, da die fruehere Sorge (Tippen im
/// SSID-Praefix-Feld loest bei jedem Zeichen einen Neuaufbau aus) entfaellt,
/// seit dieses Feld aus den Settings entfernt wurde (Preset "WiFi mLRS UDP").
///
/// autoDispose: verbindet erst, wenn der Fly-Screen tatsaechlich beobachtet
/// wird, und trennt sich wieder (Doku Abschnitt 8: "Verlassen des
/// Fly-Modus gibt den Netz-Request frei"), sobald niemand mehr zuhoert
/// (z.B. Rueckkehr in den Plan-Modus) statt endlos im Hintergrund
/// weiterzulaufen.
final flightControllerLinkProvider = Provider.autoDispose<FlightControllerLink>((ref) {
final connectionType = ref.read(connectionSettingsProvider).value?.connectionType;
/// Bewusst NICHT autoDispose (Doku: "beim Wechsel in Plan kein disconnect
/// triggern, Verbindung aktiv halten") - anders als frueher trennt ein
/// Wechsel zurueck in den Plan-Modus (der telemetryProvider nicht mehr
/// beobachtet) die Verbindung nicht mehr automatisch. Sie bleibt bis zum
/// expliziten "Disconnect" in den Settings, einer Aenderung der
/// Verbindungsart oder Schliessen der App bestehen.
/// [MspFlightControllerLink.connect]/[MockFlightControllerLink.connect]
/// sind deshalb idempotent: jeder erneute Watch von [telemetryProvider]
/// (z.B. erneuter Eintritt in den Fly-Modus) ruft `connect()` erneut auf,
/// darf aber keinen zweiten MSP-Client/-Poller nebenher starten.
final flightControllerLinkProvider = Provider<FlightControllerLink>((ref) {
final connectionType = ref.watch(connectionSettingsProvider).value?.connectionType;
final FlightControllerLink link = connectionType == ConnectionType.wifi
? MspFlightControllerLink(transport: ref.watch(wifiTransportProvider))
: MockFlightControllerLink();
@@ -36,11 +46,29 @@ final flightControllerLinkProvider = Provider.autoDispose<FlightControllerLink>(
return link;
});
/// Live-Telemetrie des verbundenen Flightcontrollers (Doku 3.4). connect()
/// wird beim ersten Abonnenten ausgeloest - MockFlightControllerLink
/// verlangt das vor subscribeTelemetry().
/// Live-Telemetrie des verbundenen Flightcontrollers (Doku 3.4). Bleibt
/// selbst autoDispose: nur die Frame-Weiterleitung an gerade aktive Watcher
/// endet beim Verlassen, nicht die zugrundeliegende Verbindung (siehe
/// [flightControllerLinkProvider]).
///
/// Ruft bei WLAN/MSP bewusst NICHT einfach `link.connect()` auf, sobald
/// irgendwer (z.B. FlyScreen beim Eintritt in den Fly-Modus) diesen Provider
/// beobachtet (Doku: "kein connect beim Wechsel in den Fly-Modus, um das
/// Debuggen auf echter Hardware zu vereinfachen") - `MspFlightControllerLink.
/// connect()` wuerde sonst ueber `transport.connect()` sofort einen
/// WifiNetworkSpecifier-Systemdialog ausloesen, unabhaengig vom entfernten
/// Auto-Connect-Trigger in TopModeBar. Stattdessen wird erst aktiv, sobald
/// die rohe WLAN-Verbindung bereits ueber den expliziten "Connect"-Knopf in
/// den Settings steht - bis dahin bleibt der Stream leer (kein Frame,
/// FlyScreen zeigt den Fallback-Marker auf dem ersten Wegpunkt). Fuer
/// Mock/Bluetooth/5G/USB gilt diese Einschraenkung nicht, dort ist
/// "verbinden" ohnehin folgenlos bzw. noch nicht umgesetzt.
final telemetryProvider = StreamProvider.autoDispose<TelemetryFrame>((ref) async* {
final link = ref.watch(flightControllerLinkProvider);
if (link is MspFlightControllerLink &&
ref.watch(wifiLinkStateProvider).value != LinkState.connected) {
return;
}
await link.connect();
yield* link.subscribeTelemetry();
});