From b09f37e025cb566ff818d466a1c19e66b7c43175 Mon Sep 17 00:00:00 2001 From: Mayur Mahajan <47064215+MayurSMahajan@users.noreply.github.com> Date: Fri, 30 Dec 2022 09:14:17 +0530 Subject: [PATCH] [FR] Create a new yellow theme for AppFlowy (#1539) * feat: add dandelion color scheme * feat: add dandelion to colorsheme * feat: add setting for choosing theme * refactor: make theme selection ui consistent * refactor: remove duplicate themeTypeLabel * refactor: translate theme type setting * refactor: use an extension method for themename * refactor: change community theme name * refactor: add theme name in app theme * refactor: remove theme type from cubit * refactor: allow theme change with themename * test: getThemeNameForDisplaying method * chore: refactor the theme name to const string * refactor: remove theme translation logic * fix: add translation for theme label Co-authored-by: Lucas.Xu --- .../app_flowy/assets/translations/en.json | 5 +- .../lib/workspace/application/appearance.dart | 4 +- .../widgets/settings_appearance_view.dart | 61 +++++++++++++++ .../lib/colorscheme/colorscheme.dart | 27 +++++-- .../lib/colorscheme/dandelion.dart | 74 +++++++++++++++++++ .../packages/flowy_infra/lib/theme.dart | 24 ++---- 6 files changed, 167 insertions(+), 28 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_infra/lib/colorscheme/dandelion.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index dd29956c4b..f4a2845157 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -165,7 +165,8 @@ "light": "Light Mode", "dark": "Dark Mode", "system": "Adapt to System" - } + }, + "theme":"Theme" }, "files": { "defaultLocation": "Where your data is stored now", @@ -173,7 +174,7 @@ "restoreLocation": "Restore to AppFlowy default path", "customizeLocation": "Open another folder", "restartApp": "Please restart app for the changes to take effect.", - "exportDatabase": "Export databae", + "exportDatabase": "Export database", "selectFiles": "Select the files that need to be export", "createNewFolder": "Create a new folder", "createNewFolderDesc": "Tell us where you want to store your data ...", diff --git a/frontend/app_flowy/lib/workspace/application/appearance.dart b/frontend/app_flowy/lib/workspace/application/appearance.dart index 41e5036db0..655ccec0eb 100644 --- a/frontend/app_flowy/lib/workspace/application/appearance.dart +++ b/frontend/app_flowy/lib/workspace/application/appearance.dart @@ -35,7 +35,7 @@ class AppearanceSettingsCubit extends Cubit { void setTheme(String themeName) { _setting.theme = themeName; _saveAppearanceSettings(); - emit(state.copyWith(appTheme: AppTheme.fromName(themeName: themeName))); + emit(state.copyWith(appTheme: AppTheme.fromName(themeName))); } /// Update the theme mode in the user's settings and emit an updated state. @@ -161,7 +161,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState { LocaleSettingsPB localePB, ) { return AppearanceSettingsState( - appTheme: AppTheme.fromName(themeName: themeName), + appTheme: AppTheme.fromName(themeName), font: font, monospaceFont: monospaceFont, themeMode: _themeModeFromPB(themeModePB), diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart index bd3d3c0726..53dac3b8b7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart @@ -3,6 +3,7 @@ import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flutter/material.dart'; @@ -20,6 +21,7 @@ class SettingsAppearanceView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ ThemeModeSetting(currentThemeMode: state.themeMode), + ThemeSetting(currentTheme: state.appTheme.themeName), ], ); }, @@ -28,6 +30,65 @@ class SettingsAppearanceView extends StatelessWidget { } } +class ThemeSetting extends StatelessWidget { + final String currentTheme; + const ThemeSetting({ + super.key, + required this.currentTheme, + }); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: FlowyText.medium( + LocaleKeys.settings_appearance_theme.tr(), + overflow: TextOverflow.ellipsis, + ), + ), + AppFlowyPopover( + direction: PopoverDirection.bottomWithRightAligned, + child: FlowyTextButton( + currentTheme, + fillColor: Colors.transparent, + hoverColor: Theme.of(context).colorScheme.secondary, + onPressed: () {}, + ), + popupBuilder: (BuildContext context) { + return IntrinsicWidth( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _themeItemButton(context, BuiltInTheme.light), + _themeItemButton(context, BuiltInTheme.dandelion), + ], + ), + ); + }, + ), + ], + ); + } + + Widget _themeItemButton(BuildContext context, String theme) { + return SizedBox( + height: 32, + child: FlowyButton( + text: FlowyText.medium(theme), + rightIcon: currentTheme == theme + ? svgWidget("grid/checkmark") + : const SizedBox(), + onTap: () { + if (currentTheme != theme) { + context.read().setTheme(theme); + } + }, + ), + ); + } +} + class ThemeModeSetting extends StatelessWidget { final ThemeMode currentThemeMode; const ThemeModeSetting({required this.currentThemeMode, super.key}); diff --git a/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/colorscheme.dart b/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/colorscheme.dart index 1ac6223370..e2dac88013 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/colorscheme.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/colorscheme.dart @@ -1,6 +1,23 @@ import 'package:flutter/material.dart'; +import 'package:flowy_infra/theme.dart'; import 'default_colorscheme.dart'; +import 'dandelion.dart'; + +/// A map of all the built-in themes. +/// +/// The key is the theme name, and the value is a list of two color schemes: +/// the first is for light mode, and the second is for dark mode. +const Map> themeMap = { + BuiltInTheme.light: [ + DefaultColorScheme.light(), + DefaultColorScheme.dark(), + ], + BuiltInTheme.dandelion: [ + DandelionColorScheme.light(), + DandelionColorScheme.dark(), + ], +}; @immutable abstract class FlowyColorScheme { @@ -69,15 +86,9 @@ abstract class FlowyColorScheme { factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) { switch (brightness) { case Brightness.light: - return const DefaultColorScheme.light(); + return themeMap[themeName]?[0] ?? const DefaultColorScheme.light(); case Brightness.dark: - return const DefaultColorScheme.dark(); + return themeMap[themeName]?[1] ?? const DefaultColorScheme.dark(); } } - - // factory FlowyColorScheme.fromJson(Map json, Brightness brightness) { - // // load Json - - // return FlowyColorScheme(brightness...); - // } } diff --git a/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/dandelion.dart b/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/dandelion.dart new file mode 100644 index 0000000000..21492f43b4 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_infra/lib/colorscheme/dandelion.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +import 'colorscheme.dart'; + +const _black = Color(0xff000000); +const _white = Color(0xFFFFFFFF); + +class DandelionColorScheme extends FlowyColorScheme { + const DandelionColorScheme.light() + : super( + surface: Colors.white, + hover: const Color(0xFFe0f8ff), + selector: const Color(0xfff2fcff), + red: const Color(0xfffb006d), + yellow: const Color(0xffffd667), + green: const Color(0xff66cf80), + shader1: const Color(0xff333333), + shader2: const Color(0xff4f4f4f), + shader3: const Color(0xff828282), + shader4: const Color(0xffbdbdbd), + shader5: const Color(0xffe0e0e0), + shader6: const Color(0xfff2f2f2), + shader7: const Color(0xffffffff), + bg1: const Color(0xFFFFD13E), + bg2: const Color(0xffedeef2), + bg3: const Color(0xffe2e4eb), + bg4: const Color(0xff2c144b), + tint1: const Color(0xffe8e0ff), + tint2: const Color(0xffffe7fd), + tint3: const Color(0xffffe7ee), + tint4: const Color(0xffffefe3), + tint5: const Color(0xfffff2cd), + tint6: const Color(0xfff5ffdc), + tint7: const Color(0xffddffd6), + tint8: const Color(0xffdefff1), + tint9: const Color(0xffe1fbff), + main1: const Color(0xffe21f74), + main2: const Color.fromARGB(255, 224, 25, 111), + shadow: _black, + ); + + const DandelionColorScheme.dark() + : super( + surface: const Color(0xff292929), + hover: const Color(0xff1f1f1f), + selector: const Color(0xff333333), + red: const Color(0xfffb006d), + yellow: const Color(0xffffd667), + green: const Color(0xff66cf80), + shader1: _white, + shader2: const Color(0xffffffff), + shader3: const Color(0xff828282), + shader4: const Color(0xffbdbdbd), + shader5: _white, + shader6: _black, + shader7: _black, + bg1: const Color(0xFFD5A200), + bg2: _black, + bg3: const Color(0xff4f4f4f), + bg4: const Color(0xff2c144b), + tint1: const Color(0xffc3adff), + tint2: const Color(0xffffadf9), + tint3: const Color(0xffffadad), + tint4: const Color(0xffffcfad), + tint5: const Color(0xfffffead), + tint6: const Color(0xffe6ffa3), + tint7: const Color(0xffbcffad), + tint8: const Color(0xffadffe2), + tint9: const Color(0xffade4ff), + main1: const Color(0xffe21f74), + main2: const Color.fromARGB(255, 224, 25, 111), + shadow: _black, + ); +} diff --git a/frontend/app_flowy/packages/flowy_infra/lib/theme.dart b/frontend/app_flowy/packages/flowy_infra/lib/theme.dart index 2ce6aa26b1..4a32a0e16b 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/theme.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/theme.dart @@ -1,35 +1,27 @@ import 'package:flowy_infra/colorscheme/colorscheme.dart'; import 'package:flutter/material.dart'; -const List builtInThemes = [ - 'light', -]; +class BuiltInTheme { + static const String light = 'light'; + static const String dandelion = 'dandelion'; +} class AppTheme { // metadata member + final String themeName; final FlowyColorScheme lightTheme; final FlowyColorScheme darkTheme; // static final Map _cachedJsonData = {}; const AppTheme({ + required this.themeName, required this.lightTheme, required this.darkTheme, }); - factory AppTheme.fromName({required String themeName}) { - // if (builtInThemes.contains(themeName)) { - // return AppTheme( - // lightTheme: FlowyColorScheme.builtIn(themeName, Brightness.light), - // darkTheme: FlowyColorScheme.builtIn(themeName, Brightness.dark), - // ); - // } else { - // // load from Json - // return AppTheme( - // lightTheme: FlowyColorScheme.fromJson(_jsonData, Brightness.light), - // darkTheme: FlowyColorScheme.fromJson(_jsonData, Brightness.dark), - // ); - // } + factory AppTheme.fromName(String themeName) { return AppTheme( + themeName: themeName, lightTheme: FlowyColorScheme.builtIn(themeName, Brightness.light), darkTheme: FlowyColorScheme.builtIn(themeName, Brightness.dark), );