Browse Source

feat(neon): Support custom backgrounds

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/943/head
jld3103 1 year ago
parent
commit
48e762cd76
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 1
      packages/neon/neon/lib/l10n/en.arb
  2. 6
      packages/neon/neon/lib/l10n/localizations.dart
  3. 3
      packages/neon/neon/lib/l10n/localizations_en.dart
  4. 9
      packages/neon/neon/lib/src/app.dart
  5. 5
      packages/neon/neon/lib/src/pages/home.dart
  6. 3
      packages/neon/neon/lib/src/pages/settings.dart
  7. 25
      packages/neon/neon/lib/src/theme/theme.dart
  8. 12
      packages/neon/neon/lib/src/utils/global_options.dart
  9. 56
      packages/neon/neon/lib/src/widgets/custom_background.dart

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

@ -132,6 +132,7 @@
"globalOptionsThemeModeAutomatic": "Automatic", "globalOptionsThemeModeAutomatic": "Automatic",
"globalOptionsThemeOLEDAsDark": "OLED theme as dark theme", "globalOptionsThemeOLEDAsDark": "OLED theme as dark theme",
"globalOptionsThemeUseNextcloudTheme": "Use Nextcloud theme", "globalOptionsThemeUseNextcloudTheme": "Use Nextcloud theme",
"globalOptionsThemeCustomBackground": "Custom background",
"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

@ -515,6 +515,12 @@ abstract class NeonLocalizations {
/// **'Use Nextcloud theme'** /// **'Use Nextcloud theme'**
String get globalOptionsThemeUseNextcloudTheme; String get globalOptionsThemeUseNextcloudTheme;
/// No description provided for @globalOptionsThemeCustomBackground.
///
/// In en, this message translates to:
/// **'Custom background'**
String get globalOptionsThemeCustomBackground;
/// No description provided for @globalOptionsPushNotificationsEnabled. /// No description provided for @globalOptionsPushNotificationsEnabled.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

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

@ -254,6 +254,9 @@ class NeonLocalizationsEn extends NeonLocalizations {
@override @override
String get globalOptionsThemeUseNextcloudTheme => 'Use Nextcloud theme'; String get globalOptionsThemeUseNextcloudTheme => 'Use Nextcloud theme';
@override
String get globalOptionsThemeCustomBackground => 'Custom background';
@override @override
String get globalOptionsPushNotificationsEnabled => 'Enabled'; String get globalOptionsPushNotificationsEnabled => 'Enabled';

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

@ -22,6 +22,7 @@ import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/localizations.dart'; import 'package:neon/src/utils/localizations.dart';
import 'package:neon/src/utils/provider.dart'; import 'package:neon/src/utils/provider.dart';
import 'package:neon/src/utils/push_utils.dart'; import 'package:neon/src/utils/push_utils.dart';
import 'package:neon/src/widgets/custom_background.dart';
import 'package:neon/src/widgets/options_collection_builder.dart'; import 'package:neon/src/widgets/options_collection_builder.dart';
import 'package:nextcloud/core.dart' as core; import 'package:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
@ -297,12 +298,14 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities ? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities
: null, : null,
builder: (final context, final capabilitiesSnapshot) { builder: (final context, final capabilitiesSnapshot) {
final nextcloudTheme = capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming;
final appTheme = AppTheme( final appTheme = AppTheme(
nextcloudTheme: capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming, nextcloudTheme: nextcloudTheme,
useNextcloudTheme: options.themeUseNextcloudTheme.value, useNextcloudTheme: options.themeUseNextcloudTheme.value,
deviceThemeLight: deviceThemeLight, deviceThemeLight: deviceThemeLight,
deviceThemeDark: deviceThemeDark, deviceThemeDark: deviceThemeDark,
oledAsDark: options.themeOLEDAsDark.value, oledAsDark: options.themeOLEDAsDark.value,
customBackground: options.themeCustomBackground.value,
appThemes: _appImplementations.map((final a) => a.theme).whereNotNull(), appThemes: _appImplementations.map((final a) => a.theme).whereNotNull(),
neonTheme: widget.neonTheme, neonTheme: widget.neonTheme,
); );
@ -322,6 +325,10 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
theme: appTheme.lightTheme, theme: appTheme.lightTheme,
darkTheme: appTheme.darkTheme, darkTheme: appTheme.darkTheme,
routerConfig: _routerDelegate, routerConfig: _routerDelegate,
builder: (final context, final child) => NeonCustomBackground(
theme: options.themeCustomBackground.value ? nextcloudTheme : null,
child: child,
),
); );
}, },
); );

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

