Browse Source

Merge pull request #311 from Leptopoda/cleanup/theming

neon: cleanup theming
pull/310/head
Kate 2 years ago committed by GitHub
parent
commit
f22240a321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 68
      packages/neon/neon/lib/src/app.dart
  2. 4
      packages/neon/neon/lib/src/blocs/capabilities.dart
  3. 4
      packages/neon/neon/lib/src/pages/home.dart
  4. 3
      packages/neon/neon/lib/src/router.dart
  5. 32
      packages/neon/neon/lib/src/utils/theme.dart

68
packages/neon/neon/lib/src/app.dart

@ -28,24 +28,10 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
late final _routerDelegate = AppRouter( late final _routerDelegate = AppRouter(
navigatorKey: _navigatorKey, navigatorKey: _navigatorKey,
accountsBloc: _accountsBloc, accountsBloc: _accountsBloc,
onThemeChanged: (final nextcloudTheme) {
setState(() {
_nextcloudTheme = nextcloudTheme;
});
},
); );
NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? _nextcloudTheme;
final _platformBrightness = BehaviorSubject<Brightness>.seeded(WidgetsBinding.instance.window.platformBrightness);
Rect? _lastBounds; Rect? _lastBounds;
@override
void didChangePlatformBrightness() {
_platformBrightness.add(WidgetsBinding.instance.window.platformBrightness);
super.didChangePlatformBrightness();
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -260,42 +246,46 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
if (_platform.canUseWindowManager) { if (_platform.canUseWindowManager) {
windowManager.removeListener(this); windowManager.removeListener(this);
} }
unawaited(_platformBrightness.close());
super.dispose(); super.dispose();
} }
@override @override
Widget build(final BuildContext context) => StreamBuilder<Brightness>( Widget build(final BuildContext context) => OptionBuilder(
stream: _platformBrightness, option: widget.globalOptions.themeMode,
builder: (final context, final platformBrightnessSnapshot) => OptionBuilder( builder: (final context, final themeMode) => OptionBuilder(
option: widget.globalOptions.themeMode, option: widget.globalOptions.themeOLEDAsDark,
builder: (final context, final themeMode) => OptionBuilder( builder: (final context, final themeOLEDAsDark) => OptionBuilder(
option: widget.globalOptions.themeOLEDAsDark, option: widget.globalOptions.themeKeepOriginalAccentColor,
builder: (final context, final themeOLEDAsDark) => OptionBuilder( builder: (final context, final themeKeepOriginalAccentColor) => StreamBuilder<Account?>(
option: widget.globalOptions.themeKeepOriginalAccentColor, stream: widget.accountsBloc.activeAccount,
builder: (final context, final themeKeepOriginalAccentColor) => StreamBuilder<Account?>( builder: (final context, final activeAccountSnapshot) {
stream: widget.accountsBloc.activeAccount, if (themeMode == null || themeOLEDAsDark == null) {
builder: (final context, final activeAccountSnapshot) { return Container();
if (themeMode == null || !platformBrightnessSnapshot.hasData || themeOLEDAsDark == null) { }
return Container();
} FlutterNativeSplash.remove();
return ValueListenableBuilder(
FlutterNativeSplash.remove(); valueListenable: themeNotifier,
return MaterialApp.router( builder: (final context, final nextcloudTheme, final child) => MaterialApp.router(
localizationsDelegates: AppLocalizations.localizationsDelegates, localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales, supportedLocales: AppLocalizations.supportedLocales,
themeMode: themeMode,
theme: getThemeFromNextcloudTheme( theme: getThemeFromNextcloudTheme(
_nextcloudTheme, nextcloudTheme,
themeMode, Brightness.light,
platformBrightnessSnapshot.data!, keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false),
),
darkTheme: getThemeFromNextcloudTheme(
nextcloudTheme,
Brightness.dark,
keepOriginalAccentColor: nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false),
oledAsDark: themeOLEDAsDark, oledAsDark: themeOLEDAsDark,
keepOriginalAccentColor: _nextcloudTheme == null || (themeKeepOriginalAccentColor ?? false),
), ),
routerDelegate: _routerDelegate, routerDelegate: _routerDelegate,
); ),
}, );
), },
), ),
), ),
), ),

4
packages/neon/neon/lib/src/blocs/capabilities.dart

@ -14,6 +14,10 @@ class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents
this._requestManager, this._requestManager,
this._client, this._client,
) { ) {
capabilities.listen((final value) {
themeNotifier.value = value.data!.capabilities.theming;
});
unawaited(refresh()); unawaited(refresh());
} }

4
packages/neon/neon/lib/src/pages/home.dart

