|
1 | 1 | import "package:flutter/material.dart"; |
2 | 2 | import "package:flutter_riverpod/flutter_riverpod.dart"; |
| 3 | +import "package:freezed_annotation/freezed_annotation.dart"; |
3 | 4 |
|
4 | 5 | import "../../project_configs_provider.dart"; |
5 | 6 | import "advanced_editor.dart"; |
6 | 7 | import "models/base.dart"; |
7 | 8 | import "views/base.dart"; |
8 | 9 |
|
9 | | -class AdvancedModeNotifier extends Notifier<bool> { |
| 10 | +part "config_gui.freezed.dart"; |
| 11 | + |
| 12 | +@freezed |
| 13 | +sealed class AdvancedMode with _$AdvancedMode { |
| 14 | + // The function name and lack of other parameters makes it clear enough |
| 15 | + // ignore: avoid_positional_boolean_parameters |
| 16 | + const factory AdvancedMode.data(bool value) = AdvancedModeData; |
| 17 | + |
| 18 | + const factory AdvancedMode.loading() = AdvancedModeLoading; |
| 19 | +} |
| 20 | + |
| 21 | +class AdvancedModeNotifier extends Notifier<AdvancedMode> { |
10 | 22 | @override |
11 | | - bool build() { |
12 | | - return false; |
| 23 | + AdvancedMode build() { |
| 24 | + return const .data(false); |
13 | 25 | } |
14 | 26 |
|
15 | 27 | // The function name and lack of other parameters makes it clear enough |
16 | | - // ignore: avoid_positional_boolean_parameters, use_setters_to_change_properties |
| 28 | + // ignore: avoid_positional_boolean_parameters |
17 | 29 | void set(bool newState) { |
18 | | - state = newState; |
| 30 | + if (newState) { |
| 31 | + // advanced mode was just enabled; that goes instantly |
| 32 | + state = .data(newState); |
| 33 | + } else { |
| 34 | + // advanced mode was just disabled, so we need to re-read the file into the models again |
| 35 | + state = const .loading(); |
| 36 | + // wait a frame for the file to be properly saved on dispose of the advanced editor |
| 37 | + // this cannot be called there, because it's not allowed to red.read in a dispose() |
| 38 | + WidgetsBinding.instance.addPostFrameCallback((_) async { |
| 39 | + final ConfigFile openConfig = ref.read(openConfigProvider)!; |
| 40 | + await ref.read(projectProviderNotifier).refreshConfigFile(openConfig.file); |
| 41 | + state = .data(newState); |
| 42 | + }); |
| 43 | + } |
19 | 44 | } |
20 | 45 | } |
21 | 46 |
|
22 | | -// I don't want these for providers; too long |
23 | | -// ignore: specify_nonobvious_property_types |
24 | | -final advancedModeProvider = NotifierProvider(AdvancedModeNotifier.new); |
25 | | - |
26 | | -class ConfigGUI extends ConsumerStatefulWidget { |
| 47 | +class ConfigGUI extends ConsumerWidget { |
27 | 48 | const ConfigGUI({super.key}); |
28 | 49 |
|
29 | 50 | @override |
30 | | - ConsumerState<ConfigGUI> createState() => _ConfigGUIState(); |
31 | | -} |
32 | | - |
33 | | -class _ConfigGUIState extends ConsumerState<ConfigGUI> { |
34 | | - bool loading = false; |
35 | | - |
36 | | - @override |
37 | | - Widget build(BuildContext context) { |
| 51 | + Widget build(BuildContext context, WidgetRef ref) { |
38 | 52 | final ConfigFile openConfig = ref.watch(openConfigProvider)!; |
39 | | - final bool advancedMode = ref.watch(advancedModeProvider); |
| 53 | + final AdvancedMode advancedMode = ref.watch(advancedModeProvider); |
40 | 54 |
|
41 | 55 | return Stack( |
42 | 56 | children: [ |
43 | | - if (loading) |
44 | | - const Center(child: CircularProgressIndicator()) |
45 | | - else if (advancedMode) |
46 | | - AdvancedEditor(openConfig) |
47 | | - else |
48 | | - BaseConfigView(openConfig), |
49 | | - Align( |
50 | | - alignment: .topRight, |
51 | | - child: Padding( |
52 | | - padding: const EdgeInsets.only(right: 12, top: 8), |
53 | | - child: Row( |
54 | | - mainAxisSize: .min, |
55 | | - children: [ |
56 | | - Text( |
57 | | - "Advanced Mode", |
58 | | - style: TextStyle( |
59 | | - color: advancedMode |
60 | | - ? Colors.white |
61 | | - : TextTheme.of(context).bodyLarge?.color, |
62 | | - ), |
63 | | - ), |
64 | | - Switch( |
65 | | - value: advancedMode, |
66 | | - onChanged: loading |
67 | | - ? null |
68 | | - : (bool justSwitchedToAdvancedMode) async { |
69 | | - ref |
70 | | - .read(advancedModeProvider.notifier) |
71 | | - .set(justSwitchedToAdvancedMode); |
72 | | - setState(() { |
73 | | - if (!justSwitchedToAdvancedMode) loading = true; |
74 | | - }); |
| 57 | + advancedMode.when( |
| 58 | + data: (val) => val ? AdvancedEditor(openConfig) : BaseConfigView(openConfig), |
| 59 | + loading: () => const Center(child: CircularProgressIndicator()), |
| 60 | + ), |
| 61 | + const AdvancedModeToggle(), |
| 62 | + ], |
| 63 | + ); |
| 64 | + } |
| 65 | +} |
75 | 66 |
|
76 | | - // advanced mode was just disabled, so we need to re-read the file into the models again |
77 | | - if (!justSwitchedToAdvancedMode) { |
78 | | - //wait a frame for the file to be properly saved on dispose of the advanced editor |
79 | | - //this cannot be called there, because it's not allowed to red.read in a dispose() |
80 | | - WidgetsBinding.instance.addPostFrameCallback((_) async { |
81 | | - await ref |
82 | | - .read(projectProviderNotifier) |
83 | | - .refreshConfigFile(openConfig.file); |
84 | | - setState(() => loading = false); |
85 | | - }); |
86 | | - } |
87 | | - }, |
88 | | - ), |
89 | | - ], |
| 67 | +// I don't want these for providers; too long |
| 68 | +// ignore: specify_nonobvious_property_types |
| 69 | +final advancedModeProvider = NotifierProvider(AdvancedModeNotifier.new); |
| 70 | + |
| 71 | +class AdvancedModeToggle extends ConsumerWidget { |
| 72 | + const AdvancedModeToggle({super.key}); |
| 73 | + |
| 74 | + @override |
| 75 | + Widget build(BuildContext context, WidgetRef ref) { |
| 76 | + final AdvancedMode advancedMode = ref.watch(advancedModeProvider); |
| 77 | + final bool enabled = advancedMode.when(data: (value) => value, loading: () => true); |
| 78 | + final bool loading = advancedMode is AdvancedModeLoading; |
| 79 | + |
| 80 | + return Align( |
| 81 | + alignment: .topRight, |
| 82 | + child: Padding( |
| 83 | + padding: const EdgeInsets.only(right: 12, top: 8), |
| 84 | + child: Row( |
| 85 | + mainAxisSize: .min, |
| 86 | + children: [ |
| 87 | + Text( |
| 88 | + "Advanced Mode", |
| 89 | + style: TextStyle( |
| 90 | + color: enabled ? Colors.white : TextTheme.of(context).bodyLarge?.color, |
| 91 | + ), |
| 92 | + ), |
| 93 | + Switch( |
| 94 | + value: enabled, |
| 95 | + onChanged: loading |
| 96 | + ? null |
| 97 | + : (bool justSwitchedToAdvancedMode) => ref |
| 98 | + .read(advancedModeProvider.notifier) |
| 99 | + .set(justSwitchedToAdvancedMode), |
90 | 100 | ), |
91 | | - ), |
| 101 | + ], |
92 | 102 | ), |
93 | | - ], |
| 103 | + ), |
94 | 104 | ); |
95 | 105 | } |
96 | 106 | } |
0 commit comments