Files
dmc/app/lib/ui/providers/system_message_log_provider.dart
T
Constantin LeueandClaude Sonnet 5 b09d00ab9f Rename the Fly-mode Warnings tab to System Messages, log connection/upload events
Renames DroneEvent/DroneEventSeverity/droneEventLogProvider/
DroneStatusWarningsPanel to SystemMessage/SystemMessageSeverity/
systemMessageLogProvider/DroneStatusMessagesPanel throughout, matching
what the tab now actually shows - general system messages, not just
drone-health warnings.

Adds a new SystemMessageSeverity.info level (blue) for messages that
aren't a warning/error, and three new message sources on top of the
existing battery/failsafe detection:
- "Connected", logged the first time telemetryProvider produces a frame
  after having none - the mirror image of the existing "Connection lost"
  detection (which already fires on the first stream error after having
  had data), so no new transport-specific dependency was needed.
- "Connection type changed to X", from watching connectionSettingsProvider
  (skips the initial load so it doesn't fire on every app start).
- "Mission sent (N waypoints)" / "Mission upload failed: ...", logged
  from FlyScreen's send handler via a new public log() method on the
  notifier, alongside the existing snackbar.

Verified on the Pixel_10a emulator: entering Fly mode logs "Connected"
once the mock telemetry starts, and tapping the send button logs
"Mission sent (3 waypoints)" right after the snackbar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 10:47:38 +02:00

111 lines
4.2 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../domain/telemetry/system_message.dart';
import '../../transport/connection_type.dart';
import '../../transport/flight_controller_link.dart';
import 'connection_settings_provider.dart';
import 'telemetry_provider.dart';
/// Fuehrt das System-Messages-Log fuer den gleichnamigen Tab im
/// Drohnen-Status-Menue (Doku: "aendere das warnings Menü in System
/// Messages ... Verbindung hergestellt/verloren, Verbindungstyp geaendert,
/// Wegpunkte uebertragen") - beobachtet [telemetryProvider] und
/// [connectionSettingsProvider] dauerhaft (bewusst KEIN autoDispose, siehe
/// telemetry_provider.dart-Doku zur analogen Begruendung bei
/// flightControllerLinkProvider), damit ein Ereignis auch dann protokolliert
/// wird, wenn die System-Messages-Ansicht selbst gerade nicht geoeffnet ist.
/// Beginnt zu beobachten, sobald irgendein Widget diesen Provider erstmals
/// liest (siehe FlyScreen) - vor diesem Zeitpunkt liegende Ereignisse
/// erscheinen nicht im Log, das ist fuer ein Live-Log erwartbar.
class SystemMessageLogNotifier extends Notifier<List<SystemMessage>> {
TelemetryFrame? _previousFrame;
bool _hadData = false;
@override
List<SystemMessage> build() {
ref.listen<AsyncValue<TelemetryFrame>>(telemetryProvider, (previous, next) {
next.when(
data: (frame) {
// Flankengetriggert wie "Connection lost" unten, nur umgekehrt -
// anders als dort ist hier kein Sonderfall fuer die allererste
// Verbindung noetig: der Uebergang "noch keine Daten" -> "erste
// Daten" ist immer ein echtes "Connected", auch beim allerersten
// Mal.
if (!_hadData) {
_log('Connected', SystemMessageSeverity.info);
}
final events = detectSystemMessages(
previous: _previousFrame,
current: frame,
now: DateTime.now(),
);
_previousFrame = frame;
_hadData = true;
if (events.isNotEmpty) {
state = [...events.reversed, ...state];
}
},
error: (error, stackTrace) {
// Nur melden, wenn zuvor bereits Frames flossen - sonst wuerde
// schon das (normale) Ausbleiben der allerersten Verbindung als
// "Connection lost" auftauchen.
if (_hadData) {
_log('Connection lost', SystemMessageSeverity.critical);
}
_previousFrame = null;
_hadData = false;
},
loading: () {},
);
});
// Verbindungsart-Wechsel (Doku: "Verbindungstyp geaendert") - nur ab dem
// zweiten geladenen Wert protokollieren, sonst wuerde bereits das
// erstmalige Laden der Einstellungen aus der DB als "Wechsel" erscheinen.
ConnectionType? previousType;
var sawFirstLoad = false;
ref.listen(connectionSettingsProvider, (previous, next) {
final type = next.value?.connectionType;
if (type == null) return;
if (!sawFirstLoad) {
sawFirstLoad = true;
previousType = type;
return;
}
if (type != previousType) {
_log('Connection type changed to ${_connectionTypeLabel(type)}',
SystemMessageSeverity.info);
previousType = type;
}
});
return [];
}
String _connectionTypeLabel(ConnectionType type) => switch (type) {
ConnectionType.wifi => 'WiFi mLRS UDP',
ConnectionType.mock => 'Mock (Test)',
};
/// Fuegt einen Eintrag manuell hinzu (Doku: "Wegpunkte uebertragen") - fuer
/// Ereignisse, die nicht aus der Telemetrie/den Einstellungen ableitbar
/// sind, sondern vom Aufloeser einer konkreten Aktion (z.B. FlyScreen nach
/// einem Missions-Upload) gemeldet werden.
void log(String message, {SystemMessageSeverity severity = SystemMessageSeverity.info}) {
_log(message, severity);
}
void _log(String message, SystemMessageSeverity severity) {
state = [
SystemMessage(timestamp: DateTime.now(), message: message, severity: severity),
...state,
];
}
void clear() => state = [];
}
final systemMessageLogProvider =
NotifierProvider<SystemMessageLogNotifier, List<SystemMessage>>(
SystemMessageLogNotifier.new);