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>
This commit is contained in:
Jean-Philippe Brule
2025-11-16 00:52:14 -05:00
parent fcf8c9bd94
commit 96c9e59cf0
5 changed files with 273 additions and 40 deletions
+40 -4
View File
@@ -31,6 +31,7 @@ class _DarkModeMapComponentState extends State<DarkModeMapComponent> {
bool _isInitializing = false;
bool _isStartingNavigation = false;
String _loadingMessage = 'Initializing...';
Brightness? _lastBrightness;
@override
void initState() {
@@ -38,6 +39,20 @@ class _DarkModeMapComponentState extends State<DarkModeMapComponent> {
_initializeNavigation();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Detect theme changes and reapply map style
final currentBrightness = Theme.of(context).brightness;
if (_lastBrightness != null &&
_lastBrightness != currentBrightness &&
_navigationController != null) {
_applyDarkModeStyle();
}
_lastBrightness = currentBrightness;
}
Future<void> _initializeNavigation() async {
if (_isInitializing || _isSessionInitialized) return;
@@ -121,14 +136,35 @@ class _DarkModeMapComponentState extends State<DarkModeMapComponent> {
if (!mounted || _navigationController == null) return;
try {
// Apply dark mode style configuration for Google Maps
// This reduces eye strain in low-light environments
if (!mounted) return;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
if (isDarkMode) {
// Dark map style with warm accent colors
await _navigationController!.setMapStyle(_getDarkMapStyle());
// Dark mode style - Note: Currently only supported on Android
const simpleDarkStyle = '''[
{
"elementType": "geometry",
"stylers": [{"color": "#242424"}]
},
{
"elementType": "labels.text.fill",
"stylers": [{"color": "#746855"}]
},
{
"elementType": "labels.text.stroke",
"stylers": [{"color": "#242424"}]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [{"color": "#17263c"}]
}
]''';
await _navigationController!.setMapStyle(simpleDarkStyle);
} else {
// Reset to default light style
await _navigationController!.setMapStyle(null);
}
} catch (e) {
if (mounted) {