Add top bar for switching between Plan and Fly mode
- TopModeBar widget: persistent pill-shaped header (HTML prototype: #topBarWrap/#editModeBtn/#flyModeBtn) tinted in the active mode's color, with the inactive mode offered as a solid button in the corner to switch into it. - AppShell now provides a single shared Scaffold + Stack, overlaying TopModeBar on top of whichever screen (Plan/Fly) is active, instead of each screen owning its own Scaffold. - Wired the Fly button to AppModeCubit.toFly(), which enforces the Ready-to-Fly gate (doc 4.5). Since upload/verify isn't wired up yet, the gate is never satisfied yet, so tapping Fly now shows a SnackBar instead of throwing an uncaught StateError. - Extended the widget test to cover both the bar's presence and the gate-rejection path (was the source of a real bug: an initial negative-margin Container hack for the "bleed into the corner" look violated Container's margin.isNonNegative assertion and crashed the whole tree - fixed with padding instead). Verified with flutter analyze, flutter test, and a real run on the Pixel_10a emulator (visually matches the prototype screenshots in design/, Fly-tap correctly shows the gate message without crashing or switching mode). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
02dd1bc11a
commit
fc7d014fda
@@ -4,9 +4,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../app_mode/app_mode_cubit.dart';
|
||||
import 'screens/fly/fly_screen.dart';
|
||||
import 'screens/plan/plan_screen.dart';
|
||||
import 'widgets/top_mode_bar.dart';
|
||||
|
||||
/// Schaltet zwischen Plan- und Fly-Screen um, gesteuert von der
|
||||
/// App-Mode State Machine (Architektur-Doku 2.2). Connect/Upload sind
|
||||
/// Haelt die persistente Kopfleiste (Plan/Fly-Umschalter) und schaltet
|
||||
/// darunter zwischen Plan- und Fly-Screen um, gesteuert von der App-Mode
|
||||
/// State Machine (Architektur-Doku 2.2). Connect/Upload sind
|
||||
/// Uebergangszustaende innerhalb des Plan-Screens (Handover-Prozess).
|
||||
class AppShell extends StatelessWidget {
|
||||
const AppShell({super.key});
|
||||
@@ -14,6 +16,15 @@ class AppShell extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mode = context.select((AppModeCubit c) => c.state.mode);
|
||||
return mode == AppMode.fly ? const FlyScreen() : const PlanScreen();
|
||||
final screen = mode == AppMode.fly ? const FlyScreen() : const PlanScreen();
|
||||
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
Positioned.fill(child: screen),
|
||||
const Align(alignment: Alignment.topCenter, child: TopModeBar()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user