import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../view/settings/defaultSettings.dart'; import 'settings.dart'; class SettingsProvider extends ChangeNotifier { static const String _fieldName = "settings"; late SharedPreferences _storage; late Settings _settings = DefaultSettings.get(); Settings val({bool write = false}) { if(write) { notifyListeners(); Future.delayed(const Duration(milliseconds: 300)).then((_) => update()); } return _settings; } SettingsProvider() { _readFromStorage(); } void reset() async { _storage = await SharedPreferences.getInstance(); _storage.remove(_fieldName); notifyListeners(); } void _readFromStorage() async { _storage = await SharedPreferences.getInstance(); try { _settings = Settings.fromJson(jsonDecode(_storage.getString(_fieldName)!)); } catch(exception) { try { log("Settings were changed, trying to recover from old Settings: ${exception.toString()}"); _settings = Settings.fromJson(_mergeSettings(jsonDecode(_storage.getString(_fieldName)!), DefaultSettings.get().toJson())); log("Settings recovered successfully: ${_settings.toJson().toString()}"); } catch(exception) { log("Settings are defective and not recoverable, using defaults: ${exception.toString()}"); _settings = DefaultSettings.get(); log("Settings were reset to defaults!"); } } notifyListeners(); } void update() async { await _storage.setString(_fieldName, jsonEncode(_settings.toJson())); } Map _mergeSettings(Map oldMap, Map newMap) { Map mergedMap = Map.from(newMap); oldMap.forEach((key, value) { if (mergedMap.containsKey(key)) { if (value is Map && mergedMap[key] is Map) { mergedMap[key] = _mergeSettings(value, mergedMap[key]); } else { mergedMap[key] = value; } } }); return mergedMap; } }