import "package:flutter/material.dart"; import "package:shared_preferences/shared_preferences.dart"; import "models.dart"; /// App-wide appearance preferences (theme / locale / date format / font size), /// mirroring the web app's prefs.js. Persisted to SharedPreferences so the /// chosen theme survives a restart before /api/me loads, and exposed as a /// ChangeNotifier so MaterialApp and date formatting react to changes. class AppSettings extends ChangeNotifier { static const _kTheme = "cc_theme"; static const _kLocale = "cc_locale"; static const _kDateFormat = "cc_dateFormat"; static const _kFontSize = "cc_fontSize"; String theme = "system"; // light | dark | system String locale = "en-US"; String dateFormat = "YMD"; // YMD | DMY_NUM | DMY | MDY String fontSize = "medium"; // small | medium | large Future loadFromStorage() async { final prefs = await SharedPreferences.getInstance(); theme = prefs.getString(_kTheme) ?? theme; locale = prefs.getString(_kLocale) ?? locale; dateFormat = prefs.getString(_kDateFormat) ?? dateFormat; fontSize = prefs.getString(_kFontSize) ?? fontSize; notifyListeners(); } Future _persist() async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_kTheme, theme); await prefs.setString(_kLocale, locale); await prefs.setString(_kDateFormat, dateFormat); await prefs.setString(_kFontSize, fontSize); } /// Sync from a freshly fetched profile (login, boot, settings saves). void applyFromProfile(UserProfile p) { theme = p.theme; locale = p.locale; dateFormat = p.dateFormat; fontSize = p.fontSize; _persist(); notifyListeners(); } /// Optimistically apply a single changed field (used by Settings so the UI /// reacts instantly while the PATCH is in flight). void patch({String? theme, String? locale, String? dateFormat, String? fontSize}) { if (theme != null) this.theme = theme; if (locale != null) this.locale = locale; if (dateFormat != null) this.dateFormat = dateFormat; if (fontSize != null) this.fontSize = fontSize; _persist(); notifyListeners(); } ThemeMode get themeMode => switch (theme) { "light" => ThemeMode.light, "dark" => ThemeMode.dark, _ => ThemeMode.system, }; double get textScale => switch (fontSize) { "small" => 0.9375, "large" => 1.125, _ => 1.0, }; }