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",
"globalOptionsThemeOLEDAsDark": "OLED theme as dark theme",
"globalOptionsThemeUseNextcloudTheme": "Use Nextcloud theme",
"globalOptionsThemeCustomBackground": "Custom background",
"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",
"globalOptionsPushNotificationsDistributor": "UnifiedPush Distributor",

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

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

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

@ -254,6 +254,9 @@ class NeonLocalizationsEn extends NeonLocalizations {
@override
String get globalOptionsThemeUseNextcloudTheme => 'Use Nextcloud theme';
@override
String get globalOptionsThemeCustomBackground => 'Custom background';
@override
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/provider.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:nextcloud/core.dart' as core;
import 'package:nextcloud/nextcloud.dart';
@ -297,12 +298,14 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
? _accountsBloc.getCapabilitiesBlocFor(activeAccountSnapshot.data!).capabilities
: null,
builder: (final context, final capabilitiesSnapshot) {
final nextcloudTheme = capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming;
final appTheme = AppTheme(
nextcloudTheme: capabilitiesSnapshot.data?.capabilities.themingPublicCapabilities?.theming,
nextcloudTheme: nextcloudTheme,
useNextcloudTheme: options.themeUseNextcloudTheme.value,
deviceThemeLight: deviceThemeLight,
deviceThemeDark: deviceThemeDark,
oledAsDark: options.themeOLEDAsDark.value,
customBackground: options.themeCustomBackground.value,
appThemes: _appImplementations.map((final a) => a.theme).whereNotNull(),
neonTheme: widget.neonTheme,
);
@ -322,6 +325,10 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
theme: appTheme.lightTheme,
darkTheme: appTheme.darkTheme,
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) {
return Row(
children: [
ColoredBox(
color: Theme.of(context).colorScheme.background,
child: drawer,
),
drawer,
Expanded(
child: body,
),

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

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

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

@ -17,6 +17,7 @@ class AppTheme {
required this.neonTheme,
final bool useNextcloudTheme = false,
this.oledAsDark = false,
this.customBackground = false,
this.appThemes,
}) : useNextcloudTheme = nextcloudTheme == null || useNextcloudTheme;
@ -35,6 +36,9 @@ class AppTheme {
/// Whether to use [NcColors.oledBackground] in the dark theme.
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.
final Iterable<ThemeExtension>? appThemes;
@ -80,7 +84,7 @@ class AppTheme {
ThemeData _getTheme(final Brightness brightness) {
final colorScheme = _buildColorScheme(brightness);
return ThemeData(
final theme = ThemeData(
useMaterial3: true,
colorScheme: colorScheme,
scaffoldBackgroundColor: colorScheme.background,
@ -95,6 +99,25 @@ class AppTheme {
...?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].

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

@ -73,6 +73,7 @@ class GlobalOptions extends OptionsCollection {
themeMode,
themeOLEDAsDark,
themeUseNextcloudTheme,
themeCustomBackground,
pushNotificationsEnabled,
pushNotificationsDistributor,
startupMinimized,
@ -160,6 +161,14 @@ class GlobalOptions extends OptionsCollection {
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.
///
/// 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]
themeUseNextcloudTheme._('theme-use-nextcloud-theme'),
/// The storage key for [GlobalOptions.themeCustomBackground]
themeCustomBackground._('theme-custom-background'),
/// The storage key for [GlobalOptions.pushNotificationsEnabled]
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