Browse Source

fix(neon): Separate Nextcloud and device theme to fix contrast problems

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/1064/head
jld3103 1 year ago
parent
commit
f93226b2ac
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 4
      packages/app/linux/flutter/generated_plugin_registrant.cc
  2. 1
      packages/app/linux/flutter/generated_plugins.cmake
  3. 8
      packages/app/pubspec.lock
  4. 79
      packages/neon/neon/lib/src/app.dart
  5. 57
      packages/neon/neon/lib/src/theme/theme.dart
  6. 3
      packages/neon/neon/pubspec.yaml

4
packages/app/linux/flutter/generated_plugin_registrant.cc

@ -6,6 +6,7 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever/screen_retriever_plugin.h>
#include <tray_manager/tray_manager_plugin.h> #include <tray_manager/tray_manager_plugin.h>
@ -13,6 +14,9 @@
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar); file_selector_plugin_register_with_registrar(file_selector_linux_registrar);

1
packages/app/linux/flutter/generated_plugins.cmake

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
file_selector_linux file_selector_linux
screen_retriever screen_retriever
tray_manager tray_manager

8
packages/app/pubspec.lock

@ -201,6 +201,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.3" version: "3.2.3"
dynamic_color:
dependency: transitive
description:
name: dynamic_color
sha256: "8b8bd1d798bd393e11eddeaa8ae95b12ff028bf7d5998fc5d003488cd5f4ce2f"
url: "https://pub.dev"
source: hosted
version: "1.6.8"
dynamite_runtime: dynamite_runtime:
dependency: "direct overridden" dependency: "direct overridden"
description: description:

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

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
@ -284,42 +285,48 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
} }
@override @override
Widget build(final BuildContext context) => OptionsCollectionBuilder( Widget build(final BuildContext context) => DynamicColorBuilder(
valueListenable: _globalOptions, builder: (final deviceThemeLight, final deviceThemeDark) => OptionsCollectionBuilder(
builder: (final context, final options, final _) => StreamBuilder<Account?>( valueListenable: _globalOptions,
stream: _accountsBloc.activeAccount, builder: (final context, final options, final _) => StreamBuilder<Account?>(
builder: (final context, final activeAccountSnapshot) { stream: _accountsBloc.activeAccount,
FlutterNativeSplash.remove(); builder: (final context, final activeAccountSnapshot) {
return ResultBuilder<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data?>.behaviorSubject( FlutterNativeSplash.remove();
subject: activeAccountSnapshot.hasData return ResultBuilder<core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data?>.behaviorSubject(
? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities subject: activeAccountSnapshot.hasData
: null, ? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities
builder: (final context, final capabilitiesSnapshot) { : null,
final appTheme = AppTheme( builder: (final context, final capabilitiesSnapshot) {
capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming, final appTheme = AppTheme(
useNextcloudTheme: options.themeUseNextcloudTheme.value, nextcloudTheme: capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming,
oledAsDark: options.themeOLEDAsDark.value, useNextcloudTheme: options.themeUseNextcloudTheme.value,
appThemes: _appImplementations.map((final a) => a.theme).whereNotNull(), deviceThemeLight: deviceThemeLight,
neonTheme: widget.neonTheme, deviceThemeDark: deviceThemeDark,
); oledAsDark: options.themeOLEDAsDark.value,
appThemes: _appImplementations.map((final a) => a.theme).whereNotNull(),
return MaterialApp.router( neonTheme: widget.neonTheme,
localizationsDelegates: [ );
..._appImplementations.map((final app) => app.localizationsDelegate),
...NeonLocalizations.localizationsDelegates, return MaterialApp.router(
], localizationsDelegates: [
supportedLocales: { ..._appImplementations.map((final app) => app.localizationsDelegate),
..._appImplementations.map((final app) => app.supportedLocales).expand((final element) => element), ...NeonLocalizations.localizationsDelegates,
...NeonLocalizations.supportedLocales, ],
}, supportedLocales: {
themeMode: options.themeMode.value, ..._appImplementations
theme: appTheme.lightTheme, .map((final app) => app.supportedLocales)
darkTheme: appTheme.darkTheme, .expand((final element) => element),
routerConfig: _routerDelegate, ...NeonLocalizations.supportedLocales,
); },
}, themeMode: options.themeMode.value,
); theme: appTheme.lightTheme,
}, darkTheme: appTheme.darkTheme,
routerConfig: _routerDelegate,
);
},
);
},
),
), ),
); );
} }

57
packages/neon/neon/lib/src/theme/theme.dart

@ -10,8 +10,10 @@ import 'package:nextcloud/core.dart' as core;
@immutable @immutable
class AppTheme { class AppTheme {
/// Creates a new Neon app theme. /// Creates a new Neon app theme.
const AppTheme( const AppTheme({
this.nextcloudTheme, { required this.nextcloudTheme,
required this.deviceThemeLight,
required this.deviceThemeDark,
required this.neonTheme, required this.neonTheme,
final bool useNextcloudTheme = false, final bool useNextcloudTheme = false,
this.oledAsDark = false, this.oledAsDark = false,
@ -24,6 +26,12 @@ class AppTheme {
/// Whether to use of the Nextcloud theme. /// Whether to use of the Nextcloud theme.
final bool useNextcloudTheme; final bool useNextcloudTheme;
/// The light theme provided by the device.
final ColorScheme? deviceThemeLight;
/// The dark theme provided by the device.
final ColorScheme? deviceThemeDark;
/// Whether to use [NcColors.oledBackground] in the dark theme. /// Whether to use [NcColors.oledBackground] in the dark theme.
final bool oledAsDark; final bool oledAsDark;
@ -34,19 +42,39 @@ class AppTheme {
final NeonTheme neonTheme; final NeonTheme neonTheme;
ColorScheme _buildColorScheme(final Brightness brightness) { ColorScheme _buildColorScheme(final Brightness brightness) {
final primaryColor = ColorScheme? colorScheme;
nextcloudTheme?.color != null ? HexColor(nextcloudTheme!.color) : neonTheme.colorScheme.primary;
final primaryColorOverride = useNextcloudTheme ? primaryColor : null; if (nextcloudTheme != null && useNextcloudTheme) {
final oledBackgroundOverride = oledAsDark && brightness == Brightness.dark ? NcColors.oledBackground : null; final primaryColor = HexColor(nextcloudTheme!.color);
final onPrimaryColor = HexColor(nextcloudTheme!.colorText);
return ColorScheme.fromSeed(
seedColor: primaryColor, colorScheme = ColorScheme.fromSeed(
seedColor: primaryColor,
brightness: brightness,
).copyWith(
primary: primaryColor,
onPrimary: onPrimaryColor,
secondary: primaryColor,
onSecondary: onPrimaryColor,
tertiary: primaryColor,
onTertiary: onPrimaryColor,
);
} else {
colorScheme = brightness == Brightness.dark ? deviceThemeDark : deviceThemeLight;
}
colorScheme ??= ColorScheme.fromSeed(
seedColor: NcColors.primary,
brightness: brightness, brightness: brightness,
).copyWith(
background: oledBackgroundOverride,
primary: primaryColorOverride,
secondary: primaryColorOverride,
); );
if (oledAsDark && brightness == Brightness.dark) {
colorScheme = colorScheme.copyWith(
background: NcColors.oledBackground,
);
}
return colorScheme;
} }
ThemeData _getTheme(final Brightness brightness) { ThemeData _getTheme(final Brightness brightness) {
@ -56,7 +84,8 @@ class AppTheme {
useMaterial3: true, useMaterial3: true,
colorScheme: colorScheme, colorScheme: colorScheme,
scaffoldBackgroundColor: colorScheme.background, scaffoldBackgroundColor: colorScheme.background,
cardColor: colorScheme.background, // For LicensePage cardColor: colorScheme.background,
// For LicensePage
snackBarTheme: _snackBarTheme, snackBarTheme: _snackBarTheme,
dividerTheme: _dividerTheme, dividerTheme: _dividerTheme,
scrollbarTheme: _scrollbarTheme, scrollbarTheme: _scrollbarTheme,

3
packages/neon/neon/pubspec.yaml

@ -9,6 +9,7 @@ environment:
dependencies: dependencies:
collection: ^1.0.0 collection: ^1.0.0
crypto: ^3.0.0 crypto: ^3.0.0
dynamic_color: ^1.0.0
file_picker: ^6.0.0 file_picker: ^6.0.0
filesize: ^2.0.0 filesize: ^2.0.0
flutter: flutter:
@ -66,7 +67,7 @@ dev_dependencies:
git: git:
url: https://github.com/nextcloud/neon url: https://github.com/nextcloud/neon
path: packages/neon_lints path: packages/neon_lints
test: ^1.24.9 test: ^1.24.3
vector_graphics_compiler: ^1.1.9 vector_graphics_compiler: ^1.1.9
flutter: flutter:

Loading…
Cancel
Save