ionic-planb-logistic-app-fl.../lib/main.dart
Jean-Philippe Brule 96c9e59cf0 Implement system theme support and dark mode infrastructure
Add comprehensive theme management system with iOS system integration:

- System theme detection: App follows iOS dark/light mode preferences via ThemeMode.system
- Theme provider: Centralized theme state management with Riverpod (defaults to dark mode)
- Settings toggle: Segmented button UI for Light/Dark/Auto theme selection
- iOS system UI: Status bar and navigation bar adapt to current theme brightness

Dark mode map styling (Android-ready):
- DarkModeMapComponent: Reactive theme change detection with didChangeDependencies
- Map style application: Custom dark JSON style for navigation maps
- Theme-aware styling: Automatically applies/resets map style on theme changes
- Note: Map styling currently Android-only due to iOS SDK limitations

Updates:
- main.dart: System UI overlay styling for iOS, theme provider integration
- settings_page.dart: SegmentedButton theme toggle with icons
- providers.dart: themeModeProvider for app-wide theme state
- dark_mode_map.dart: Theme reactivity and style application logic
- navigation_page.dart: Theme detection infrastructure (prepared for future use)

Design philosophy:
- Follow system preferences by default for native iOS experience
- Manual override available for user preference
- Clean separation between Flutter UI theming and native map styling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 00:52:14 -05:00

90 lines
2.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'theme.dart';
import 'providers/providers.dart';
import 'pages/login_page.dart';
import 'pages/routes_page.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
runApp(
const ProviderScope(
child: PlanBLogisticApp(),
),
);
}
class PlanBLogisticApp extends ConsumerWidget {
const PlanBLogisticApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final language = ref.watch(languageProvider);
final themeMode = ref.watch(themeModeProvider);
return MaterialApp(
title: 'Plan B Logistics',
theme: MaterialTheme(const TextTheme()).light(),
darkTheme: MaterialTheme(const TextTheme()).dark(),
themeMode: themeMode,
locale: Locale(language),
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('fr', ''),
],
home: const AppHome(),
);
}
}
class AppHome extends ConsumerWidget {
const AppHome({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isAuthenticatedAsync = ref.watch(isAuthenticatedProvider);
// Update iOS system UI to match current theme
final brightness = Theme.of(context).brightness;
final isDark = brightness == Brightness.dark;
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarBrightness: isDark ? Brightness.dark : Brightness.light,
statusBarIconBrightness: isDark ? Brightness.light : Brightness.dark,
systemNavigationBarColor: isDark ? Colors.black : Colors.white,
systemNavigationBarIconBrightness: isDark ? Brightness.light : Brightness.dark,
),
);
return isAuthenticatedAsync.when(
data: (isAuthenticated) {
if (isAuthenticated) {
return const RoutesPage();
} else {
return const LoginPage();
}
},
loading: () => const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
),
error: (error, stackTrace) => const LoginPage(),
);
}
}