perf(startup): bootstrap persisted app state

This commit is contained in:
zarzet
2026-07-16 08:08:27 +07:00
parent 10d59bc2b6
commit 5a970ac83d
4 changed files with 109 additions and 21 deletions
@@ -4,3 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
/// main.dart via a ProviderScope override). UI uses it to skip expensive
/// effects like the shell's backdrop blur.
final lowEndDeviceProvider = Provider<bool>((ref) => false);
/// Generic visual capability decided by the startup runtime profile. Effects
/// can consume this without hardcoding a device model or platform source.
final backdropBlurEnabledProvider = Provider<bool>((ref) => false);
+21 -2
View File
@@ -19,6 +19,25 @@ const _spotifyClientSecretKey = 'spotify_client_secret';
const _retiredBuiltInProviderIds = {'deezer', 'qobuz', 'tidal', 'youtube'};
final _log = AppLogger('SettingsProvider');
/// Startup override used to render the correct route/locale on the first
/// frame. The notifier still performs migrations and full validation after it
/// mounts.
final initialSettingsProvider = Provider<AppSettings>(
(ref) => const AppSettings(),
);
AppSettings loadBootstrapSettings(SharedPreferences prefs) {
final rawSettings = prefs.getString(_settingsKey);
if (rawSettings == null || rawSettings.isEmpty) return const AppSettings();
try {
final decoded = jsonDecode(rawSettings);
if (decoded is! Map) return const AppSettings();
return AppSettings.fromJson(Map<String, dynamic>.from(decoded));
} catch (_) {
return const AppSettings();
}
}
class SettingsNotifier extends Notifier<AppSettings> {
static final RegExp _isoRegionPattern = RegExp(r'^[A-Z]{2}$');
static const Set<String> _searchTabValues = {
@@ -41,8 +60,8 @@ class SettingsNotifier extends Notifier<AppSettings> {
@override
AppSettings build() {
_loadSettings();
return const AppSettings();
unawaited(_loadSettings());
return ref.read(initialSettingsProvider);
}
Future<void> _loadSettings() async {
+14 -1
View File
@@ -3,6 +3,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotiflac_android/models/theme_settings.dart';
final initialThemeSettingsProvider = Provider<ThemeSettings>(
(ref) => const ThemeSettings(),
);
ThemeSettings loadBootstrapThemeSettings(SharedPreferences prefs) {
return ThemeSettings(
themeMode: themeModeFromString(prefs.getString(kThemeModeKey)),
useDynamicColor: prefs.getBool(kUseDynamicColorKey) ?? true,
seedColorValue: prefs.getInt(kSeedColorKey) ?? kDefaultSeedColor,
useAmoled: prefs.getBool(kUseAmoledKey) ?? false,
);
}
final themeProvider = NotifierProvider<ThemeNotifier, ThemeSettings>(() {
return ThemeNotifier();
});
@@ -13,7 +26,7 @@ class ThemeNotifier extends Notifier<ThemeSettings> {
@override
ThemeSettings build() {
_loadFromStorage();
return const ThemeSettings();
return ref.read(initialThemeSettingsProvider);
}
Future<void> _loadFromStorage() async {