From 15eaf4af6039bff28b8ccb95fb1149f0f34bba9d Mon Sep 17 00:00:00 2001 From: Tien Do Nam Date: Tue, 12 Sep 2023 23:02:58 +0200 Subject: [PATCH] feat: add OLED color mode --- assets/CHANGELOG.md | 1 + assets/i18n/strings.i18n.json | 3 ++- assets/i18n/strings_de.i18n.json | 3 ++- lib/main.dart | 6 ++--- lib/model/persistence/color_mode.dart | 1 + lib/pages/tabs/settings_tab.dart | 6 +++++ lib/theme.dart | 39 ++++++++++++++++++++------- 7 files changed, 44 insertions(+), 15 deletions(-) diff --git a/assets/CHANGELOG.md b/assets/CHANGELOG.md index b58cc8fee6a..18f003ec868 100644 --- a/assets/CHANGELOG.md +++ b/assets/CHANGELOG.md @@ -1,6 +1,7 @@ ## 1.12.0 (2023-) - feat: drastically improve GPU usage by optimizing the spin animation (@Tienisto) +- feat: add OLED color mode (@Tienisto) - feat: use better colors for the toggle switches in the settings (@gitstart) - feat(linux): allow disabling client side decorations on Wayland (@I-Want-ToBelieve) - fix(desktop): fallback to "$HOME/Downloads" when default downloads folder is unavailable (@Sqbika) diff --git a/assets/i18n/strings.i18n.json b/assets/i18n/strings.i18n.json index 4564d453127..0052f222ea2 100644 --- a/assets/i18n/strings.i18n.json +++ b/assets/i18n/strings.i18n.json @@ -86,7 +86,8 @@ }, "color": "Color", "colorOptions": { - "system": "System" + "system": "System", + "oled": "OLED" }, "language": "Language", "languageOptions": { diff --git a/assets/i18n/strings_de.i18n.json b/assets/i18n/strings_de.i18n.json index 96b1102a735..0e81213c38e 100644 --- a/assets/i18n/strings_de.i18n.json +++ b/assets/i18n/strings_de.i18n.json @@ -86,7 +86,8 @@ }, "color": "Farbe", "colorOptions": { - "system": "System" + "system": "System", + "oled": "OLED" }, "language": "Sprache", "languageOptions": { diff --git a/lib/main.dart b/lib/main.dart index 067bc237c04..552b4288c18 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -69,9 +69,9 @@ class LocalSendApp extends StatelessWidget { supportedLocales: AppLocaleUtils.supportedLocales, localizationsDelegates: GlobalMaterialLocalizations.delegates, debugShowCheckedModeBanner: false, - theme: getTheme(Brightness.light, colorMode == ColorMode.system ? dynamicColors?.light : null), - darkTheme: getTheme(Brightness.dark, colorMode == ColorMode.system ? dynamicColors?.dark : null), - themeMode: themeMode, + theme: getTheme(colorMode, Brightness.light, dynamicColors), + darkTheme: getTheme(colorMode, Brightness.dark, dynamicColors), + themeMode: colorMode == ColorMode.oled ? ThemeMode.dark : themeMode, navigatorKey: Routerino.navigatorKey, home: RouterinoHome( builder: () => const HomePage( diff --git a/lib/model/persistence/color_mode.dart b/lib/model/persistence/color_mode.dart index 17b0d3a9d4e..08d4e79b48f 100644 --- a/lib/model/persistence/color_mode.dart +++ b/lib/model/persistence/color_mode.dart @@ -1,4 +1,5 @@ enum ColorMode { system, // dynamic colors localsend, + oled, } diff --git a/lib/pages/tabs/settings_tab.dart b/lib/pages/tabs/settings_tab.dart index 53ced205310..bf5ce8d1b1c 100644 --- a/lib/pages/tabs/settings_tab.dart +++ b/lib/pages/tabs/settings_tab.dart @@ -117,6 +117,10 @@ class _SettingsTabState extends State with Riverpie { onChanged: (colorMode) async { if (colorMode != null) { await ref.notifier(settingsProvider).setColorMode(colorMode); + if (colorMode == ColorMode.oled) { + await ref.notifier(settingsProvider).setTheme(ThemeMode.dark); + await updateSystemOverlayStyleWithBrightness(Brightness.dark); + } } }, ), @@ -662,6 +666,8 @@ extension on ColorMode { return t.settingsTab.general.colorOptions.system; case ColorMode.localsend: return t.appName; + case ColorMode.oled: + return t.settingsTab.general.colorOptions.oled; } } } diff --git a/lib/theme.dart b/lib/theme.dart index 35d8dea3287..50691edcbb9 100644 --- a/lib/theme.dart +++ b/lib/theme.dart @@ -1,17 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:localsend_app/gen/strings.g.dart'; +import 'package:localsend_app/model/persistence/color_mode.dart'; import 'package:localsend_app/provider/device_info_provider.dart'; import 'package:localsend_app/util/native/platform_check.dart'; +import 'package:localsend_app/util/ui/dynamic_colors.dart'; import 'package:riverpie_flutter/riverpie_flutter.dart'; final _borderRadius = BorderRadius.circular(5); -ThemeData getTheme(Brightness brightness, ColorScheme? colorScheme) { - colorScheme ??= ColorScheme.fromSeed( - seedColor: Colors.teal, - brightness: brightness, - ); +ThemeData getTheme(ColorMode colorMode, Brightness brightness, DynamicColors? dynamicColors) { + final colorScheme = _determineColorScheme(colorMode, brightness, dynamicColors); final lightInputBorder = OutlineInputBorder( borderSide: BorderSide(color: colorScheme.secondaryContainer), @@ -50,7 +49,7 @@ ThemeData getTheme(Brightness brightness, ColorScheme? colorScheme) { return ThemeData( colorScheme: colorScheme, useMaterial3: true, - navigationBarTheme: brightness == Brightness.dark + navigationBarTheme: colorScheme.brightness == Brightness.dark ? NavigationBarThemeData( iconTheme: MaterialStateProperty.all(const IconThemeData(color: Colors.white)), ) @@ -58,14 +57,14 @@ ThemeData getTheme(Brightness brightness, ColorScheme? colorScheme) { inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: colorScheme.secondaryContainer, - border: brightness == Brightness.light ? lightInputBorder : darkInputBorder, - focusedBorder: brightness == Brightness.light ? lightInputBorder : darkInputBorder, - enabledBorder: brightness == Brightness.light ? lightInputBorder : darkInputBorder, + border: colorScheme.brightness == Brightness.light ? lightInputBorder : darkInputBorder, + focusedBorder: colorScheme.brightness == Brightness.light ? lightInputBorder : darkInputBorder, + enabledBorder: colorScheme.brightness == Brightness.light ? lightInputBorder : darkInputBorder, contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( - foregroundColor: brightness == Brightness.dark ? Colors.white : null, + foregroundColor: colorScheme.brightness == Brightness.dark ? Colors.white : null, padding: checkPlatformIsDesktop() ? const EdgeInsets.all(16) : const EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), ), @@ -131,3 +130,23 @@ extension ColorSchemeExt on ColorScheme { extension InputDecorationThemeExt on InputDecorationTheme { BorderRadius get borderRadius => _borderRadius; } + +ColorScheme _determineColorScheme(ColorMode mode, Brightness brightness, DynamicColors? dynamicColors) { + final colorScheme = switch (mode) { + ColorMode.system => brightness == Brightness.light ? dynamicColors?.light : dynamicColors?.dark, + ColorMode.localsend => null, + ColorMode.oled => ColorScheme.fromSeed( + seedColor: Colors.teal, + brightness: brightness, + ).copyWith( + background: Colors.black, + surface: Colors.black, + ), + }; + + return colorScheme ?? + ColorScheme.fromSeed( + seedColor: Colors.teal, + brightness: brightness, + ); +}