import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/mission/mission_stats.dart'; import '../../domain/mission/mission_warnings.dart'; import '../../domain/telemetry/drone_status.dart'; import '../../domain/waypoint/flat_waypoint_list.dart'; import '../providers/altitude_profile_provider.dart'; import 'battery_indicator_bar.dart'; import 'bottom_stats_bar.dart'; import 'mini_altitude_profile.dart'; /// Gemeinsamer Fusszeilen-Aufbau (Warnungsbanner + Hoehenprofil + /// BottomStatsBar), geteilt zwischen Plan- und Fly-Modus (Doku 3.9/3.10) - /// beide zeigen dieselbe Missionsuebersicht, nur Reticle/Draeder gibt es /// ausschliesslich im Plan-Modus. class MissionFooterBar extends ConsumerWidget { const MissionFooterBar({ super.key, required this.waypoints, required this.legClimbBad, required this.vertexBad, required this.activeIndex, required this.totalDistanceM, required this.totalDurationSec, this.flyMissionStatus, this.droneStatus, required this.warnings, this.showWarningsBanner = true, this.batteryPercent, this.onSendTap, this.sending = false, required this.onDetailsTap, required this.onWarningsTap, required this.onSettingsTap, }); final List waypoints; final List legClimbBad; final List vertexBad; final int activeIndex; final double totalDistanceM; final double totalDurationSec; /// Nur im Fly-Modus gesetzt (Doku: "Live-Status der Mission in der /// Details-Pille") - ersetzt dort die statischen Plan-Werte /// (Wegpunktzahl/Gesamtdistanz/-dauer) durch aktiven Wegpunkt sowie /// Distanz/Zeit dorthin. Bleibt im Plan-Modus null. final FlyMissionStatus? flyMissionStatus; /// Nur im Fly-Modus gesetzt (Doku: "im fly modus zeigt die drone pille /// den zustand der drohne") - siehe BottomStatsBar.droneStatus. FlyScreen /// setzt hier immer einen Wert (auch ohne Telemetrie-Frame, siehe dortige /// Doku), Plan-Modus nie - dient deshalb hier zugleich als Fly/Plan- /// Unterscheidung fuer die Sichtbarkeit von [batteryPercent], statt dafuer /// ein eigenes Flag zu fuehren. final DroneStatus? droneStatus; final List warnings; /// Blendet das Text-Warnbanner ueber der Fusszeile aus (Doku: "Banner mit /// Warnungen ueber der Fusszeile im Fly-Modus entfernen") - der runde /// Warnungsknopf in BottomStatsBar (oeffnet weiterhin WarningsPanel) bleibt /// davon unberuehrt, nur die staendig sichtbare Textzeile verschwindet. /// Default true, damit der Plan-Modus unveraendert bleibt. final bool showWarningsBanner; /// Nur im Fly-Modus gesetzt (Doku: "Batterieanzeige im Fly-Modus /// hinzufuegen") - zeigt den Batteriebalken ueber der BottomStatsBar an, /// unter einem ggf. ausgeklappten Hoehenprofil. Sichtbarkeit haengt an /// [droneStatus] statt an diesem Wert selbst (siehe dort) - im Fly-Modus /// bleibt der Balken deshalb auch ohne Telemetrie-Frame sichtbar, nur der /// Prozentwert ist dann null (BatteryIndicatorBar zeigt dafuer einen /// neutralen "keine Daten"-Zustand statt 0%, das faelschlich als /// kritischer Ladestand gelesen werden koennte). final int? batteryPercent; /// Siehe BottomStatsBar.onSendTap. final VoidCallback? onSendTap; /// Siehe BottomStatsBar.sending. final bool sending; final VoidCallback onDetailsTap; final VoidCallback onWarningsTap; final VoidCallback onSettingsTap; @override Widget build(BuildContext context, WidgetRef ref) { final isExpanded = ref.watch(altitudeProfileExpandedProvider); return Column( mainAxisSize: MainAxisSize.min, children: [ if (showWarningsBanner && warnings.isNotEmpty) Container( width: double.infinity, color: const Color(0xFF7C2D12), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), child: Text( warnings.map((w) => w.text).join(' ยท '), textAlign: TextAlign.center, style: const TextStyle(color: Color(0xFFFDE3D0), fontSize: 12), ), ), Container( width: double.infinity, color: const Color(0xFF0F0F0F).withValues(alpha: 0.72), child: Column( mainAxisSize: MainAxisSize.min, children: [ if (isExpanded) Padding( padding: const EdgeInsets.fromLTRB(8, 6, 8, 0), child: MiniAltitudeProfile( waypoints: waypoints, legClimbBad: legClimbBad, vertexBad: vertexBad, activeIndex: activeIndex, ), ), if (droneStatus != null) Padding( padding: const EdgeInsets.fromLTRB(0, 4, 0, 0), child: BatteryIndicatorBar(percent: batteryPercent), ), BottomStatsBar( waypointCount: waypoints.length, totalDistanceM: totalDistanceM, totalDurationSec: totalDurationSec, flyMissionStatus: flyMissionStatus, droneStatus: droneStatus, onTap: onDetailsTap, warnings: warnings, onSendTap: onSendTap, sending: sending, onWarningsTap: onWarningsTap, onSettingsTap: onSettingsTap, ), ], ), ), ], ); } }