mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-12 01:36:20 +02:00
112 lines
3.0 KiB
Dart
112 lines
3.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
/// Theme mode preference options
|
|
enum AppThemeMode {
|
|
system, // Follow system preference
|
|
light, // Force light mode
|
|
dark, // Force dark mode
|
|
}
|
|
|
|
/// Keys for SharedPreferences storage
|
|
class _ThemeKeys {
|
|
static const String themeMode = 'app_theme_mode';
|
|
}
|
|
|
|
/// Theme state containing current mode
|
|
class ThemeState {
|
|
final AppThemeMode appThemeMode;
|
|
final ThemeMode themeMode;
|
|
|
|
const ThemeState({
|
|
this.appThemeMode = AppThemeMode.dark,
|
|
this.themeMode = ThemeMode.dark,
|
|
});
|
|
|
|
ThemeState copyWith({
|
|
AppThemeMode? appThemeMode,
|
|
ThemeMode? themeMode,
|
|
}) {
|
|
return ThemeState(
|
|
appThemeMode: appThemeMode ?? this.appThemeMode,
|
|
themeMode: themeMode ?? this.themeMode,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Theme provider for managing light/dark mode with persistence
|
|
class ThemeNotifier extends StateNotifier<ThemeState> {
|
|
ThemeNotifier() : super(const ThemeState()) {
|
|
_loadTheme();
|
|
}
|
|
|
|
/// Load saved theme preference from SharedPreferences
|
|
Future<void> _loadTheme() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final savedMode = prefs.getString(_ThemeKeys.themeMode);
|
|
|
|
if (savedMode != null) {
|
|
final appMode = AppThemeMode.values.firstWhere(
|
|
(e) => e.name == savedMode,
|
|
orElse: () => AppThemeMode.dark,
|
|
);
|
|
state = state.copyWith(
|
|
appThemeMode: appMode,
|
|
themeMode: _mapToThemeMode(appMode),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Error loading theme: $e');
|
|
}
|
|
}
|
|
|
|
/// Set theme mode and persist to SharedPreferences
|
|
Future<void> setThemeMode(AppThemeMode mode) async {
|
|
state = state.copyWith(
|
|
appThemeMode: mode,
|
|
themeMode: _mapToThemeMode(mode),
|
|
);
|
|
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_ThemeKeys.themeMode, mode.name);
|
|
} catch (e) {
|
|
debugPrint('Error saving theme: $e');
|
|
}
|
|
}
|
|
|
|
/// Quick toggle between light and dark (skip system)
|
|
Future<void> toggleTheme() async {
|
|
final newMode = state.appThemeMode == AppThemeMode.dark
|
|
? AppThemeMode.light
|
|
: AppThemeMode.dark;
|
|
await setThemeMode(newMode);
|
|
}
|
|
|
|
/// Check if currently in dark mode
|
|
bool get isDarkMode {
|
|
return state.themeMode == ThemeMode.dark ||
|
|
(state.themeMode == ThemeMode.system &&
|
|
WidgetsBinding.instance.platformDispatcher.platformBrightness == Brightness.dark);
|
|
}
|
|
|
|
/// Map AppThemeMode to Flutter's ThemeMode
|
|
ThemeMode _mapToThemeMode(AppThemeMode mode) {
|
|
switch (mode) {
|
|
case AppThemeMode.system:
|
|
return ThemeMode.system;
|
|
case AppThemeMode.light:
|
|
return ThemeMode.light;
|
|
case AppThemeMode.dark:
|
|
return ThemeMode.dark;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Provider for theme state
|
|
final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeState>((ref) {
|
|
return ThemeNotifier();
|
|
});
|