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