Nikolas Rimikis
1 year ago
28 changed files with 399 additions and 389 deletions
@ -1,51 +1,67 @@
|
||||
import 'dart:async'; |
||||
|
||||
import 'package:collection/collection.dart'; |
||||
import 'package:neon/src/settings/models/option.dart'; |
||||
import 'package:neon/src/settings/widgets/label_builder.dart'; |
||||
import 'package:rxdart/rxdart.dart'; |
||||
|
||||
class SelectOption<T> extends Option<T> { |
||||
/// Creates a SelectOption |
||||
SelectOption({ |
||||
required super.storage, |
||||
required super.key, |
||||
required super.label, |
||||
required super.defaultValue, |
||||
required this.values, |
||||
required final Map<T, LabelBuilder> values, |
||||
super.category, |
||||
super.enabled, |
||||
}) : super(stream: BehaviorSubject()) { |
||||
unawaited( |
||||
values.first.then((final vs) async { |
||||
final valueStr = storage.getString(key); |
||||
T? initialValue; |
||||
|
||||
if (valueStr != null) { |
||||
initialValue = _fromString(vs, valueStr); |
||||
} |
||||
stream.add(initialValue ?? defaultValue); |
||||
}), |
||||
); |
||||
} |
||||
}) : _values = values, |
||||
super(initialValue: _fromString(values, storage.getString(key))); |
||||
|
||||
/// Creates a SelectOption depending on the State of another [Option]. |
||||
SelectOption.depend({ |
||||
required super.storage, |
||||
required super.key, |
||||
required super.label, |
||||
required super.defaultValue, |
||||
required final Map<T, LabelBuilder> values, |
||||
required super.enabled, |
||||
super.category, |
||||
}) : _values = values, |
||||
super.depend(initialValue: _fromString(values, storage.getString(key))); |
||||
|
||||
T? _fromString(final Map<T, LabelBuilder> vs, final String? valueStr) { |
||||
final v = vs.keys.where((final e) => e.toString() == valueStr); |
||||
if (v.length == 1) { |
||||
return v.first; |
||||
static T? _fromString<T>(final Map<T, LabelBuilder> vs, final String? valueStr) { |
||||
if (valueStr == null) { |
||||
return null; |
||||
} |
||||
return null; |
||||
|
||||
return vs.keys.firstWhereOrNull((final e) => e.toString() == valueStr); |
||||
} |
||||
|
||||
final BehaviorSubject<Map<T, LabelBuilder>> values; |
||||
Map<T, LabelBuilder> _values; |
||||
|
||||
@override |
||||
Future set(final T value) { |
||||
stream.add(value); |
||||
return storage.setString(key, value.toString()); |
||||
set value(final T value) { |
||||
unawaited(storage.setString(key, value.toString())); |
||||
super.value = value; |
||||
} |
||||
|
||||
/// A collection of different values this can have. |
||||
/// |
||||
/// See: |
||||
/// * [value] for the currently selected one |
||||
Map<T, LabelBuilder> get values => _values; |
||||
|
||||
set values(final Map<T, LabelBuilder> newValues) { |
||||
if (_values == newValues) { |
||||
return; |
||||
} |
||||
_values = newValues; |
||||
notifyListeners(); |
||||
} |
||||
|
||||
@override |
||||
String? serialize() => value?.toString(); |
||||
|
||||
@override |
||||
Future<T?> deserialize(final dynamic data) async => _fromString(await values.first, data as String?); |
||||
T? deserialize(final dynamic data) => _fromString(_values, data as String?); |
||||
} |
||||
|
@ -1,25 +1,39 @@
|
||||
import 'dart:async'; |
||||
|
||||
import 'package:neon/src/settings/models/option.dart'; |
||||
import 'package:rxdart/rxdart.dart'; |
||||
|
||||
class ToggleOption extends Option<bool> { |
||||
/// Creates a ToggleOption |
||||
ToggleOption({ |
||||
required super.storage, |
||||
required super.key, |
||||
required super.label, |
||||
required super.defaultValue, |
||||
required final bool defaultValue, |
||||
super.category, |
||||
super.enabled, |
||||
}) : super(stream: BehaviorSubject.seeded(storage.getBool(key) ?? defaultValue)); |
||||
}) : super(defaultValue: storage.getBool(key) ?? defaultValue); |
||||
|
||||
/// Creates a ToggleOption depending on the State of another [Option]. |
||||
ToggleOption.depend({ |
||||
required super.storage, |
||||
required super.key, |
||||
required super.label, |
||||
required final bool defaultValue, |
||||
required super.enabled, |
||||
super.category, |
||||
}) : super.depend( |
||||
defaultValue: storage.getBool(key) ?? defaultValue, |
||||
); |
||||
|
||||
@override |
||||
Future set(final bool value) { |
||||
stream.add(value); |
||||
return storage.setBool(key, value); |
||||
set value(final bool value) { |
||||
unawaited(storage.setBool(key, value)); |
||||
super.value = value; |
||||
} |
||||
|
||||
@override |
||||
bool serialize() => value; |
||||
|
||||
@override |
||||
Future<bool?> deserialize(final dynamic data) async => data as bool; |
||||
bool deserialize(final dynamic data) => data as bool; |
||||
} |
||||
|
@ -1,24 +0,0 @@
|
||||
import 'package:flutter/widgets.dart'; |
||||
import 'package:neon/src/settings/models/option.dart'; |
||||
|
||||
typedef OptionBuilderFunction<T> = Widget Function(BuildContext context, T snapshot); |
||||
|
||||
class OptionBuilder<T> extends StreamBuilderBase<T, T> { |
||||
OptionBuilder({ |
||||
required this.option, |
||||
required this.builder, |
||||
super.key, |
||||
}) : super(stream: option.stream); |
||||
|
||||
final Option<T> option; |
||||
final OptionBuilderFunction<T> builder; |
||||
|
||||
@override |
||||
T afterData(final T current, final T data) => data; |
||||
|
||||
@override |
||||
T initial() => option.defaultValue; |
||||
|
||||
@override |
||||
Widget build(final BuildContext context, final T currentSummary) => builder(context, currentSummary); |
||||
} |
Loading…
Reference in new issue