mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[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:
parent
aa5f052ecf
commit
b09f37e025
@ -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 ...",
|
||||||
|
@ -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),
|
||||||
|
@ -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});
|
||||||
|
@ -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...);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
);
|
||||||
|
}
|
@ -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),
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user