From cc4a05bf11788a109f9ce991830406bd43ca0796 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Thu, 21 Sep 2023 19:24:05 +0800 Subject: [PATCH] new: `rebuild` impl --- lib/app.dart | 9 ++++--- lib/core/extension/context/snackbar.dart | 9 ------- lib/core/utils/rebuild.dart | 33 ++++++++++++++++++++++++ lib/main.dart | 5 +--- lib/view/page/backup.dart | 3 ++- lib/view/page/setting/entry.dart | 20 +++++++------- lib/view/widget/rebuild.dart | 32 ----------------------- 7 files changed, 51 insertions(+), 60 deletions(-) create mode 100644 lib/core/utils/rebuild.dart delete mode 100644 lib/view/widget/rebuild.dart diff --git a/lib/app.dart b/lib/app.dart index d699ff06..0b25ad9a 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/locale.dart'; +import 'package:toolbox/core/utils/rebuild.dart'; import 'package:toolbox/data/res/store.dart'; +import 'package:toolbox/view/widget/value_notifier.dart'; import 'core/utils/ui.dart'; import 'data/res/build_data.dart'; @@ -33,9 +35,10 @@ class MyApp extends StatelessWidget { } Widget _wrapTheme(BuildContext context) { - return ValueListenableBuilder( - valueListenable: Stores.setting.themeMode.listenable(), - builder: (_, tMode, __) { + return ValueBuilder( + listenable: RebuildNodes.app, + build: () { + final tMode = Stores.setting.themeMode.fetch(); final isAMOLED = tMode >= 0 && tMode <= ThemeMode.values.length - 1; // Issue #57 // if not [ok] -> [AMOLED] mode, use [ThemeMode.dark] diff --git a/lib/core/extension/context/snackbar.dart b/lib/core/extension/context/snackbar.dart index e207e0f7..b77bd994 100644 --- a/lib/core/extension/context/snackbar.dart +++ b/lib/core/extension/context/snackbar.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:toolbox/view/widget/rebuild.dart'; extension SnackBarX on BuildContext { void showSnackBar(String text) => @@ -22,12 +21,4 @@ extension SnackBarX on BuildContext { ), )); } - - void showRestartSnackbar({String? btn, String? msg}) { - showSnackBarWithAction( - msg ?? 'Need restart to take effect', - btn ?? 'Restart', - () => RebuildWidget.restartApp(this), - ); - } } diff --git a/lib/core/utils/rebuild.dart b/lib/core/utils/rebuild.dart new file mode 100644 index 00000000..ae5fe931 --- /dev/null +++ b/lib/core/utils/rebuild.dart @@ -0,0 +1,33 @@ +import 'package:flutter/foundation.dart'; + +// ignore: prefer_void_to_null +class _RebuildNode implements ValueListenable { + final List _listeners = []; + + _RebuildNode(); + + @override + void addListener(VoidCallback listener) { + _listeners.add(listener); + } + + @override + void removeListener(VoidCallback listener) { + _listeners.remove(listener); + } + + void rebuild() { + for (var listener in _listeners) { + listener(); + } + } + + @override + Null get value => null; +} + +class RebuildNodes { + const RebuildNodes._(); + + static final _RebuildNode app = _RebuildNode(); +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index fb79ccbf..efda26b8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,7 +31,6 @@ import 'data/provider/virtual_keyboard.dart'; import 'data/res/color.dart'; import 'locator.dart'; import 'view/widget/custom_appbar.dart'; -import 'view/widget/rebuild.dart'; Future main() async { _runInZone(() async { @@ -48,9 +47,7 @@ Future main() async { ChangeNotifierProvider(create: (_) => locator()), ChangeNotifierProvider(create: (_) => locator()), ], - child: const RebuildWidget( - child: MyApp(), - ), + child: const MyApp(), ), ); }); diff --git a/lib/view/page/backup.dart b/lib/view/page/backup.dart index 092f66c7..a51be93f 100644 --- a/lib/view/page/backup.dart +++ b/lib/view/page/backup.dart @@ -8,6 +8,7 @@ import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/utils/platform/base.dart'; +import 'package:toolbox/core/utils/rebuild.dart'; import 'package:toolbox/data/model/app/backup.dart'; import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/path.dart'; @@ -156,7 +157,7 @@ class BackupPage extends StatelessWidget { onPressed: () async { backup.restore(); context.pop(); - context.showRestartSnackbar(btn: s.restart, msg: s.needRestart); + RebuildNodes.app.rebuild(); }, child: Text(s.ok), ), diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 60e11923..77df3def 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -12,6 +12,7 @@ import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/utils/platform/auth.dart'; import 'package:toolbox/core/utils/platform/base.dart'; +import 'package:toolbox/core/utils/rebuild.dart'; import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/store.dart'; @@ -372,7 +373,7 @@ class _SettingPageState extends State { _setting.primaryColor.put(_selectedColorValue.value); primaryColor = color; context.pop(); - context.showRestartSnackbar(btn: _s.restart, msg: _s.needRestart); + RebuildNodes.app.rebuild(); } // Widget _buildLaunchPage() { @@ -484,6 +485,8 @@ class _SettingPageState extends State { onSelected: (int idx) { _nightMode.value = idx; _setting.themeMode.put(_nightMode.value); + + RebuildNodes.app.rebuild(); }, child: Text( _buildThemeModeStr(_nightMode.value), @@ -527,10 +530,7 @@ class _SettingPageState extends State { onPressed: () { _setting.fontPath.delete(); context.pop(); - context.showRestartSnackbar( - btn: _s.restart, - msg: _s.needRestart, - ); + RebuildNodes.app.rebuild(); }, child: Text(_s.clear), ) @@ -554,7 +554,7 @@ class _SettingPageState extends State { } context.pop(); - context.showRestartSnackbar(btn: _s.restart, msg: _s.needRestart); + RebuildNodes.app.rebuild(); return; } context.showSnackBar(_s.failed); @@ -634,7 +634,7 @@ class _SettingPageState extends State { onSelected: (String idx) { _localeCode.value = idx; _setting.locale.put(idx); - context.showRestartSnackbar(btn: _s.restart, msg: _s.needRestart); + RebuildNodes.app.rebuild(); }, child: Text( _s.languageName, @@ -724,10 +724,8 @@ class _SettingPageState extends State { title: Text(_s.fullScreen), trailing: StoreSwitch( prop: _setting.fullScreen, - func: (_) => context.showRestartSnackbar( - btn: _s.restart, - msg: _s.needRestart, - ), + func: (_) => + RebuildNodes.app.rebuild(), ), ); } diff --git a/lib/view/widget/rebuild.dart b/lib/view/widget/rebuild.dart deleted file mode 100644 index 0d96bd71..00000000 --- a/lib/view/widget/rebuild.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; - -class RebuildWidget extends StatefulWidget { - const RebuildWidget({super.key, required this.child}); - - final Widget child; - - static void restartApp(BuildContext context) { - context.findAncestorStateOfType<_RebuildWidgetState>()?.restartApp(); - } - - @override - _RebuildWidgetState createState() => _RebuildWidgetState(); -} - -class _RebuildWidgetState extends State { - Key key = UniqueKey(); - - void restartApp() { - setState(() { - key = UniqueKey(); - }); - } - - @override - Widget build(BuildContext context) { - return KeyedSubtree( - key: key, - child: widget.child, - ); - } -}