autoconnect on fly mode (does not work yet)

This commit is contained in:
Constantin Leue
2026-08-02 08:25:23 +02:00
parent 5e9ef43f2f
commit 607dbb6584
13 changed files with 430 additions and 29 deletions
+91 -3
View File
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
@@ -5,8 +6,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../app_mode/app_mode_cubit.dart';
import '../../transport/connection_type.dart';
import '../../transport/link_transport.dart';
import '../dmc_colors.dart';
import '../providers/connection_settings_provider.dart';
import '../providers/flight_mode_provider.dart';
import '../providers/wifi_connection_provider.dart';
import 'flight_mode_pill.dart';
import 'fly_map_controls.dart';
import 'header_wind_pill.dart';
@@ -35,7 +40,7 @@ class TopModeBar extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isFly = context.select((AppModeCubit c) => c.state.mode == AppMode.fly);
final activeTint = isFly ? DmcColors.flyModeRed : DmcColors.editModeGreen;
final activeTint = isFly ? DmcColors.flyModeColor : DmcColors.planModeColor;
// Kein SafeArea: das wendet links/rechts die jeweils tatsaechlichen
// (oft asymmetrischen) Insets an, wodurch die Leiste sichtbar von der
@@ -72,7 +77,7 @@ class TopModeBar extends ConsumerWidget {
_ModeButton(
label: 'Plan',
isActive: !isFly,
inactiveColor: DmcColors.editModeGreen,
inactiveColor: DmcColors.planModeColor,
cornerRadius: const BorderRadius.only(
bottomLeft: Radius.circular(26),
),
@@ -82,6 +87,8 @@ class TopModeBar extends ConsumerWidget {
const SizedBox(width: 8),
const HeaderWindPill(),
const SizedBox(width: 8),
const _WifiConnectionProgressPill(),
const SizedBox(width: 8),
const Expanded(child: FlightModePill()),
const SizedBox(width: 8),
const FlyMapControls(),
@@ -96,7 +103,7 @@ class TopModeBar extends ConsumerWidget {
_ModeButton(
label: 'Fly',
isActive: isFly,
inactiveColor: DmcColors.flyModeRed,
inactiveColor: DmcColors.flyModeColor,
cornerRadius: const BorderRadius.only(
bottomRight: Radius.circular(26),
),
@@ -105,6 +112,7 @@ class TopModeBar extends ConsumerWidget {
// Eintritt in den Fly-Modus setzt immer auf Waypoint
// zurueck (Doku 3.11).
ref.read(flightModeProvider.notifier).reset();
_maybeAutoConnectWifi(ref);
},
),
],
@@ -115,6 +123,86 @@ class TopModeBar extends ConsumerWidget {
}
}
/// Verbindet automatisch zur mLRS-Bruecke, wenn in den Fly-Modus gewechselt
/// wird (Doku Kommunikationsschicht v2 Abschnitt 8: "Verbindung automatisch
/// herstellen bei Wechsel in Fly, wenn WLAN gemerkt"). Voraussetzungen:
/// Verbindungsart ist WLAN, "Auto-connect"-Einstellung ist an, und es gibt
/// bereits eine gemerkte SSID aus einer frueheren erfolgreichen Verbindung -
/// ohne gemerkte SSID muesste ohnehin der Systemdialog erscheinen, das ist
/// dann kein "automatisches" Verbinden mehr. Der Fortschritt ist ueber
/// [_WifiConnectionProgressPill] sichtbar.
Future<void> _maybeAutoConnectWifi(WidgetRef ref) async {
final settings = ref.read(connectionSettingsProvider).value;
if (settings == null) return;
if (settings.connectionType != ConnectionType.wifi) return;
if (!settings.connectionAutoConnect) return;
if (settings.connectionWifiLastSsid == null) return;
final transport = ref.read(wifiTransportProvider);
if (transport.currentState == LinkState.connected ||
transport.currentState == LinkState.connecting) {
return;
}
try {
await transport.connect();
} on LinkConnectException {
// Grund/Nachricht sind bereits ueber den State-Stream gemeldet, siehe
// _WifiConnectionProgressPill.
}
}
/// Kompakte Fortschrittsanzeige fuer den automatischen WLAN-Verbindungsaufbau
/// (siehe [_maybeAutoConnectWifi]) - nur sichtbar, solange die Verbindungsart
/// WLAN ist und gerade etwas passiert bzw. ein Fehler vorliegt. Bleibt im
/// Ruhezustand (disconnected, kein vorheriger Fehler) unsichtbar, damit die
/// Kopfleiste nicht dauerhaft mit einer Statuspille zugestellt ist.
class _WifiConnectionProgressPill extends ConsumerWidget {
const _WifiConnectionProgressPill();
@override
Widget build(BuildContext context, WidgetRef ref) {
final connectionType = ref.watch(connectionSettingsProvider).value?.connectionType;
final linkState = ref.watch(wifiLinkStateProvider).value;
if (connectionType != ConnectionType.wifi) return const SizedBox.shrink();
if (linkState == null || linkState == LinkState.disconnected) {
return const SizedBox.shrink();
}
final (label, color) = switch (linkState) {
LinkState.connecting => ('Connecting…', DmcColors.pafAmber),
LinkState.connected => ('WiFi connected', DmcColors.liveGreen),
LinkState.error => ('WiFi error', DmcColors.warnRed),
LinkState.disconnected => ('', Colors.grey),
};
return Padding(
padding: const EdgeInsets.only(right: 8),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (linkState == LinkState.connecting) ...[
SizedBox(
width: 10,
height: 10,
child: CircularProgressIndicator(strokeWidth: 1.5, color: color),
),
const SizedBox(width: 6),
],
Text(label, style: TextStyle(color: color, fontSize: 11)),
],
),
),
);
}
}
class _ModeButton extends StatelessWidget {
const _ModeButton({
required this.label,