import 'package:hub/shared/utils/storage_util.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:hub/shared/utils/cache_util.dart'; import 'package:synchronized/synchronized.dart'; class SharedPreferencesStorageHelper implements Storage { static final SharedPreferencesStorageHelper _instance = SharedPreferencesStorageHelper._internal(); static final _lock = Lock(); SharedPreferences? _prefs; factory SharedPreferencesStorageHelper() => _instance; SharedPreferencesStorageHelper._internal(); static SharedPreferencesStorageHelper get instance => _instance; bool _isFirstRun = true; bool get isFirstRun => _isFirstRun; set isFirstRun(bool value) => _setAndCacheBool('first_run', value, (v) => _isFirstRun = v); Future ensureInitialization() async { await _lock.synchronized(() async { if (_prefs == null) { _prefs = await SharedPreferences.getInstance(); _isFirstRun = _prefs?.getBool('first_run') ?? true; } }); } Future _setAndCache(String key, T value, Function(T) cacheSetter, Future Function(String, T) setFunc) async { await _lock.synchronized(() async { await setFunc(key, value); CacheUtil.instance.set(key, value); cacheSetter(value); }); } Future _setAndCacheString(String key, String value, Function(String) cacheSetter) async { await _setAndCache(key, value, cacheSetter, _prefs!.setString); } Future _setAndCacheBool(String key, bool value, Function(bool) cacheSetter) async { await _setAndCache(key, value, cacheSetter, _prefs!.setBool); } Future _setAndCacheInt(String key, int value, Function(int) cacheSetter) async { await _setAndCache(key, value, cacheSetter, _prefs!.setInt); } Future _setAndCacheDouble(String key, double value, Function(double) cacheSetter) async { await _setAndCache(key, value, cacheSetter, _prefs!.setDouble); } Future _setAndCacheStringList(String key, List value, Function(List) cacheSetter) async { await _setAndCache(key, value, cacheSetter, _prefs!.setStringList); } @override Future set(String key, dynamic value) async { await _lock.synchronized(() async { if (value is bool) { await _prefs?.setBool(key, value); } else if (value is String) { await _prefs?.setString(key, value); } else if (value is int) { await _prefs?.setInt(key, value); } else if (value is double) { await _prefs?.setDouble(key, value); } else if (value is List) { await _prefs?.setStringList(key, value); } CacheUtil.instance.set(key, value); }); } @override Future get(String key) async { return await _lock.synchronized(() async { var value = CacheUtil.instance.get(key); if (value == null) { value = _prefs?.get(key); CacheUtil.instance.set(key, value); } return value; }); } @override Future delete(String key) async { await _lock.synchronized(() async { await _prefs?.remove(key); CacheUtil.instance.delete(key); }); } Future purge() async { await _lock.synchronized(() async { await _prefs?.clear(); CacheUtil.instance.clear(); await ensureInitialization(); }); } }