import 'dart:async'; import 'package:flutter_driver/driver_extension.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'src/demo_controller.dart'; import 'src/demo_view.dart'; const _defaultServerUrl = String.fromEnvironment( 'SERVERPOD_URL', defaultValue: 'http://localhost:8080/', ); const _lightDemoColorScheme = ColorSchemes.lightNeutral; const _darkDemoColorScheme = ColorSchemes.darkNeutral; ThemeData _demoTheme(ColorScheme colorScheme) { return ThemeData(colorScheme: colorScheme, radius: 0.5); } void main() { enableFlutterDriverExtension(enableTextEntryEmulation: false); runApp(const DemoRoot()); } /// Hosts the [ShadcnApp] and owns the light/dark theme selection. class DemoRoot extends StatefulWidget { const DemoRoot({super.key}); @override State createState() => _DemoRootState(); } class _DemoRootState extends State { bool _isDark = true; void _toggleTheme() => setState(() => _isDark = !_isDark); @override Widget build(BuildContext context) { return ShadcnApp( title: 'Offline Sync Demo', theme: _demoTheme(_lightDemoColorScheme), darkTheme: _demoTheme(_darkDemoColorScheme), themeMode: _isDark ? ThemeMode.dark : ThemeMode.light, debugShowCheckedModeBanner: false, home: DemoHome(isDark: _isDark, onToggleTheme: _toggleTheme), ); } } /// The main screen: builds the controller and the dashboard scaffold. class DemoHome extends StatefulWidget { const DemoHome({ super.key, required this.isDark, required this.onToggleTheme, }); final bool isDark; final VoidCallback onToggleTheme; @override State createState() => _DemoHomeState(); } class _DemoHomeState extends State { late final DemoController controller; @override void initState() { super.initState(); controller = DemoController(serverUrl: _defaultServerUrl); unawaited(controller.initialize()); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( headers: [ AppBar( title: const Text('Serverpod Offline Sync Demo'), subtitle: const Text(_defaultServerUrl), trailing: [ ThemeToggleButton( isDark: widget.isDark, onToggle: widget.onToggleTheme, ), const Gap(8), UserAvatarMenu(controller: controller), ], ), const Divider(), ], child: DemoDashboard(controller: controller), ); } }