@ -5,12 +5,10 @@ const kQuickBarWidth = kAvatarSize + 20;
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({ const HomePage({
required this.account, required this.account,
required this.onThemeChanged,
super.key, super.key,
}); });
final Account account; final Account account;
final Function(NextcloudTheme? theme) onThemeChanged;
@override @override
State<HomePage> createState() => _HomePageState(); State<HomePage> createState() => _HomePageState();
@ -48,8 +46,6 @@ class _HomePageState extends State<HomePage> {
_capabilitiesBloc.capabilities.listen((final result) async { _capabilitiesBloc.capabilities.listen((final result) async {
if (result.data != null) { if (result.data != null) {
widget.onThemeChanged(result.data!.capabilities.theming);
// ignore cached version and prevent duplicate dialogs // ignore cached version and prevent duplicate dialogs
if (result.cached) { if (result.cached) {
return; return;

3
packages/neon/neon/lib/src/router.dart

@ -5,11 +5,9 @@ class AppRouter extends RouterDelegate<Account> with ChangeNotifier, PopNavigato
AppRouter({ AppRouter({
required this.navigatorKey, required this.navigatorKey,
required this.accountsBloc, required this.accountsBloc,
required this.onThemeChanged,
}); });
final AccountsBloc accountsBloc; final AccountsBloc accountsBloc;
final Function(NextcloudTheme? theme) onThemeChanged;
final _globalPopups = const GlobalPopups(); final _globalPopups = const GlobalPopups();
@override @override
@ -41,7 +39,6 @@ class AppRouter extends RouterDelegate<Account> with ChangeNotifier, PopNavigato
HomePage( HomePage(
key: Key(currentConfiguration!.id), key: Key(currentConfiguration!.id),
account: currentConfiguration!, account: currentConfiguration!,
onThemeChanged: onThemeChanged,
), ),
], ],
), ),

32
packages/neon/neon/lib/src/utils/theme.dart

@ -1,34 +1,26 @@
part of '../../neon.dart'; part of '../../neon.dart';
final themeNotifier = ValueNotifier<NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming?>(null);
const themePrimaryColor = Color(0xFFF37736); const themePrimaryColor = Color(0xFFF37736);
ThemeData getThemeFromNextcloudTheme( ThemeData getThemeFromNextcloudTheme(
final NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? nextcloudTheme, final NextcloudCoreServerCapabilities_Ocs_Data_Capabilities_Theming? nextcloudTheme,
final ThemeMode themeMode, final Brightness brightness, {
final Brightness platformBrightness, {
required final bool oledAsDark,
required final bool keepOriginalAccentColor, required final bool keepOriginalAccentColor,
final bool oledAsDark = false,
}) { }) {
final primaryColor = nextcloudTheme?.color != null ? HexColor(nextcloudTheme!.color!) : themePrimaryColor; if (oledAsDark) {
assert(brightness == Brightness.dark, 'Brightness.dark is required for oledAsDark.');
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;
} }
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 keepOriginalAccentColorOverride = keepOriginalAccentColor ? primaryColor : null;
final colorScheme = ColorScheme.fromSeed( final colorScheme = ColorScheme.fromSeed(
seedColor: primaryColor, seedColor: primaryColor,
brightness: selectBrightness, brightness: brightness,
).copyWith( ).copyWith(
background: oledBackgroundOverride, background: oledBackgroundOverride,
primary: keepOriginalAccentColorOverride, primary: keepOriginalAccentColorOverride,
@ -37,7 +29,7 @@ ThemeData getThemeFromNextcloudTheme(
final fillColor = MaterialStateProperty.resolveWith((final states) { final fillColor = MaterialStateProperty.resolveWith((final states) {
if (states.contains(MaterialState.disabled)) { if (states.contains(MaterialState.disabled)) {
return selectBrightness == Brightness.dark ? Colors.white38 : Colors.black38; return brightness == Brightness.dark ? Colors.white38 : Colors.black38;
} }
return colorScheme.primary; return colorScheme.primary;
@ -62,7 +54,7 @@ ThemeData getThemeFromNextcloudTheme(
), ),
popupMenuTheme: PopupMenuThemeData( popupMenuTheme: PopupMenuThemeData(
// TODO: Only needed until M3 popup menus are implemented // TODO: Only needed until M3 popup menus are implemented
color: selectBrightness == Brightness.dark color: brightness == Brightness.dark
? oledAsDark ? oledAsDark
? const Color(0xFF202020) ? const Color(0xFF202020)
: const Color(0xFF404040) : const Color(0xFF404040)

Loading…
Cancel
Save