fix(ui): theme toggle is now actually reactive
The toggle changed _mode and called setState on StudioAppState, but the sidebar that hosts the toggle button never rebuilt: StudioApp returns `MaterialApp(home: const StudioShell())`, and the const child's element doesn't get a didUpdateWidget on parent rebuild. So the toggle's icon would only flip on the next health-poll tick (up to 5s later) when the sidebar's own setState fired for an unrelated reason. Switch to a ValueNotifier-based pattern: - StudioAppState exposes `modeNotifier` (ValueNotifier<...>) instead of a getter. - StudioApp wraps MaterialApp in a ValueListenableBuilder bound to the notifier so themeMode flips immediately. - _ThemeToggle is itself a ValueListenableBuilder against the same notifier — its icon and onPressed always reflect the current value without depending on parent rebuild timing. Bumps fai_studio 0.7.2 -> 0.7.3. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
20230684a9
commit
2f32023322
2 changed files with 54 additions and 37 deletions
|
|
@ -19,7 +19,7 @@ import 'widgets/widgets.dart';
|
|||
/// Studio's own build version. Bump on every UI commit so the
|
||||
/// running app self-identifies — visible in the sidebar header
|
||||
/// and quick-glance proof that you're seeing the current build.
|
||||
const String kStudioVersion = '0.7.2';
|
||||
const String kStudioVersion = '0.7.3';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
|
@ -45,23 +45,32 @@ class StudioApp extends StatefulWidget {
|
|||
}
|
||||
|
||||
class StudioAppState extends State<StudioApp> {
|
||||
late ThemeModeValue _mode;
|
||||
|
||||
ThemeModeValue get mode => _mode;
|
||||
/// Exposed so any descendant can listen via
|
||||
/// `ValueListenableBuilder` and rebuild instantly when the
|
||||
/// theme flips. setState alone wouldn't propagate through
|
||||
/// `MaterialApp(home: const StudioShell())` because the
|
||||
/// const child's element doesn't get a `didUpdateWidget`.
|
||||
late final ValueNotifier<ThemeModeValue> modeNotifier;
|
||||
|
||||
Future<void> setMode(ThemeModeValue m) async {
|
||||
setState(() => _mode = m);
|
||||
modeNotifier.value = m;
|
||||
await HubService.instance.saveThemeMode(m);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_mode = widget.initialThemeMode;
|
||||
modeNotifier = ValueNotifier(widget.initialThemeMode);
|
||||
}
|
||||
|
||||
ThemeMode _flutterMode() {
|
||||
switch (_mode) {
|
||||
@override
|
||||
void dispose() {
|
||||
modeNotifier.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
ThemeMode _flutterMode(ThemeModeValue v) {
|
||||
switch (v) {
|
||||
case ThemeModeValue.system:
|
||||
return ThemeMode.system;
|
||||
case ThemeModeValue.light:
|
||||
|
|
@ -73,13 +82,16 @@ class StudioAppState extends State<StudioApp> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
return ValueListenableBuilder<ThemeModeValue>(
|
||||
valueListenable: modeNotifier,
|
||||
builder: (_, mode, _) => MaterialApp(
|
||||
title: 'F∆I Studio',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: FaiTheme.light(),
|
||||
darkTheme: FaiTheme.dark(),
|
||||
themeMode: _flutterMode(),
|
||||
themeMode: _flutterMode(mode),
|
||||
home: const StudioShell(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -436,7 +448,10 @@ class _ThemeToggle extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final app = StudioApp.of(context);
|
||||
final mode = app?.mode ?? ThemeModeValue.system;
|
||||
if (app == null) return const SizedBox.shrink();
|
||||
return ValueListenableBuilder<ThemeModeValue>(
|
||||
valueListenable: app.modeNotifier,
|
||||
builder: (_, mode, _) {
|
||||
final icon = switch (mode) {
|
||||
ThemeModeValue.system => Icons.brightness_auto_outlined,
|
||||
ThemeModeValue.light => Icons.light_mode_outlined,
|
||||
|
|
@ -457,7 +472,9 @@ class _ThemeToggle extends StatelessWidget {
|
|||
ThemeModeValue.light => ThemeModeValue.dark,
|
||||
ThemeModeValue.dark => ThemeModeValue.system,
|
||||
};
|
||||
app?.setMode(next);
|
||||
app.setMode(next);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
name: fai_studio
|
||||
description: "F∆I Studio — desktop GUI for the F∆I hub"
|
||||
publish_to: 'none'
|
||||
version: 0.7.2
|
||||
version: 0.7.3
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.0-200.1.beta
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue