mnemo_cards/lib/widgets/shared_pref_button.dart

118 lines
3 KiB
Dart
Raw Normal View History

2024-05-22 20:48:44 +00:00
import 'dart:async';
import 'package:flutter/cupertino.dart';
2024-06-14 19:47:28 +00:00
import 'package:mnemo_cards/main.dart';
2024-06-15 15:42:18 +00:00
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
2024-05-22 20:48:44 +00:00
import 'package:shared_preferences/shared_preferences.dart';
2024-06-15 15:42:18 +00:00
class SharedPrefButton<T> extends StatefulWidget {
final Function(T)? onClick;
2024-05-22 20:48:44 +00:00
final String spKey;
2024-06-15 15:42:18 +00:00
final T Function(T? current)? setOnTap;
final bool Function(T? current)? shouldRebuild;
final Widget Function(T? value, ValueSetter<T> setValue)? builder;
2024-05-22 20:48:44 +00:00
SharedPrefButton({
2024-06-15 15:42:18 +00:00
this.builder,
2024-05-22 20:48:44 +00:00
required this.spKey,
2024-06-15 15:42:18 +00:00
this.setOnTap,
2024-05-22 20:48:44 +00:00
this.onClick,
2024-06-15 15:42:18 +00:00
this.shouldRebuild,
});
SharedPrefButton.builder({
this.builder,
required this.spKey,
this.setOnTap,
this.onClick,
this.shouldRebuild,
2024-05-22 20:48:44 +00:00
});
@override
2024-06-15 15:42:18 +00:00
State<StatefulWidget> createState() => _SharedPrefButtonState<T>();
2024-05-22 20:48:44 +00:00
}
2024-06-15 15:42:18 +00:00
class _SharedPrefButtonState<T> extends State<SharedPrefButton<T>> {
2024-05-22 20:48:44 +00:00
SharedPreferences? _sp;
2024-06-15 15:42:18 +00:00
T? value;
2024-05-22 20:48:44 +00:00
StreamSubscription? _streamSubscription;
@override
void dispose() {
_streamSubscription?.cancel();
_streamSubscription = null;
super.dispose();
}
@override
void initState() {
super.initState();
2024-06-14 19:47:28 +00:00
_sp = globalSharedPreferences;
2024-06-15 15:42:18 +00:00
value = valueFromSp;
_streamSubscription =
Stream.periodic(const Duration(milliseconds: 500), (_) => valueFromSp)
.distinct()
.listen((v) {
if (value != v) {
value = v;
if (mounted && widget.shouldRebuild?.call(value) != false) {
setState(() {});
}
2024-05-22 20:48:44 +00:00
}
});
}
2024-06-15 15:42:18 +00:00
T? get valueFromSp {
if (T == bool) {
return (_sp?.getBool(widget.spKey) ?? false).as<T?>();
} else if (T == int) {
return _sp?.getInt(widget.spKey).as<T?>();
} else if (T == num || T == double) {
return _sp?.getDouble(widget.spKey).as<T?>();
} else if (T == String) {
return _sp?.getString(widget.spKey).as<T?>();
} else if (T == Iterable<String>) {
return _sp?.getStringList(widget.spKey).as<T?>();
}
return null;
}
Future<void> setValue(T value) async {
if (T == bool) {
_sp?.setBool(widget.spKey, value as bool);
} else if (T == int) {
_sp?.setInt(widget.spKey, value as int);
} else if (T == num || T == double) {
_sp?.setDouble(widget.spKey, value as double);
} else if (T == String) {
_sp?.setString(widget.spKey, value as String);
} else if (T == Iterable<String>) {
_sp?.setStringList(widget.spKey, (value as Iterable<String>).toList());
}
}
2024-05-22 20:48:44 +00:00
@override
Widget build(BuildContext context) {
return GestureDetector(
2024-06-15 15:42:18 +00:00
behavior: HitTestBehavior.opaque,
onTap: widget.setOnTap != null
? () async {
value = widget.setOnTap!.call(value);
if (value != null) {
_setValue(value!);
}
2024-05-22 20:48:44 +00:00
}
: null,
2024-06-15 15:42:18 +00:00
child: widget.builder?.call(value, _setValue),
2024-05-22 20:48:44 +00:00
);
}
2024-06-15 15:42:18 +00:00
Future<void> _setValue(T value) async {
await setValue(value!);
if (widget.shouldRebuild?.call(value) != false) {
setState(() {});
}
}
2024-05-22 20:48:44 +00:00
}