import 'dart:convert'; import 'package:color_blindness/color_blindness.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../models/focus_mode_data.dart'; import '../models/settings/network_capabilities_settings.dart'; import '../utils/theme_mode_extensions.dart'; const _lowBandwidthModeKey = 'LowBandwidthMode'; const _themeModeKey = 'ThemeMode'; const _colorBlindnessTestingModeKey = 'ColorBlindnessTestingMode'; const _logLevelKey = 'LogLevel'; const _networkCapabilitiesKey = 'NetworkCapabilities'; const _notificationGroupingKey = 'NotificationGrouping'; const _spoilerHidingEnabledKey = 'SpoilerHidingEnabled'; const _focusModeKey = 'FocusMode'; class SettingsService extends ChangeNotifier { late final SharedPreferences _prefs; var _initialized = false; SettingsService(); var _lowBandwidthMode = false; bool get lowBandwidthMode => _lowBandwidthMode; set lowBandwidthMode(bool value) { _lowBandwidthMode = value; _prefs.setBool(_lowBandwidthModeKey, _lowBandwidthMode); notifyListeners(); } var _notificationGrouping = true; bool get notificationGrouping => _notificationGrouping; set notificationGrouping(bool value) { _notificationGrouping = value; _prefs.setBool(_notificationGroupingKey, _notificationGrouping); notifyListeners(); } var _spoilerHidingEnabled = true; bool get spoilerHidingEnabled => _spoilerHidingEnabled; set spoilerHidingEnabled(bool value) { _spoilerHidingEnabled = value; _prefs.setBool(_spoilerHidingEnabledKey, _spoilerHidingEnabled); notifyListeners(); } var _themeMode = ThemeMode.system; ThemeMode get themeMode => _themeMode; set themeMode(ThemeMode mode) { _themeMode = mode; _prefs.setString(_themeModeKey, _themeMode.name); notifyListeners(); } ColorBlindnessType _colorBlindnessType = ColorBlindnessType.none; ColorBlindnessType get colorBlindnessType => _colorBlindnessType; set colorBlindnessType(ColorBlindnessType type) { _colorBlindnessType = type; _prefs.setString(_colorBlindnessTestingModeKey, type.name); notifyListeners(); } Level _logLevel = Level.SEVERE; Level get logLevel => _logLevel; set logLevel(Level level) { _logLevel = level; _prefs.setString(_logLevelKey, level.name); notifyListeners(); } NetworkCapabilitiesSettings _networkCapabilities = NetworkCapabilitiesSettings.defaultSettings(); NetworkCapabilitiesSettings get networkCapabilities => _networkCapabilities; set networkCapabilities(NetworkCapabilitiesSettings updatedCapabilities) { _networkCapabilities = updatedCapabilities; final jsonString = jsonEncode(_networkCapabilities.toJson()); _prefs.setString(_networkCapabilitiesKey, jsonString); notifyListeners(); } FocusModeData _focusModeData = FocusModeData.disabled(); FocusModeData get focusModeData => _focusModeData; set focusModeData(FocusModeData updatedData) { _focusModeData = updatedData; final jsonData = _focusModeData.toJson(); final jsonString = jsonEncode(jsonData); _prefs.setString(_focusModeKey, jsonString); notifyListeners(); } Future initialize() async { if (_initialized) { return; } _prefs = await SharedPreferences.getInstance(); _lowBandwidthMode = _prefs.getBool(_lowBandwidthModeKey) ?? false; _notificationGrouping = _prefs.getBool(_notificationGroupingKey) ?? true; _spoilerHidingEnabled = _prefs.getBool(_spoilerHidingEnabledKey) ?? true; _themeMode = ThemeModeExtensions.parse(_prefs.getString(_themeModeKey)); _colorBlindnessType = _colorBlindnessTypeFromPrefs(_prefs); _logLevel = _levelFromPrefs(_prefs); _networkCapabilities = _networkCapabilitiesFromPrefs(_prefs); _focusModeData = _focusModeDataFromPrefs(_prefs); _initialized = true; } } ColorBlindnessType _colorBlindnessTypeFromPrefs(SharedPreferences prefs) { final cbString = prefs.getString(_colorBlindnessTestingModeKey); if (cbString?.isEmpty ?? true) { return ColorBlindnessType.none; } return ColorBlindnessType.values.firstWhere( (c) => c.name == cbString, orElse: () => ColorBlindnessType.none, ); } NetworkCapabilitiesSettings _networkCapabilitiesFromPrefs( SharedPreferences prefs) { final ncString = prefs.getString(_networkCapabilitiesKey); if (ncString?.isEmpty ?? true) { return NetworkCapabilitiesSettings.defaultSettings(); } final List json = jsonDecode(ncString!); final nc = NetworkCapabilitiesSettings.fromJson(json); return nc; } Level _levelFromPrefs(SharedPreferences prefs) { final levelString = prefs.getString(_logLevelKey); return switch (levelString) { 'ALL' => Level.ALL, 'FINEST' => Level.FINEST, 'FINER' => Level.FINER, 'FINE' => Level.FINE, 'CONFIG' => Level.CONFIG, 'INFO' => Level.INFO, 'WARNING' => Level.WARNING, 'SEVERE' => Level.SEVERE, 'SHOUT' => Level.SHOUT, 'OFF' => Level.OFF, _ => Level.OFF, }; } FocusModeData _focusModeDataFromPrefs(SharedPreferences prefs) { final fmString = prefs.getString(_focusModeKey); if (fmString?.isEmpty ?? true) { return FocusModeData.disabled(); } final Map json = jsonDecode(fmString!); final fm = FocusModeData.fromJson(json); return fm; }