@ -183,10 +183,7 @@ class _HomePageState extends State<HomePage> {
if (drawerAlwaysVisible) { if (drawerAlwaysVisible) {
return Row( return Row(
children: [ children: [
ColoredBox( drawer,
color: Theme.of(context).colorScheme.background,
child: drawer,
),
Expanded( Expanded(
child: body, child: body,
), ),

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

@ -159,6 +159,9 @@ class _SettingsPageState extends State<SettingsPage> {
ToggleSettingsTile( ToggleSettingsTile(
option: globalOptions.themeUseNextcloudTheme, option: globalOptions.themeUseNextcloudTheme,
), ),
ToggleSettingsTile(
option: globalOptions.themeCustomBackground,
),
], ],
), ),
SettingsCategory( SettingsCategory(

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

@ -17,6 +17,7 @@ class AppTheme {
required this.neonTheme, required this.neonTheme,
final bool useNextcloudTheme = false, final bool useNextcloudTheme = false,
this.oledAsDark = false, this.oledAsDark = false,
this.customBackground = false,
this.appThemes, this.appThemes,
}) : useNextcloudTheme = nextcloudTheme == null || useNextcloudTheme; }) : useNextcloudTheme = nextcloudTheme == null || useNextcloudTheme;
@ -35,6 +36,9 @@ class AppTheme {
/// Whether to use [NcColors.oledBackground] in the dark theme. /// Whether to use [NcColors.oledBackground] in the dark theme.
final bool oledAsDark; final bool oledAsDark;
/// Whether to use a custom background image provided by the Nextcloud server.
final bool customBackground;
/// The theme extensions provided by the `AppImplementation`s. /// The theme extensions provided by the `AppImplementation`s.
final Iterable<ThemeExtension>? appThemes; final Iterable<ThemeExtension>? appThemes;
@ -80,7 +84,7 @@ class AppTheme {
ThemeData _getTheme(final Brightness brightness) { ThemeData _getTheme(final Brightness brightness) {
final colorScheme = _buildColorScheme(brightness); final colorScheme = _buildColorScheme(brightness);
return ThemeData( final theme = ThemeData(
useMaterial3: true, useMaterial3: true,
colorScheme: colorScheme, colorScheme: colorScheme,
scaffoldBackgroundColor: colorScheme.background, scaffoldBackgroundColor: colorScheme.background,
@ -95,6 +99,25 @@ class AppTheme {
...?appThemes, ...?appThemes,
], ],
); );
if (useNextcloudTheme && customBackground) {
return theme.copyWith(
scaffoldBackgroundColor: Colors.transparent,
cardColor: Colors.transparent,
drawerTheme: const DrawerThemeData(
backgroundColor: Colors.transparent,
),
appBarTheme: const AppBarTheme(
backgroundColor: Colors.transparent,
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: Colors.transparent,
elevation: 0,
),
);
}
return theme;
} }
/// Returns a new theme for [Brightness.light]. /// Returns a new theme for [Brightness.light].

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

@ -73,6 +73,7 @@ class GlobalOptions extends OptionsCollection {
themeMode, themeMode,
themeOLEDAsDark, themeOLEDAsDark,
themeUseNextcloudTheme, themeUseNextcloudTheme,
themeCustomBackground,
pushNotificationsEnabled, pushNotificationsEnabled,
pushNotificationsDistributor, pushNotificationsDistributor,
startupMinimized, startupMinimized,
@ -160,6 +161,14 @@ class GlobalOptions extends OptionsCollection {
defaultValue: true, defaultValue: true,
); );
late final themeCustomBackground = ToggleOption.depend(
storage: storage,
key: GlobalOptionKeys.themeCustomBackground,
label: (final context) => NeonLocalizations.of(context).globalOptionsThemeCustomBackground,
defaultValue: false,
enabled: themeUseNextcloudTheme,
);
/// Whether to enable the push notifications plugin. /// Whether to enable the push notifications plugin.
/// ///
/// Setting this option to true will request the permission to show notifications. /// Setting this option to true will request the permission to show notifications.
@ -289,6 +298,9 @@ enum GlobalOptionKeys implements Storable {
/// The storage key for [GlobalOptions.themeUseNextcloudTheme] /// The storage key for [GlobalOptions.themeUseNextcloudTheme]
themeUseNextcloudTheme._('theme-use-nextcloud-theme'), themeUseNextcloudTheme._('theme-use-nextcloud-theme'),
/// The storage key for [GlobalOptions.themeCustomBackground]
themeCustomBackground._('theme-custom-background'),
/// The storage key for [GlobalOptions.pushNotificationsEnabled] /// The storage key for [GlobalOptions.pushNotificationsEnabled]
pushNotificationsEnabled._('push-notifications-enabled'), pushNotificationsEnabled._('push-notifications-enabled'),

56
packages/neon/neon/lib/src/widgets/custom_background.dart

@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:neon/src/utils/hex_color.dart';
import 'package:neon/src/widgets/image.dart';
import 'package:nextcloud/core.dart' as core;
@internal
class NeonCustomBackground extends StatelessWidget {
const NeonCustomBackground({
required this.theme,
required this.child,
super.key,
});
final core.ThemingPublicCapabilities_Theming? theme;
final Widget? child;
double _opacity(final BuildContext context) => Theme.of(context).brightness == Brightness.light ? 0.2 : 0.1;
@override
Widget build(final BuildContext context) {
if (theme == null) {
return ColoredBox(
color: Theme.of(context).colorScheme.background,
child: child,
);
}
if (theme?.backgroundPlain ?? true) {
return ColoredBox(
color:
Color.lerp(HexColor(theme!.background), Theme.of(context).colorScheme.background, 1 - _opacity(context))!,
child: child,
);
}
final image = NeonUrlImage(
url: theme!.background,
fit: BoxFit.fill,
);
return ColoredBox(
color: Theme.of(context).colorScheme.background,
child: Stack(
children: [
Positioned.fill(
child: Opacity(
opacity: _opacity(context),
child: image,
),
),
if (child != null) child!,
],
),
);
}
}
Loading…
Cancel
Save