Browse Source

Merge pull request #1064 from nextcloud/fix/neon/nextcloud-theme-contrast

pull/943/merge
Kate 1 year ago committed by GitHub
parent
commit
a50b341ad3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  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. 2
      packages/neon/neon/lib/l10n/en.arb
  5. 6
      packages/neon/neon/lib/l10n/localizations.dart
  6. 2
      packages/neon/neon/lib/l10n/localizations_en.dart
  7. 79
      packages/neon/neon/lib/src/app.dart
  8. 2
      packages/neon/neon/lib/src/pages/settings.dart
  9. 64
      packages/neon/neon/lib/src/theme/theme.dart
  10. 16
      packages/neon/neon/lib/src/utils/global_options.dart
  11. 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:

2
packages/neon/neon/lib/l10n/en.arb

@ -131,7 +131,7 @@
"globalOptionsThemeModeDark": "Dark", "globalOptionsThemeModeDark": "Dark",
"globalOptionsThemeModeAutomatic": "Automatic", "globalOptionsThemeModeAutomatic": "Automatic",
"globalOptionsThemeOLEDAsDark": "OLED theme as dark theme", "globalOptionsThemeOLEDAsDark": "OLED theme as dark theme",
"globalOptionsThemeKeepOriginalAccentColor": "Keep the original accent color", "globalOptionsThemeUseNextcloudTheme": "Use Nextcloud theme",
"globalOptionsPushNotificationsEnabled": "Enabled", "globalOptionsPushNotificationsEnabled": "Enabled",
"globalOptionsPushNotificationsEnabledDisabledNotice": "No UnifiedPush distributor could be found or you denied the permission for showing notifications. Please go to the app settings and allow notifications and go to https://unifiedpush.org/users/distributors and setup any of the listed distributors. Then re-open this app and you should be able to enable notifications", "globalOptionsPushNotificationsEnabledDisabledNotice": "No UnifiedPush distributor could be found or you denied the permission for showing notifications. Please go to the app settings and allow notifications and go to https://unifiedpush.org/users/distributors and setup any of the listed distributors. Then re-open this app and you should be able to enable notifications",
"globalOptionsPushNotificationsDistributor": "UnifiedPush Distributor", "globalOptionsPushNotificationsDistributor": "UnifiedPush Distributor",

6
packages/neon/neon/lib/l10n/localizations.dart

@ -509,11 +509,11 @@ abstract class NeonLocalizations {
/// **'OLED theme as dark theme'** /// **'OLED theme as dark theme'**
String get globalOptionsThemeOLEDAsDark; String get globalOptionsThemeOLEDAsDark;
/// No description provided for @globalOptionsThemeKeepOriginalAccentColor. /// No description provided for @globalOptionsThemeUseNextcloudTheme.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Keep the original accent color'** /// **'Use Nextcloud theme'**
String get globalOptionsThemeKeepOriginalAccentColor; String get globalOptionsThemeUseNextcloudTheme;
/// No description provided for @globalOptionsPushNotificationsEnabled. /// No description provided for @globalOptionsPushNotificationsEnabled.
/// ///

2
packages/neon/neon/lib/l10n/localizations_en.dart

@ -252,7 +252,7 @@ class NeonLocalizationsEn extends NeonLocalizations {
String get globalOptionsThemeOLEDAsDark => 'OLED theme as dark theme'; String get globalOptionsThemeOLEDAsDark => 'OLED theme as dark theme';
@override @override
String get globalOptionsThemeKeepOriginalAccentColor => 'Keep the original accent color'; String get globalOptionsThemeUseNextcloudTheme => 'Use Nextcloud theme';
@override @override
String get globalOptionsPushNotificationsEnabled => 'Enabled'; String get globalOptionsPushNotificationsEnabled => 'Enabled';

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(
keepOriginalAccentColor: options.themeKeepOriginalAccentColor.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,
);
},
);
},
),
), ),
); );
} }

2
packages/neon/neon/lib/src/pages/settings.dart

@ -157,7 +157,7 @@ class _SettingsPageState extends State<SettingsPage> {
option: globalOptions.themeOLEDAsDark, option: globalOptions.themeOLEDAsDark,
), ),
ToggleSettingsTile( ToggleSettingsTile(
option: globalOptions.themeKeepOriginalAccentColor, option: globalOptions.themeUseNextcloudTheme,
), ),
], ],
), ),

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

