Files
umbrix/lib/utils/pref_notifier.dart

103 lines
2.6 KiB
Dart
Raw Normal View History

2023-12-01 12:56:24 +03:30
import 'package:hiddify/core/preferences/preferences_provider.dart';
2023-09-06 12:56:30 +03:30
import 'package:hiddify/utils/custom_loggers.dart';
2023-08-24 14:48:19 +03:30
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
2023-09-17 14:24:25 +03:30
class Pref<T, P> with InfraLogger {
const Pref(
this.prefs,
this.key,
this.defaultValue, {
this.mapFrom,
this.mapTo,
});
final SharedPreferences prefs;
final String key;
final T defaultValue;
2023-09-17 14:24:25 +03:30
final T Function(P value)? mapFrom;
final P Function(T value)? mapTo;
/// Updates the value asynchronously.
Future<void> update(T value) async {
2023-09-14 12:56:22 +03:30
loggy.debug("updating preference [$key]($T) to [$value]");
2023-09-17 14:24:25 +03:30
Object? mapped = value;
if (mapTo != null) {
mapped = mapTo!(value);
}
try {
2023-09-17 14:24:25 +03:30
switch (mapped) {
case String _:
await prefs.setString(key, mapped);
case bool _:
await prefs.setBool(key, mapped);
case int _:
await prefs.setInt(key, mapped);
case double _:
await prefs.setDouble(key, mapped);
case List<String> _:
await prefs.setStringList(key, mapped);
}
} catch (e) {
loggy.warning("error updating preference[$key]: $e");
}
}
T getValue() {
try {
2023-09-14 12:56:22 +03:30
loggy.debug("getting persisted preference [$key]($T)");
2023-09-17 14:24:25 +03:30
if (mapFrom != null) {
final persisted = prefs.get(key) as P?;
if (persisted == null) return defaultValue;
return mapFrom!(persisted);
2023-09-14 12:56:22 +03:30
} else if (T == List<String>) {
2023-09-17 14:24:25 +03:30
return prefs.getStringList(key) as T? ?? defaultValue;
}
return prefs.get(key) as T? ?? defaultValue;
} catch (e) {
loggy.warning("error getting preference[$key]: $e");
return defaultValue;
}
}
}
2023-09-17 14:24:25 +03:30
class PrefNotifier<T, P> extends AutoDisposeNotifier<T> with InfraLogger {
2023-09-06 12:56:30 +03:30
PrefNotifier(
2023-09-17 14:24:25 +03:30
this._key,
this._defaultValue,
this._mapFrom,
this._mapTo,
2023-09-06 12:56:30 +03:30
);
2023-08-24 14:48:19 +03:30
2023-09-17 14:24:25 +03:30
final String _key;
final T _defaultValue;
final T Function(P value)? _mapFrom;
final P Function(T)? _mapTo;
late final Pref<T, P> _pref = Pref(
2023-12-01 12:56:24 +03:30
ref.watch(sharedPreferencesProvider).requireValue,
2023-09-17 14:24:25 +03:30
_key,
_defaultValue,
mapFrom: _mapFrom,
mapTo: _mapTo,
);
2023-08-24 14:48:19 +03:30
2023-09-17 14:24:25 +03:30
static AutoDisposeNotifierProvider<PrefNotifier<T, P>, T> provider<T, P>(
2023-08-24 14:48:19 +03:30
String key,
2023-09-01 14:55:15 +03:30
T defaultValue, {
2023-09-17 14:24:25 +03:30
T Function(P value)? mapFrom,
P Function(T value)? mapTo,
2023-09-01 14:55:15 +03:30
}) =>
2023-09-06 12:56:30 +03:30
AutoDisposeNotifierProvider(
2023-09-01 14:55:15 +03:30
() => PrefNotifier(key, defaultValue, mapFrom, mapTo),
2023-08-24 14:48:19 +03:30
);
2023-09-06 12:56:30 +03:30
Future<void> update(T value) async {
2023-09-17 14:24:25 +03:30
_pref.update(value);
2023-09-06 12:56:30 +03:30
super.state = value;
}
@override
2023-09-17 14:24:25 +03:30
T build() => _pref.getValue();
2023-08-24 14:48:19 +03:30
}