From 47e0d0de1fb337475726de8504433939c31e5ec2 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 27 Jun 2023 18:54:47 +0200 Subject: [PATCH 1/3] neon, settings: improve nullability of OptionBuilder --- packages/neon/neon/lib/src/app.dart | 8 ++--- .../neon/lib/src/utils/sort_box_builder.dart | 10 +++---- .../src/widgets/checkbox_settings_tile.dart | 30 +++++++++---------- .../lib/src/widgets/option_builder.dart | 25 ++++++++-------- 4 files changed, 33 insertions(+), 40 deletions(-) diff --git a/packages/neon/neon/lib/src/app.dart b/packages/neon/neon/lib/src/app.dart index e82bcf19..36073816 100644 --- a/packages/neon/neon/lib/src/app.dart +++ b/packages/neon/neon/lib/src/app.dart @@ -254,10 +254,6 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra builder: (final context, final themeKeepOriginalAccentColor) => StreamBuilder( stream: _accountsBloc.activeAccount, builder: (final context, final activeAccountSnapshot) { - if (themeMode == null || themeOLEDAsDark == null) { - return Container(); - } - FlutterNativeSplash.remove(); return ResultBuilder.behaviorSubject( stream: activeAccountSnapshot.hasData @@ -280,12 +276,12 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra theme: getThemeFromNextcloudTheme( nextcloudTheme, Brightness.light, - keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + keepOriginalAccentColor: nextcloudTheme == null || themeKeepOriginalAccentColor, ), darkTheme: getThemeFromNextcloudTheme( nextcloudTheme, Brightness.dark, - keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + keepOriginalAccentColor: nextcloudTheme == null || themeKeepOriginalAccentColor, oledAsDark: themeOLEDAsDark, ), routerConfig: _routerDelegate, diff --git a/packages/neon/neon/lib/src/utils/sort_box_builder.dart b/packages/neon/neon/lib/src/utils/sort_box_builder.dart index 8226219f..22c1ecc5 100644 --- a/packages/neon/neon/lib/src/utils/sort_box_builder.dart +++ b/packages/neon/neon/lib/src/utils/sort_box_builder.dart @@ -21,12 +21,10 @@ class SortBoxBuilder extends StatelessWidget { option: sortPropertyOption, builder: (final context, final property) => OptionBuilder( option: sortBoxOrderOption, - builder: (final context, final order) => property == null || order == null - ? Container() - : builder( - context, - input == null ? null : sortBox.sort(input!, Box(property, order)), - ), + builder: (final context, final order) => builder( + context, + input == null ? null : sortBox.sort(input!, Box(property, order)), + ), ), ); } diff --git a/packages/settings/lib/src/widgets/checkbox_settings_tile.dart b/packages/settings/lib/src/widgets/checkbox_settings_tile.dart index 72c99838..f4496d7e 100644 --- a/packages/settings/lib/src/widgets/checkbox_settings_tile.dart +++ b/packages/settings/lib/src/widgets/checkbox_settings_tile.dart @@ -9,21 +9,19 @@ class CheckBoxSettingsTile extends InputSettingsTile { @override Widget build(final BuildContext context) => OptionBuilder( option: option, - builder: (final context, final value) => value == null - ? Container() - : StreamBuilder( - stream: option.enabled, - builder: (final context, final enabledSnapshot) => !enabledSnapshot.hasData - ? Container() - : CheckboxListTile( - title: Text(option.label(context)), - value: value, - onChanged: enabledSnapshot.requireData - ? (final value) async { - await option.set(value!); - } - : null, - ), - ), + builder: (final context, final value) => StreamBuilder( + stream: option.enabled, + builder: (final context, final enabledSnapshot) => !enabledSnapshot.hasData + ? Container() + : CheckboxListTile( + title: Text(option.label(context)), + value: value, + onChanged: enabledSnapshot.requireData + ? (final value) async { + await option.set(value!); + } + : null, + ), + ), ); } diff --git a/packages/settings/lib/src/widgets/option_builder.dart b/packages/settings/lib/src/widgets/option_builder.dart index 605b6563..2e2e4039 100644 --- a/packages/settings/lib/src/widgets/option_builder.dart +++ b/packages/settings/lib/src/widgets/option_builder.dart @@ -1,22 +1,23 @@ part of '../../settings.dart'; -class OptionBuilder extends StatelessWidget { - const OptionBuilder({ +typedef OptionBuilderFunction = Widget Function(BuildContext context, T snapshot); + +class OptionBuilder extends StreamBuilderBase { + OptionBuilder({ required this.option, required this.builder, super.key, - }); + }) : super(stream: option.stream); final Option option; - final Widget Function(BuildContext context, T? data) builder; + final OptionBuilderFunction builder; + + @override + T afterData(final T current, final T data) => data; + + @override + T initial() => option.defaultValue; @override - Widget build(final BuildContext context) => StreamBuilder( - stream: option.stream, - initialData: option.defaultValue, - builder: (final context, final valueSnapshot) => builder( - context, - valueSnapshot.data, - ), - ); + Widget build(final BuildContext context, final T currentSummary) => builder(context, currentSummary); } From 71bcae8eccc6245822423175f57f2e68af1d17ff Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 27 Jun 2023 18:54:48 +0200 Subject: [PATCH 2/3] settings: make option immutable --- packages/settings/lib/src/options/option.dart | 4 +++- packages/settings/lib/src/options/select_option.dart | 3 +-- packages/settings/lib/src/options/toggle_option.dart | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/settings/lib/src/options/option.dart b/packages/settings/lib/src/options/option.dart index 14023de1..63be2b00 100644 --- a/packages/settings/lib/src/options/option.dart +++ b/packages/settings/lib/src/options/option.dart @@ -2,12 +2,14 @@ part of '../../settings.dart'; class OptionDisableException implements Exception {} +@immutable abstract class Option { Option({ required this.storage, required this.key, required this.label, required this.defaultValue, + required this.stream, this.category, final BehaviorSubject? enabled, }) : enabled = enabled ?? BehaviorSubject.seeded(true); @@ -18,8 +20,8 @@ abstract class Option { final T defaultValue; final OptionsCategory? category; final BehaviorSubject enabled; + final BehaviorSubject stream; - late BehaviorSubject stream; T get value { if (hasValue) { return stream.value; diff --git a/packages/settings/lib/src/options/select_option.dart b/packages/settings/lib/src/options/select_option.dart index 99d07a63..126307d9 100644 --- a/packages/settings/lib/src/options/select_option.dart +++ b/packages/settings/lib/src/options/select_option.dart @@ -9,8 +9,7 @@ class SelectOption extends Option { required this.values, super.category, super.enabled, - }) { - stream = BehaviorSubject(); + }) : super(stream: BehaviorSubject()) { unawaited( values.first.then((final vs) async { final valueStr = storage.getString(key); diff --git a/packages/settings/lib/src/options/toggle_option.dart b/packages/settings/lib/src/options/toggle_option.dart index c1c6fa6e..1e47d2b8 100644 --- a/packages/settings/lib/src/options/toggle_option.dart +++ b/packages/settings/lib/src/options/toggle_option.dart @@ -8,9 +8,7 @@ class ToggleOption extends Option { required super.defaultValue, super.category, super.enabled, - }) { - stream = BehaviorSubject.seeded(storage.getBool(key) ?? defaultValue); - } + }) : super(stream: BehaviorSubject.seeded(storage.getBool(key) ?? defaultValue)); @override Future set(final bool value) { From d5ac8bee1ee970acc4f1127131ff5e9b3e62e116 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 27 Jun 2023 18:54:48 +0200 Subject: [PATCH 3/3] neon: cleanup SortBoxBuilder --- .../neon/lib/src/utils/sort_box_builder.dart | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/neon/neon/lib/src/utils/sort_box_builder.dart b/packages/neon/neon/lib/src/utils/sort_box_builder.dart index 22c1ecc5..b9d96efc 100644 --- a/packages/neon/neon/lib/src/utils/sort_box_builder.dart +++ b/packages/neon/neon/lib/src/utils/sort_box_builder.dart @@ -17,14 +17,21 @@ class SortBoxBuilder extends StatelessWidget { final Widget Function(BuildContext, List?) builder; @override - Widget build(final BuildContext context) => OptionBuilder( - option: sortPropertyOption, - builder: (final context, final property) => OptionBuilder( - option: sortBoxOrderOption, - builder: (final context, final order) => builder( - context, - input == null ? null : sortBox.sort(input!, Box(property, order)), - ), - ), - ); + Widget build(final BuildContext context) { + if (input == null || (input?.isEmpty ?? false)) { + return builder(context, null); + } + + return OptionBuilder( + option: sortPropertyOption, + builder: (final context, final property) => OptionBuilder( + option: sortBoxOrderOption, + builder: (final context, final order) { + final box = Box(property, order); + + return builder(context, sortBox.sort(input!, box)); + }, + ), + ); + } }