diff --git a/lib/main.dart b/lib/main.dart index 791774f..07adef5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:animated_theme_switcher/animated_theme_switcher.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:whispering_pages/api/server_provider.dart'; @@ -36,14 +37,16 @@ class MyApp extends ConsumerWidget { routerConfig.goNamed(Routes.onboarding.name); } - return MaterialApp.router( - debugShowCheckedModeBanner: false, - theme: lightTheme, - darkTheme: darkTheme, - themeMode: ref.watch(appSettingsProvider).isDarkMode - ? ThemeMode.dark - : ThemeMode.light, - routerConfig: routerConfig, + return ThemeProvider( + initTheme: + ref.read(appSettingsProvider).isDarkMode ? darkTheme : lightTheme, + builder: (context, myTheme) { + return MaterialApp.router( + debugShowCheckedModeBanner: false, + routerConfig: routerConfig, + theme: myTheme, + ); + }, ); } } diff --git a/lib/pages/app_settings.dart b/lib/pages/app_settings.dart index c7699ee..cce14f1 100644 --- a/lib/pages/app_settings.dart +++ b/lib/pages/app_settings.dart @@ -1,3 +1,4 @@ +import 'package:animated_theme_switcher/animated_theme_switcher.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_settings_ui/flutter_settings_ui.dart'; @@ -5,6 +6,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:whispering_pages/api/authenticated_user_provider.dart'; import 'package:whispering_pages/api/server_provider.dart'; import 'package:whispering_pages/settings/app_settings_provider.dart'; +import 'package:whispering_pages/theme/theme.dart'; class AppSettingsPage extends HookConsumerWidget { const AppSettingsPage({ @@ -20,45 +22,120 @@ class AppSettingsPage extends HookConsumerWidget { final serverURIController = useTextEditingController(); final formKey = GlobalKey(); - return Scaffold( - appBar: AppBar( - title: const Text('App Settings'), - ), - body: SettingsList( - sections: [ - SettingsSection( - title: const Text('Appearance'), - tiles: [ - SettingsTile.switchTile( - initialValue: appSettings.isDarkMode, - title: const Text('Dark Mode'), - description: const Text('we all know dark mode is better'), - leading: appSettings.isDarkMode - ? const Icon(Icons.dark_mode) - : const Icon(Icons.light_mode), - onToggle: (value) { - ref.read(appSettingsProvider.notifier).toggleDarkMode(); - }, - ), - SettingsTile.switchTile( - initialValue: appSettings.useMaterialThemeOnItemPage, - title: const Text('Use Material Theming on Item Page'), - description: const Text( - 'get fancy with the colors on the item page at the cost of some performance', + return ThemeSwitchingArea( + child: Builder( + builder: (context) { + return Scaffold( + appBar: AppBar( + title: const Text('App Settings'), + ), + body: SettingsList( + sections: [ + SettingsSection( + title: const Text('Appearance'), + tiles: [ + ThemeSwitcherTile( + initialValue: appSettings.isDarkMode, + title: const Text('Dark Mode'), + description: + const Text('we all know dark mode is better'), + leading: (appSettings.isDarkMode + ? const Icon(Icons.dark_mode) + : const Icon(Icons.light_mode)), + onToggle: (value, context) { + ThemeSwitcher.of(context) + .changeTheme(theme: value ? darkTheme : lightTheme); + ref.read(appSettingsProvider.notifier).toggleDarkMode(); + }, + ), + SettingsTile.switchTile( + initialValue: appSettings.useMaterialThemeOnItemPage, + title: const Text('Use Material Theming on Item Page'), + description: const Text( + 'get fancy with the colors on the item page at the cost of some performance', + ), + leading: const Icon(Icons.dynamic_form_outlined), + onToggle: (value) { + ref.read(appSettingsProvider.notifier).updateState( + appSettings.copyWith( + useMaterialThemeOnItemPage: value, + ), + ); + }, + ), + ], ), - leading: const Icon(Icons.dynamic_form_outlined), - onToggle: (value) { - ref.read(appSettingsProvider.notifier).updateState( - appSettings.copyWith( - useMaterialThemeOnItemPage: value, - ), - ); - }, - ), - ], - ), - ], + ], + ), + ); + }, ), ); } } + +// a custom settings tile that extends AbstractSettingsTile but also returns ThemeSwitcher +// so we can switch themes by using the switch tile ans ThemeSwitcher.of(context).changeTheme() +// it is nothing but a wrapper around the switch tile so the type is settings tile but also contains a theme switcher +class ThemeSwitcherTile extends AbstractSettingsTile { + ThemeSwitcherTile({ + required this.initialValue, + required this.onToggle, + this.descriptionInlineIos = false, + this.activeSwitchColor, + this.leading, + this.trailing, + required this.title, + this.description, + this.onPressed, + this.enabled = true, + this.backgroundColor, + super.key, + }) { + value = null; + tileType = SettingsTileType.switchTile; + } + + final Widget? leading; + + final Widget? trailing; + + final Widget title; + + final Widget? description; + + final bool descriptionInlineIos; + + final Color? backgroundColor; + + final Function(BuildContext context)? onPressed; + + late final Color? activeSwitchColor; + late final Widget? value; + late final Function(bool value, BuildContext context)? onToggle; + late final SettingsTileType tileType; + late final bool? initialValue; + late final bool enabled; + + @override + Widget build(BuildContext context) { + return ThemeSwitcher( + builder: (context) { + return SettingsTile.switchTile( + initialValue: initialValue, + title: title, + description: description, + descriptionInlineIos: descriptionInlineIos, + leading: leading, + trailing: trailing, + onToggle: (value) { + onToggle?.call(value, context); + }, + onPressed: onPressed, + enabled: enabled, + backgroundColor: backgroundColor, + ); + }, + ); + } +}