Skip to content

Instantly share code, notes, and snippets.

@yongjhih
Last active November 14, 2024 13:59
Show Gist options
  • Save yongjhih/5d8f74c11c5331bf05b74baa133a9787 to your computer and use it in GitHub Desktop.
Save yongjhih/5d8f74c11c5331bf05b74baa133a9787 to your computer and use it in GitHub Desktop.
abstract class Preference<T> {
String get key;
T? get value;
set value(T? newValue);
T? get();
Future<bool> set(T? newValue);
Future<bool> remove();
}
class BasePreference<T> implements Preference<T> {
const BasePreference(
this.key,
this._getter,
this._setter,
this._remove,
);
@override
final String key;
final T? Function(String key) _getter;
final Future<bool> Function(String key, T value) _setter;
final Future<bool> Function(String key) _remove;
@override
T? get value => get();
@override
set value(T? newValue) => set(newValue);
@override
T? get() => _getter(key);
@override
Future<bool> set(T? newValue) => newValue == null
? remove()
: _setter(key, newValue);
@override
Future<bool> remove() => _remove(key);
}
extension SharedPreferencesX on SharedPreferences {
Preference<bool> asBool(String key) => asPreference(key, getBool, setBool);
Preference<String> asString(String key) => asPreference(key, getString, setString);
Preference<int> asInt(String key) => asPreference(key, getInt, setInt);
Preference<double> asDouble(String key) => asPreference(key, getDouble, setDouble);
Preference<List<String>> asStringList(String key) => asPreference(key, getStringList, setStringList);
Preference<T> asPreference<T>(String key,
T? Function(String key) getter,
Future<bool> Function(String key, T value) setter,
) => BasePreference(key, getter, setter, remove);
}
extension PreferenceStateX<T> on Preference<T> {
/// Custom hook to get and set the preference value, treating it like useState().
ValueNotifier<T?> asState() {
final state = useState<T?>(value); // Initialize state with preference value
// Sync changes back to the preference whenever state.value changes.
useEffect(() {
final listener = () {
value = state.value; // Update preference whenever state changes
};
state.addListener(listener);
// Clean up the listener when the widget is disposed
return () => state.removeListener(listener);
}, [state]);
return state;
}
}
class PreferenceSwitch extends HookWidget {
final Preference<bool> preference;
const PreferenceSwitch({
super.key,
required this.preference,
});
@override
Widget build(BuildContext context) {
final preferenceState = preference.asState();
return Switch(
value: preferenceState.value ?? false,
onChanged: (newValue) {
preferenceState.value = newValue;
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment