Skip to content

Commit 5749675

Browse files
committed
Split the Advanced Mode toggle into its own widget
1 parent 4117baf commit 5749675

4 files changed

Lines changed: 354 additions & 68 deletions

File tree

build.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ targets:
1515
generate_for:
1616
- lib/project_configs_provider.dart
1717
- lib/project_view/configs/models/*.dart
18+
- lib/project_view/configs/config_gui.dart
Lines changed: 77 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,106 @@
11
import "package:flutter/material.dart";
22
import "package:flutter_riverpod/flutter_riverpod.dart";
3+
import "package:freezed_annotation/freezed_annotation.dart";
34

45
import "../../project_configs_provider.dart";
56
import "advanced_editor.dart";
67
import "models/base.dart";
78
import "views/base.dart";
89

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> {
1022
@override
11-
bool build() {
12-
return false;
23+
AdvancedMode build() {
24+
return const .data(false);
1325
}
1426

1527
// 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
1729
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+
}
1944
}
2045
}
2146

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 {
2748
const ConfigGUI({super.key});
2849

2950
@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) {
3852
final ConfigFile openConfig = ref.watch(openConfigProvider)!;
39-
final bool advancedMode = ref.watch(advancedModeProvider);
53+
final AdvancedMode advancedMode = ref.watch(advancedModeProvider);
4054

4155
return Stack(
4256
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+
}
7566

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),
90100
),
91-
),
101+
],
92102
),
93-
],
103+
),
94104
);
95105
}
96106
}

0 commit comments

Comments
 (0)