Files
SpotiFLAC-Mobile/lib/providers/theme_provider.dart
T
zarzet 6388f3a5b8 perf: optimize providers, caching, and reduce rebuilds
- Cache SharedPreferences.getInstance() in providers (settings, theme, recent_access)
- Pre-compute download counts in queue provider to avoid repeated filtering
- Add identical() caching for RecentAccessView in HomeTab
- Use selective watching for exploreProvider (sections, greeting, isLoading only)
- Move isYTMusicQuickPicks computation to ExploreSection.fromJson()
- Hoist static RegExp patterns to avoid repeated compilation
- Use batch operations for iOS path migration in history_database
- Replace containsKey+lookup with single lookup in palette_service
- Pre-compute lowercase strings outside filter loops in logger
- Fix _isLoaded race condition in DownloadHistoryNotifier
2026-01-22 03:56:47 +07:00

94 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotiflac_android/models/theme_settings.dart';
/// Provider for theme settings state management
final themeProvider = NotifierProvider<ThemeNotifier, ThemeSettings>(() {
return ThemeNotifier();
});
/// Notifier for managing theme settings with persistence
class ThemeNotifier extends Notifier<ThemeSettings> {
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
@override
ThemeSettings build() {
// Load settings asynchronously on first access
_loadFromStorage();
return const ThemeSettings();
}
/// Load theme settings from SharedPreferences
Future<void> _loadFromStorage() async {
try {
final prefs = await _prefs;
final modeString = prefs.getString(kThemeModeKey);
final useDynamic = prefs.getBool(kUseDynamicColorKey);
final seedColor = prefs.getInt(kSeedColorKey);
final useAmoled = prefs.getBool(kUseAmoledKey);
state = ThemeSettings(
themeMode: _themeModeFromString(modeString),
useDynamicColor: useDynamic ?? true,
seedColorValue: seedColor ?? kDefaultSeedColor,
useAmoled: useAmoled ?? false,
);
} catch (e) {
debugPrint('Error loading theme settings: $e');
}
}
/// Save current settings to SharedPreferences
Future<void> _saveToStorage() async {
try {
final prefs = await _prefs;
await prefs.setString(kThemeModeKey, state.themeMode.name);
await prefs.setBool(kUseDynamicColorKey, state.useDynamicColor);
await prefs.setInt(kSeedColorKey, state.seedColorValue);
await prefs.setBool(kUseAmoledKey, state.useAmoled);
} catch (e) {
debugPrint('Error saving theme settings: $e');
}
}
/// Set theme mode (light, dark, or system)
Future<void> setThemeMode(ThemeMode mode) async {
state = state.copyWith(themeMode: mode);
await _saveToStorage();
}
/// Enable or disable dynamic color from wallpaper
Future<void> setUseDynamicColor(bool value) async {
state = state.copyWith(useDynamicColor: value);
await _saveToStorage();
}
/// Set custom seed color (used when dynamic color is disabled)
Future<void> setSeedColor(Color color) async {
state = state.copyWith(seedColorValue: color.toARGB32());
await _saveToStorage();
}
/// Set seed color from int value
Future<void> setSeedColorValue(int colorValue) async {
state = state.copyWith(seedColorValue: colorValue);
await _saveToStorage();
}
/// Enable or disable AMOLED mode (pure black background)
Future<void> setUseAmoled(bool value) async {
state = state.copyWith(useAmoled: value);
await _saveToStorage();
}
/// Helper to convert string to ThemeMode
ThemeMode _themeModeFromString(String? value) {
if (value == null) return ThemeMode.system;
return ThemeMode.values.firstWhere(
(e) => e.name == value,
orElse: () => ThemeMode.system,
);
}
}