From 8d82c934579522215e7f5aa79922eaf85b4e08c5 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 11 May 2023 12:49:39 +0200 Subject: [PATCH 1/2] neon: cleanup theming let the MaterialApp decide wich theme to use for a given brightness Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/src/app.dart | 71 ++++++++++----------- packages/neon/neon/lib/src/utils/theme.dart | 30 +++------ 2 files changed, 42 insertions(+), 59 deletions(-) diff --git a/packages/neon/neon/lib/src/app.dart b/packages/neon/neon/lib/src/app.dart index 83563284..68b5cdd5 100644 --- a/packages/neon/neon/lib/src/app.dart +++ b/packages/neon/neon/lib/src/app.dart @@ -36,16 +36,8 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra ); NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? _nextcloudTheme; - final _platformBrightness = BehaviorSubject.seeded(WidgetsBinding.instance.window.platformBrightness); Rect? _lastBounds; - @override - void didChangePlatformBrightness() { - _platformBrightness.add(WidgetsBinding.instance.window.platformBrightness); - - super.didChangePlatformBrightness(); - } - @override void initState() { super.initState(); @@ -260,42 +252,43 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra if (_platform.canUseWindowManager) { windowManager.removeListener(this); } - unawaited(_platformBrightness.close()); super.dispose(); } @override - Widget build(final BuildContext context) => StreamBuilder( - stream: _platformBrightness, - builder: (final context, final platformBrightnessSnapshot) => OptionBuilder( - option: widget.globalOptions.themeMode, - builder: (final context, final themeMode) => OptionBuilder( - option: widget.globalOptions.themeOLEDAsDark, - builder: (final context, final themeOLEDAsDark) => OptionBuilder( - option: widget.globalOptions.themeKeepOriginalAccentColor, - builder: (final context, final themeKeepOriginalAccentColor) => StreamBuilder( - stream: widget.accountsBloc.activeAccount, - builder: (final context, final activeAccountSnapshot) { - if (themeMode == null || !platformBrightnessSnapshot.hasData || themeOLEDAsDark == null) { - return Container(); - } - - FlutterNativeSplash.remove(); - return MaterialApp.router( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - theme: getThemeFromNextcloudTheme( - _nextcloudTheme, - themeMode, - platformBrightnessSnapshot.data!, - oledAsDark: themeOLEDAsDark, - keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), - ), - routerDelegate: _routerDelegate, - ); - }, - ), + Widget build(final BuildContext context) => OptionBuilder( + option: widget.globalOptions.themeMode, + builder: (final context, final themeMode) => OptionBuilder( + option: widget.globalOptions.themeOLEDAsDark, + builder: (final context, final themeOLEDAsDark) => OptionBuilder( + option: widget.globalOptions.themeKeepOriginalAccentColor, + builder: (final context, final themeKeepOriginalAccentColor) => StreamBuilder( + stream: widget.accountsBloc.activeAccount, + builder: (final context, final activeAccountSnapshot) { + if (themeMode == null || themeOLEDAsDark == null) { + return Container(); + } + + FlutterNativeSplash.remove(); + return MaterialApp.router( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + themeMode: themeMode, + theme: getThemeFromNextcloudTheme( + _nextcloudTheme, + Brightness.light, + keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + ), + darkTheme: getThemeFromNextcloudTheme( + _nextcloudTheme, + Brightness.dark, + oledAsDark: themeOLEDAsDark, + keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + ), + routerDelegate: _routerDelegate, + ); + }, ), ), ), diff --git a/packages/neon/neon/lib/src/utils/theme.dart b/packages/neon/neon/lib/src/utils/theme.dart index 4c498042..d59f58c7 100644 --- a/packages/neon/neon/lib/src/utils/theme.dart +++ b/packages/neon/neon/lib/src/utils/theme.dart @@ -4,31 +4,21 @@ const themePrimaryColor = Color(0xFFF37736); ThemeData getThemeFromNextcloudTheme( final NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? nextcloudTheme, - final ThemeMode themeMode, - final Brightness platformBrightness, { - required final bool oledAsDark, + final Brightness brightness, { required final bool keepOriginalAccentColor, + final bool oledAsDark = false, }) { - final primaryColor = nextcloudTheme?.color != null ? HexColor(nextcloudTheme!.color!) : themePrimaryColor; - - late final Brightness selectBrightness; - switch (themeMode) { - case ThemeMode.system: - selectBrightness = platformBrightness; - break; - case ThemeMode.light: - selectBrightness = Brightness.light; - break; - case ThemeMode.dark: - selectBrightness = Brightness.dark; - break; + if (oledAsDark) { + assert(brightness == Brightness.dark, 'Brightness.dark is required for oledAsDark.'); } - final oledBackgroundOverride = selectBrightness == Brightness.dark && oledAsDark ? Colors.black : null; + final primaryColor = nextcloudTheme?.color != null ? HexColor(nextcloudTheme!.color!) : themePrimaryColor; + + final oledBackgroundOverride = oledAsDark ? Colors.black : null; final keepOriginalAccentColorOverride = keepOriginalAccentColor ? primaryColor : null; final colorScheme = ColorScheme.fromSeed( seedColor: primaryColor, - brightness: selectBrightness, + brightness: brightness, ).copyWith( background: oledBackgroundOverride, primary: keepOriginalAccentColorOverride, @@ -37,7 +27,7 @@ ThemeData getThemeFromNextcloudTheme( final fillColor = MaterialStateProperty.resolveWith((final states) { if (states.contains(MaterialState.disabled)) { - return selectBrightness == Brightness.dark ? Colors.white38 : Colors.black38; + return brightness == Brightness.dark ? Colors.white38 : Colors.black38; } return colorScheme.primary; @@ -62,7 +52,7 @@ ThemeData getThemeFromNextcloudTheme( ), popupMenuTheme: PopupMenuThemeData( // TODO: Only needed until M3 popup menus are implemented - color: selectBrightness == Brightness.dark + color: brightness == Brightness.dark ? oledAsDark ? const Color(0xFF202020) : const Color(0xFF404040) From 1e7ce247c902f2df7ab9126ac8bafe5167073759 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 11 May 2023 13:29:15 +0200 Subject: [PATCH 2/2] neon: cleanup changing of NextcloudTheme Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/src/app.dart | 39 +++++++++---------- .../neon/neon/lib/src/blocs/capabilities.dart | 4 ++ packages/neon/neon/lib/src/pages/home.dart | 4 -- packages/neon/neon/lib/src/router.dart | 3 -- packages/neon/neon/lib/src/utils/theme.dart | 2 + 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/packages/neon/neon/lib/src/app.dart b/packages/neon/neon/lib/src/app.dart index 68b5cdd5..cdd467f6 100644 --- a/packages/neon/neon/lib/src/app.dart +++ b/packages/neon/neon/lib/src/app.dart @@ -28,14 +28,8 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra late final _routerDelegate = AppRouter( navigatorKey: _navigatorKey, accountsBloc: _accountsBloc, - onThemeChanged: (final nextcloudTheme) { - setState(() { - _nextcloudTheme = nextcloudTheme; - }); - }, ); - NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? _nextcloudTheme; Rect? _lastBounds; @override @@ -271,22 +265,25 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra } FlutterNativeSplash.remove(); - return MaterialApp.router( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - themeMode: themeMode, - theme: getThemeFromNextcloudTheme( - _nextcloudTheme, - Brightness.light, - keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), - ), - darkTheme: getThemeFromNextcloudTheme( - _nextcloudTheme, - Brightness.dark, - oledAsDark: themeOLEDAsDark, - keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + return ValueListenableBuilder( + valueListenable: themeNotifier, + builder: (final context, final nextcloudTheme, final child) => MaterialApp.router( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + themeMode: themeMode, + theme: getThemeFromNextcloudTheme( + nextcloudTheme, + Brightness.light, + keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + ), + darkTheme: getThemeFromNextcloudTheme( + nextcloudTheme, + Brightness.dark, + keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false), + oledAsDark: themeOLEDAsDark, + ), + routerDelegate: _routerDelegate, ), - routerDelegate: _routerDelegate, ); }, ), diff --git a/packages/neon/neon/lib/src/blocs/capabilities.dart b/packages/neon/neon/lib/src/blocs/capabilities.dart index 04c7fcd1..de91d45c 100644 --- a/packages/neon/neon/lib/src/blocs/capabilities.dart +++ b/packages/neon/neon/lib/src/blocs/capabilities.dart @@ -14,6 +14,10 @@ class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents this._requestManager, this._client, ) { + capabilities.listen((final value) { + themeNotifier.value = value.data!.capabilities.theming; + }); + unawaited(refresh()); } diff --git a/packages/neon/neon/lib/src/pages/home.dart b/packages/neon/neon/lib/src/pages/home.dart index f3591072..d807df3a 100644 --- a/packages/neon/neon/lib/src/pages/home.dart +++ b/packages/neon/neon/lib/src/pages/home.dart @@ -5,12 +5,10 @@ const kQuickBarWidth = kAvatarSize + 20; class HomePage extends StatefulWidget { const HomePage({ required this.account, - required this.onThemeChanged, super.key, }); final Account account; - final Function(NextcloudTheme? theme) onThemeChanged; @override State createState() => _HomePageState(); @@ -48,8 +46,6 @@ class _HomePageState extends State { _capabilitiesBloc.capabilities.listen((final result) async { if (result.data != null) { - widget.onThemeChanged(result.data!.capabilities.theming); - // ignore cached version and prevent duplicate dialogs if (result.cached) { return; diff --git a/packages/neon/neon/lib/src/router.dart b/packages/neon/neon/lib/src/router.dart index 4e7ac622..e482c58f 100644 --- a/packages/neon/neon/lib/src/router.dart +++ b/packages/neon/neon/lib/src/router.dart @@ -5,11 +5,9 @@ class AppRouter extends RouterDelegate with ChangeNotifier, PopNavigato AppRouter({ required this.navigatorKey, required this.accountsBloc, - required this.onThemeChanged, }); final AccountsBloc accountsBloc; - final Function(NextcloudTheme? theme) onThemeChanged; final _globalPopups = const GlobalPopups(); @override @@ -41,7 +39,6 @@ class AppRouter extends RouterDelegate with ChangeNotifier, PopNavigato HomePage( key: Key(currentConfiguration!.id), account: currentConfiguration!, - onThemeChanged: onThemeChanged, ), ], ), diff --git a/packages/neon/neon/lib/src/utils/theme.dart b/packages/neon/neon/lib/src/utils/theme.dart index d59f58c7..0b0f174f 100644 --- a/packages/neon/neon/lib/src/utils/theme.dart +++ b/packages/neon/neon/lib/src/utils/theme.dart @@ -1,5 +1,7 @@ part of '../../neon.dart'; +final themeNotifier = ValueNotifier(null); + const themePrimaryColor = Color(0xFFF37736); ThemeData getThemeFromNextcloudTheme(