84 lines
2.7 KiB
Dart
84 lines
2.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../constants/enums.dart';
|
|
import '../constants/storage_keys.dart';
|
|
import 'app_theme.dart';
|
|
import 'branding_config.dart';
|
|
|
|
final sharedPreferencesProvider = Provider<SharedPreferences>((ref) {
|
|
throw UnimplementedError('SharedPreferences must be overridden in main.dart');
|
|
});
|
|
|
|
final themeModeProvider = StateNotifierProvider<ThemeModeNotifier, ThemeModeOption>((ref) {
|
|
return ThemeModeNotifier(ref.watch(sharedPreferencesProvider));
|
|
});
|
|
|
|
final brandingProvider = StateNotifierProvider<BrandingNotifier, BrandingConfig>((ref) {
|
|
return BrandingNotifier(ref.watch(sharedPreferencesProvider));
|
|
});
|
|
|
|
class ThemeModeNotifier extends StateNotifier<ThemeModeOption> {
|
|
ThemeModeNotifier(this._prefs) : super(ThemeModeOption.system) {
|
|
_load();
|
|
}
|
|
|
|
final SharedPreferences _prefs;
|
|
|
|
void _load() {
|
|
final saved = _prefs.getString(StorageKeys.themeMode);
|
|
if (saved != null) {
|
|
state = ThemeModeOption.fromValue(saved);
|
|
}
|
|
}
|
|
|
|
Future<void> setThemeMode(ThemeModeOption mode) async {
|
|
state = mode;
|
|
await _prefs.setString(StorageKeys.themeMode, mode.value);
|
|
}
|
|
}
|
|
|
|
class BrandingNotifier extends StateNotifier<BrandingConfig> {
|
|
BrandingNotifier(this._prefs) : super(const BrandingConfig()) {
|
|
_load();
|
|
}
|
|
|
|
final SharedPreferences _prefs;
|
|
|
|
void _load() {
|
|
final primary = _prefs.getInt(StorageKeys.brandingPrimaryColor);
|
|
final secondary = _prefs.getInt(StorageKeys.brandingSecondaryColor);
|
|
final logoUrl = _prefs.getString(StorageKeys.brandingLogoUrl);
|
|
|
|
state = BrandingConfig(
|
|
primaryColorValue: primary ?? state.primaryColorValue,
|
|
secondaryColorValue: secondary ?? state.secondaryColorValue,
|
|
logoUrl: logoUrl,
|
|
);
|
|
}
|
|
|
|
Future<void> updateBranding(BrandingConfig config) async {
|
|
state = config;
|
|
await _prefs.setInt(StorageKeys.brandingPrimaryColor, config.primaryColorValue);
|
|
await _prefs.setInt(StorageKeys.brandingSecondaryColor, config.secondaryColorValue);
|
|
final logo = config.logoUrl?.trim();
|
|
if (logo != null && logo.isNotEmpty) {
|
|
await _prefs.setString(StorageKeys.brandingLogoUrl, logo);
|
|
} else {
|
|
await _prefs.remove(StorageKeys.brandingLogoUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
ThemeMode resolveThemeMode(ThemeModeOption option) {
|
|
return switch (option) {
|
|
ThemeModeOption.light => ThemeMode.light,
|
|
ThemeModeOption.dark => ThemeMode.dark,
|
|
ThemeModeOption.system => ThemeMode.system,
|
|
};
|
|
}
|
|
|
|
ThemeData buildLightTheme(BrandingConfig branding) => AppTheme.light(branding: branding);
|
|
ThemeData buildDarkTheme(BrandingConfig branding) => AppTheme.dark(branding: branding);
|