diff --git a/lib/utils/pref_notifier.dart b/lib/utils/pref_notifier.dart index a3063bd0..5a6bc761 100644 --- a/lib/utils/pref_notifier.dart +++ b/lib/utils/pref_notifier.dart @@ -3,39 +3,52 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; class PrefNotifier extends AutoDisposeNotifier { - PrefNotifier(this._key, this._defaultValue); + PrefNotifier(this._key, this._defaultValue, this._mapFrom, this._mapTo); final String _key; final T _defaultValue; + final T Function(String)? _mapFrom; + final String Function(T)? _mapTo; static AutoDisposeNotifierProvider, T> provider( String key, - T defaultValue, - ) => + T defaultValue, { + T Function(String value)? mapFrom, + String Function(T value)? mapTo, + }) => NotifierProvider.autoDispose( - () => PrefNotifier(key, defaultValue), + () => PrefNotifier(key, defaultValue, mapFrom, mapTo), ); SharedPreferences get _prefs => ref.read(sharedPreferencesProvider); /// Updates the value asynchronously. Future update(T value) async { - if (value is String) { - await _prefs.setString(_key, value); - } else if (value is bool) { - await _prefs.setBool(_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); + if (_mapTo != null && _mapFrom != null) { + await _prefs.setString(_key, _mapTo!(value)); + } else { + switch (value) { + case String _: + await _prefs.setString(_key, value); + case bool _: + await _prefs.setBool(_key, value); + case int _: + await _prefs.setInt(_key, value); + case double _: + await _prefs.setDouble(_key, value); + case List _: + await _prefs.setStringList(_key, value); + } } super.state = value; } @override T build() { + if (_mapTo != null && _mapFrom != null) { + final persisted = _prefs.getString(_key); + return persisted != null ? _mapFrom!(persisted) : _defaultValue; + } return _prefs.get(_key) as T? ?? _defaultValue; } } diff --git a/lib/utils/validators.dart b/lib/utils/validators.dart index fff27f9b..7be7e631 100644 --- a/lib/utils/validators.dart +++ b/lib/utils/validators.dart @@ -3,7 +3,16 @@ final _urlRegex = RegExp( r"^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$", ); +/// https://stackoverflow.com/a/12968117 +final _portRegex = RegExp( + r"^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", +); + /// https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url/3809435#3809435 bool isUrl(String input) { return _urlRegex.hasMatch(input.trim().toLowerCase()); } + +bool isPort(String input) { + return _portRegex.hasMatch(input); +}