@ -10,19 +10,27 @@ 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 keepOriginalAccentColor = false, final bool useNextcloudTheme = false,
this.oledAsDark = false, this.oledAsDark = false,
this.appThemes, this.appThemes,
}) : keepOriginalAccentColor = nextcloudTheme == null || keepOriginalAccentColor; }) : useNextcloudTheme = nextcloudTheme == null || useNextcloudTheme;
/// The theme provided by the Nextcloud server. /// The theme provided by the Nextcloud server.
final core.ThemingPublicCapabilities_Theming? nextcloudTheme; final core.ThemingPublicCapabilities_Theming? nextcloudTheme;
/// Whether to force the use of the Nextcloud accent color. /// Whether to use of the Nextcloud theme.
final bool keepOriginalAccentColor; 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,18 +42,39 @@ class AppTheme {
final NeonTheme neonTheme; final NeonTheme neonTheme;
ColorScheme _buildColorScheme(final Brightness brightness) { ColorScheme _buildColorScheme(final Brightness brightness) {
final primary = nextcloudTheme?.color != null ? HexColor(nextcloudTheme!.color) : neonTheme.colorScheme.primary; ColorScheme? colorScheme;
final keepOriginalAccentColorOverride = keepOriginalAccentColor ? primary : null;
final oledBackgroundOverride = oledAsDark && brightness == Brightness.dark ? NcColors.oledBackground : null; if (nextcloudTheme != null && useNextcloudTheme) {
final primaryColor = HexColor(nextcloudTheme!.color);
return ColorScheme.fromSeed( final onPrimaryColor = HexColor(nextcloudTheme!.colorText);
seedColor: primary,
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: keepOriginalAccentColorOverride,
secondary: keepOriginalAccentColorOverride,
); );
if (oledAsDark && brightness == Brightness.dark) {
colorScheme = colorScheme.copyWith(
background: NcColors.oledBackground,
);
}
return colorScheme;
} }
ThemeData _getTheme(final Brightness brightness) { ThemeData _getTheme(final Brightness brightness) {
@ -55,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,

16
packages/neon/neon/lib/src/utils/global_options.dart

@ -72,7 +72,7 @@ class GlobalOptions extends OptionsCollection {
late final List<Option<dynamic>> options = [ late final List<Option<dynamic>> options = [
themeMode, themeMode,
themeOLEDAsDark, themeOLEDAsDark,
themeKeepOriginalAccentColor, themeUseNextcloudTheme,
pushNotificationsEnabled, pushNotificationsEnabled,
pushNotificationsDistributor, pushNotificationsDistributor,
startupMinimized, startupMinimized,
@ -150,14 +150,14 @@ class GlobalOptions extends OptionsCollection {
defaultValue: false, defaultValue: false,
); );
/// Whether the `ColorScheme` should keep the accent color provided by the Nextcloud server. /// Whether the `ColorScheme` should keep the colors provided by the Nextcloud server.
/// ///
/// Defaults to `false` generating a Material 3 style color. /// Defaults to `false` generating a Material 3 style color.
late final themeKeepOriginalAccentColor = ToggleOption( late final themeUseNextcloudTheme = ToggleOption(
storage: storage, storage: storage,
key: GlobalOptionKeys.themeKeepOriginalAccentColor, key: GlobalOptionKeys.themeUseNextcloudTheme,
label: (final context) => NeonLocalizations.of(context).globalOptionsThemeKeepOriginalAccentColor, label: (final context) => NeonLocalizations.of(context).globalOptionsThemeUseNextcloudTheme,
defaultValue: false, defaultValue: true,
); );
/// Whether to enable the push notifications plugin. /// Whether to enable the push notifications plugin.
@ -286,8 +286,8 @@ enum GlobalOptionKeys implements Storable {
/// The storage key for [GlobalOptions.themeOLEDAsDark] /// The storage key for [GlobalOptions.themeOLEDAsDark]
themeOLEDAsDark._('theme-oled-as-dark'), themeOLEDAsDark._('theme-oled-as-dark'),
/// The storage key for [GlobalOptions.themeKeepOriginalAccentColor] /// The storage key for [GlobalOptions.themeUseNextcloudTheme]
themeKeepOriginalAccentColor._('theme-keep-original-accent-color'), themeUseNextcloudTheme._('theme-use-nextcloud-theme'),
/// The storage key for [GlobalOptions.pushNotificationsEnabled] /// The storage key for [GlobalOptions.pushNotificationsEnabled]
pushNotificationsEnabled._('push-notifications-enabled'), pushNotificationsEnabled._('push-notifications-enabled'),

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