[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 <lucas.xu@appflowy.io>
This commit is contained in:
Mayur Mahajan 2022-12-30 09:14:17 +05:30 committed by GitHub
parent aa5f052ecf
commit b09f37e025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 167 additions and 28 deletions

View File

@ -165,7 +165,8 @@
"light": "Light Mode", "light": "Light Mode",
"dark": "Dark Mode", "dark": "Dark Mode",
"system": "Adapt to System" "system": "Adapt to System"
} },
"theme":"Theme"
}, },
"files": { "files": {
"defaultLocation": "Where your data is stored now", "defaultLocation": "Where your data is stored now",
@ -173,7 +174,7 @@
"restoreLocation": "Restore to AppFlowy default path", "restoreLocation": "Restore to AppFlowy default path",
"customizeLocation": "Open another folder", "customizeLocation": "Open another folder",
"restartApp": "Please restart app for the changes to take effect.", "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", "selectFiles": "Select the files that need to be export",
"createNewFolder": "Create a new folder", "createNewFolder": "Create a new folder",
"createNewFolderDesc": "Tell us where you want to store your data ...", "createNewFolderDesc": "Tell us where you want to store your data ...",

View File

@ -35,7 +35,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
void setTheme(String themeName) { void setTheme(String themeName) {
_setting.theme = themeName; _setting.theme = themeName;
_saveAppearanceSettings(); _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. /// Update the theme mode in the user's settings and emit an updated state.
@ -161,7 +161,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
LocaleSettingsPB localePB, LocaleSettingsPB localePB,
) { ) {
return AppearanceSettingsState( return AppearanceSettingsState(
appTheme: AppTheme.fromName(themeName: themeName), appTheme: AppTheme.fromName(themeName),
font: font, font: font,
monospaceFont: monospaceFont, monospaceFont: monospaceFont,
themeMode: _themeModeFromPB(themeModePB), themeMode: _themeModeFromPB(themeModePB),

View File

@ -3,6 +3,7 @@ import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.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/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,6 +21,7 @@ class SettingsAppearanceView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ThemeModeSetting(currentThemeMode: state.themeMode), 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<AppearanceSettingsCubit>().setTheme(theme);
}
},
),
);
}
}
class ThemeModeSetting extends StatelessWidget { class ThemeModeSetting extends StatelessWidget {
final ThemeMode currentThemeMode; final ThemeMode currentThemeMode;
const ThemeModeSetting({required this.currentThemeMode, super.key}); const ThemeModeSetting({required this.currentThemeMode, super.key});

View File

@ -1,6 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flowy_infra/theme.dart';
import 'default_colorscheme.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<String, List<FlowyColorScheme>> themeMap = {
BuiltInTheme.light: [
DefaultColorScheme.light(),
DefaultColorScheme.dark(),
],
BuiltInTheme.dandelion: [
DandelionColorScheme.light(),
DandelionColorScheme.dark(),
],
};
@immutable @immutable
abstract class FlowyColorScheme { abstract class FlowyColorScheme {
@ -69,15 +86,9 @@ abstract class FlowyColorScheme {
factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) { factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) {
switch (brightness) { switch (brightness) {
case Brightness.light: case Brightness.light:
return const DefaultColorScheme.light(); return themeMap[themeName]?[0] ?? const DefaultColorScheme.light();
case Brightness.dark: case Brightness.dark:
return const DefaultColorScheme.dark(); return themeMap[themeName]?[1] ?? const DefaultColorScheme.dark();
} }
} }
// factory FlowyColorScheme.fromJson(Map<String, dynamic> json, Brightness brightness) {
// // load Json
// return FlowyColorScheme(brightness...);
// }
} }

View File

@ -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,
);
}

View File

@ -1,35 +1,27 @@
import 'package:flowy_infra/colorscheme/colorscheme.dart'; import 'package:flowy_infra/colorscheme/colorscheme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
const List<String> builtInThemes = [ class BuiltInTheme {
'light', static const String light = 'light';
]; static const String dandelion = 'dandelion';
}
class AppTheme { class AppTheme {
// metadata member // metadata member
final String themeName;
final FlowyColorScheme lightTheme; final FlowyColorScheme lightTheme;
final FlowyColorScheme darkTheme; final FlowyColorScheme darkTheme;
// static final Map<String, dynamic> _cachedJsonData = {}; // static final Map<String, dynamic> _cachedJsonData = {};
const AppTheme({ const AppTheme({
required this.themeName,
required this.lightTheme, required this.lightTheme,
required this.darkTheme, required this.darkTheme,
}); });
factory AppTheme.fromName({required String themeName}) { factory AppTheme.fromName(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),
// );
// }
return AppTheme( return AppTheme(
themeName: themeName,
lightTheme: FlowyColorScheme.builtIn(themeName, Brightness.light), lightTheme: FlowyColorScheme.builtIn(themeName, Brightness.light),
darkTheme: FlowyColorScheme.builtIn(themeName, Brightness.dark), darkTheme: FlowyColorScheme.builtIn(themeName, Brightness.dark),
); );