mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: appflowy themes (#1567)
* refactor: appflowy themes * refactor: store ThemeData directly in cubit * refactor: remove textStyles * refactor: move AppTheme back into cubit
This commit is contained in:
parent
67e350e797
commit
60d9a6b3ab
@ -82,8 +82,8 @@ class ApplicationWidget extends StatelessWidget {
|
||||
builder: (context, state) => MaterialApp(
|
||||
builder: overlayManagerBuilder(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: state.theme.getThemeData(state.locale),
|
||||
darkTheme: state.darkTheme.getThemeData(state.locale),
|
||||
theme: state.lightTheme,
|
||||
darkTheme: state.darkTheme,
|
||||
themeMode: state.themeMode,
|
||||
localizationsDelegates: context.localizationDelegates +
|
||||
[AppFlowyEditorLocalizations.delegate],
|
||||
|
@ -1,7 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:app_flowy/user/application/user_settings_service.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_setting.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -11,7 +13,10 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'appearance.freezed.dart';
|
||||
|
||||
/// [AppearanceSettingsCubit] is used to modify the appear setting of AppFlowy application. Includes the [Locale] and [AppTheme].
|
||||
const _white = Color(0xFFFFFFFF);
|
||||
|
||||
/// [AppearanceSettingsCubit] is used to modify the appearance of AppFlowy.
|
||||
/// It includes the [AppTheme], [ThemeMode], [TextStyles] and [Locale].
|
||||
class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
final AppearanceSettingsPB _setting;
|
||||
|
||||
@ -25,40 +30,23 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
setting.locale,
|
||||
));
|
||||
|
||||
/// Updates the current theme and notify the listeners the theme was changed.
|
||||
/// Do nothing if the passed in themeType equal to the current theme type.
|
||||
// void setTheme(Brightness brightness) {
|
||||
// if (state.theme.brightness == brightness) {
|
||||
// return;
|
||||
// }
|
||||
/// Update selected theme in the user's settings and emit an updated state
|
||||
/// with the AppTheme named [themeName].
|
||||
void setTheme(String themeName) {
|
||||
_setting.theme = themeName;
|
||||
_saveAppearanceSettings();
|
||||
emit(state.copyWith(appTheme: AppTheme.fromName(themeName: themeName)));
|
||||
}
|
||||
|
||||
// _setting.theme = themeTypeToString(brightness);
|
||||
// _saveAppearanceSettings();
|
||||
|
||||
// emit(state.copyWith(
|
||||
// theme: AppTheme.fromBrightness(
|
||||
// brightness: _setting.themeMode,
|
||||
// font: state.theme.font,
|
||||
// monospaceFont: state.theme.monospaceFont,
|
||||
// ),
|
||||
// ));
|
||||
// }
|
||||
|
||||
/// Updates the current theme and notify the listeners the theme was changed.
|
||||
/// Do nothing if the passed in themeType equal to the current theme type.
|
||||
/// Update the theme mode in the user's settings and emit an updated state.
|
||||
void setThemeMode(ThemeMode themeMode) {
|
||||
if (state.themeMode == themeMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
_setting.themeMode = _themeModeToPB(themeMode);
|
||||
_saveAppearanceSettings();
|
||||
|
||||
emit(state.copyWith(themeMode: themeMode));
|
||||
}
|
||||
|
||||
/// Updates the current locale and notify the listeners the locale was changed
|
||||
/// Fallback to [en] locale If the newLocale is not supported.
|
||||
/// Updates the current locale and notify the listeners the locale was
|
||||
/// changed. Fallback to [en] locale if [newLocale] is not supported.
|
||||
void setLocale(BuildContext context, Locale newLocale) {
|
||||
if (!context.supportedLocales.contains(newLocale)) {
|
||||
Log.warn("Unsupported locale: $newLocale, Fallback to locale: en");
|
||||
@ -106,8 +94,8 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||
return _setting.settingKeyValue[key];
|
||||
}
|
||||
|
||||
/// Called when the application launch.
|
||||
/// Uses the device locale when open the application for the first time
|
||||
/// Called when the application launches.
|
||||
/// Uses the device locale when the application is opened for the first time.
|
||||
void readLocaleWhenAppLaunch(BuildContext context) {
|
||||
if (_setting.resetToDefault) {
|
||||
_setting.resetToDefault = false;
|
||||
@ -155,32 +143,200 @@ ThemeModePB _themeModeToPB(ThemeMode themeMode) {
|
||||
|
||||
@freezed
|
||||
class AppearanceSettingsState with _$AppearanceSettingsState {
|
||||
const AppearanceSettingsState._();
|
||||
|
||||
const factory AppearanceSettingsState({
|
||||
required AppTheme theme,
|
||||
required AppTheme darkTheme,
|
||||
required AppTheme appTheme,
|
||||
required ThemeMode themeMode,
|
||||
required String font,
|
||||
required String monospaceFont,
|
||||
required Locale locale,
|
||||
}) = _AppearanceSettingsState;
|
||||
|
||||
factory AppearanceSettingsState.initial(
|
||||
String themeName,
|
||||
ThemeModePB themeMode,
|
||||
ThemeModePB themeModePB,
|
||||
String font,
|
||||
String monospaceFont,
|
||||
LocaleSettingsPB locale,
|
||||
) =>
|
||||
AppearanceSettingsState(
|
||||
theme: AppTheme.fromBrightness(
|
||||
brightness: Brightness.light,
|
||||
font: font,
|
||||
monospaceFont: monospaceFont,
|
||||
),
|
||||
darkTheme: AppTheme.fromBrightness(
|
||||
brightness: Brightness.dark,
|
||||
font: font,
|
||||
monospaceFont: monospaceFont,
|
||||
),
|
||||
themeMode: _themeModeFromPB(themeMode),
|
||||
locale: Locale(locale.languageCode, locale.countryCode),
|
||||
LocaleSettingsPB localePB,
|
||||
) {
|
||||
return AppearanceSettingsState(
|
||||
appTheme: AppTheme.fromName(themeName: themeName),
|
||||
font: font,
|
||||
monospaceFont: monospaceFont,
|
||||
themeMode: _themeModeFromPB(themeModePB),
|
||||
locale: Locale(localePB.languageCode, localePB.countryCode),
|
||||
);
|
||||
}
|
||||
|
||||
ThemeData get lightTheme => _getThemeData(Brightness.light);
|
||||
ThemeData get darkTheme => _getThemeData(Brightness.dark);
|
||||
|
||||
ThemeData _getThemeData(Brightness brightness) {
|
||||
// Poppins and SF Mono are not well supported in some languages, so use the
|
||||
// built-in font for the following languages.
|
||||
final useBuiltInFontLanguages = [
|
||||
const Locale('zh', 'CN'),
|
||||
const Locale('zh', 'TW'),
|
||||
];
|
||||
String fontFamily = font;
|
||||
String monospaceFontFamily = monospaceFont;
|
||||
if (useBuiltInFontLanguages.contains(locale)) {
|
||||
fontFamily = '';
|
||||
monospaceFontFamily = '';
|
||||
}
|
||||
|
||||
final theme = brightness == Brightness.light
|
||||
? appTheme.lightTheme
|
||||
: appTheme.darkTheme;
|
||||
|
||||
return ThemeData(
|
||||
brightness: brightness,
|
||||
textTheme:
|
||||
_getTextTheme(fontFamily: fontFamily, fontColor: theme.shader1),
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
cursorColor: theme.main2,
|
||||
selectionHandleColor: theme.main2,
|
||||
),
|
||||
primaryIconTheme: IconThemeData(color: theme.hover),
|
||||
iconTheme: IconThemeData(color: theme.shader1),
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbColor: MaterialStateProperty.all(Colors.transparent),
|
||||
),
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
canvasColor: theme.shader6,
|
||||
dividerColor: theme.shader6,
|
||||
hintColor: theme.shader3,
|
||||
disabledColor: theme.shader4,
|
||||
highlightColor: theme.main1,
|
||||
indicatorColor: theme.main1,
|
||||
toggleableActiveColor: theme.main1,
|
||||
colorScheme: ColorScheme(
|
||||
brightness: brightness,
|
||||
primary: theme.main1,
|
||||
onPrimary: _white,
|
||||
primaryContainer: theme.main2,
|
||||
onPrimaryContainer: _white,
|
||||
secondary: theme.hover,
|
||||
onSecondary: theme.shader1,
|
||||
secondaryContainer: theme.selector,
|
||||
onSecondaryContainer: theme.shader1,
|
||||
background: theme.surface,
|
||||
onBackground: theme.shader1,
|
||||
surface: theme.surface,
|
||||
onSurface: theme.shader1,
|
||||
onError: theme.shader7,
|
||||
error: theme.red,
|
||||
outline: theme.shader4,
|
||||
surfaceVariant: theme.bg1,
|
||||
shadow: theme.shadow,
|
||||
),
|
||||
extensions: [
|
||||
AFThemeExtension(
|
||||
warning: theme.yellow,
|
||||
success: theme.green,
|
||||
tint1: theme.tint1,
|
||||
tint2: theme.tint2,
|
||||
tint3: theme.tint3,
|
||||
tint4: theme.tint4,
|
||||
tint5: theme.tint5,
|
||||
tint6: theme.tint6,
|
||||
tint7: theme.tint7,
|
||||
tint8: theme.tint8,
|
||||
tint9: theme.tint9,
|
||||
greyHover: theme.bg2,
|
||||
greySelect: theme.bg3,
|
||||
lightGreyHover: theme.shader6,
|
||||
toggleOffFill: theme.shader5,
|
||||
code: _getFontStyle(
|
||||
fontFamily: monospaceFontFamily,
|
||||
fontColor: theme.shader3,
|
||||
),
|
||||
callout: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s11,
|
||||
fontColor: theme.shader3,
|
||||
),
|
||||
caption: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s11,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontColor: theme.shader3,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
TextStyle _getFontStyle({
|
||||
String? fontFamily,
|
||||
double? fontSize,
|
||||
FontWeight? fontWeight,
|
||||
Color? fontColor,
|
||||
double? letterSpacing,
|
||||
double? lineHeight,
|
||||
}) =>
|
||||
TextStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: fontSize ?? FontSizes.s12,
|
||||
color: fontColor,
|
||||
fontWeight: fontWeight ?? FontWeight.w500,
|
||||
fontFamilyFallback: const ["Noto Color Emoji"],
|
||||
letterSpacing: (fontSize ?? FontSizes.s12) * (letterSpacing ?? 0.005),
|
||||
height: lineHeight,
|
||||
);
|
||||
|
||||
TextTheme _getTextTheme(
|
||||
{required String fontFamily, required Color fontColor}) {
|
||||
return TextTheme(
|
||||
displayLarge: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s32,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 42.0,
|
||||
), // h2
|
||||
displayMedium: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s24,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 34.0,
|
||||
), // h3
|
||||
displaySmall: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s20,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 28.0,
|
||||
), // h4
|
||||
titleLarge: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s18,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // title
|
||||
titleMedium: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s16,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // heading
|
||||
titleSmall: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontSize: FontSizes.s14,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // subheading
|
||||
bodyMedium: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontColor: fontColor,
|
||||
), // body-regular
|
||||
bodySmall: _getFontStyle(
|
||||
fontFamily: fontFamily,
|
||||
fontColor: fontColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
), // body-thin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'default_colorscheme.dart';
|
||||
|
||||
@immutable
|
||||
abstract class FlowyColorScheme {
|
||||
final Color surface;
|
||||
final Color hover;
|
||||
final Color selector;
|
||||
final Color red;
|
||||
final Color yellow;
|
||||
final Color green;
|
||||
final Color shader1;
|
||||
final Color shader2;
|
||||
final Color shader3;
|
||||
final Color shader4;
|
||||
final Color shader5;
|
||||
final Color shader6;
|
||||
final Color shader7;
|
||||
final Color bg1;
|
||||
final Color bg2;
|
||||
final Color bg3;
|
||||
final Color bg4;
|
||||
final Color tint1;
|
||||
final Color tint2;
|
||||
final Color tint3;
|
||||
final Color tint4;
|
||||
final Color tint5;
|
||||
final Color tint6;
|
||||
final Color tint7;
|
||||
final Color tint8;
|
||||
final Color tint9;
|
||||
final Color main1;
|
||||
final Color main2;
|
||||
final Color shadow;
|
||||
|
||||
const FlowyColorScheme({
|
||||
required this.surface,
|
||||
required this.hover,
|
||||
required this.selector,
|
||||
required this.red,
|
||||
required this.yellow,
|
||||
required this.green,
|
||||
required this.shader1,
|
||||
required this.shader2,
|
||||
required this.shader3,
|
||||
required this.shader4,
|
||||
required this.shader5,
|
||||
required this.shader6,
|
||||
required this.shader7,
|
||||
required this.bg1,
|
||||
required this.bg2,
|
||||
required this.bg3,
|
||||
required this.bg4,
|
||||
required this.tint1,
|
||||
required this.tint2,
|
||||
required this.tint3,
|
||||
required this.tint4,
|
||||
required this.tint5,
|
||||
required this.tint6,
|
||||
required this.tint7,
|
||||
required this.tint8,
|
||||
required this.tint9,
|
||||
required this.main1,
|
||||
required this.main2,
|
||||
required this.shadow,
|
||||
});
|
||||
|
||||
factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) {
|
||||
switch (brightness) {
|
||||
case Brightness.light:
|
||||
return const DefaultColorScheme.light();
|
||||
case Brightness.dark:
|
||||
return 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 DefaultColorScheme extends FlowyColorScheme {
|
||||
const DefaultColorScheme.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(0xfff7f8fc),
|
||||
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(0xff00bcf0),
|
||||
main2: const Color(0xff00b7ea),
|
||||
shadow: _black,
|
||||
);
|
||||
|
||||
const DefaultColorScheme.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: _black,
|
||||
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(0xff00bcf0),
|
||||
main2: const Color(0xff009cc7),
|
||||
shadow: _black,
|
||||
);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TextStyles {
|
||||
final String font;
|
||||
final Color color;
|
||||
|
||||
TextStyles({
|
||||
required this.font,
|
||||
required this.color,
|
||||
});
|
||||
|
||||
TextStyle getFontStyle({
|
||||
String? fontFamily,
|
||||
double? fontSize,
|
||||
FontWeight? fontWeight,
|
||||
Color? fontColor,
|
||||
double? letterSpacing,
|
||||
double? lineHeight,
|
||||
}) =>
|
||||
TextStyle(
|
||||
fontFamily: fontFamily ?? font,
|
||||
fontSize: fontSize ?? FontSizes.s12,
|
||||
color: fontColor ?? color,
|
||||
fontWeight: fontWeight ?? FontWeight.w500,
|
||||
fontFamilyFallback: const ["Noto Color Emoji"],
|
||||
letterSpacing: (fontSize ?? FontSizes.s12) * (letterSpacing ?? 0.005),
|
||||
height: lineHeight,
|
||||
);
|
||||
|
||||
TextTheme generateTextTheme() {
|
||||
return TextTheme(
|
||||
displayLarge: getFontStyle(
|
||||
fontSize: FontSizes.s32,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 42.0,
|
||||
), // h2
|
||||
displayMedium: getFontStyle(
|
||||
fontSize: FontSizes.s24,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 34.0,
|
||||
), // h3
|
||||
displaySmall: getFontStyle(
|
||||
fontSize: FontSizes.s20,
|
||||
fontWeight: FontWeight.w600,
|
||||
lineHeight: 28.0,
|
||||
), // h4
|
||||
titleLarge: getFontStyle(
|
||||
fontSize: FontSizes.s18,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // title
|
||||
titleMedium: getFontStyle(
|
||||
fontSize: FontSizes.s16,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // heading
|
||||
titleSmall: getFontStyle(
|
||||
fontSize: FontSizes.s14,
|
||||
fontWeight: FontWeight.w600,
|
||||
), // subheading
|
||||
bodyMedium: getFontStyle(), // body-regular
|
||||
bodySmall: getFontStyle(fontWeight: FontWeight.w400), // body-thin
|
||||
);
|
||||
}
|
||||
}
|
@ -1,267 +1,37 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/text_style.dart';
|
||||
import 'package:flowy_infra/colorscheme/colorscheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'theme_extension.dart';
|
||||
|
||||
Brightness themeTypeFromString(String name) {
|
||||
Brightness themeType = Brightness.light;
|
||||
if (name == "dark") {
|
||||
themeType = Brightness.dark;
|
||||
}
|
||||
return themeType;
|
||||
}
|
||||
|
||||
String themeTypeToString(Brightness brightness) {
|
||||
switch (brightness) {
|
||||
case Brightness.light:
|
||||
return "light";
|
||||
case Brightness.dark:
|
||||
return "dark";
|
||||
}
|
||||
}
|
||||
|
||||
// Color Palettes
|
||||
const _black = Color(0xff000000);
|
||||
const _white = Color(0xFFFFFFFF);
|
||||
const List<String> builtInThemes = [
|
||||
'light',
|
||||
];
|
||||
|
||||
class AppTheme {
|
||||
Brightness brightness;
|
||||
// metadata member
|
||||
final FlowyColorScheme lightTheme;
|
||||
final FlowyColorScheme darkTheme;
|
||||
// static final Map<String, dynamic> _cachedJsonData = {};
|
||||
|
||||
late Color surface;
|
||||
late Color hover;
|
||||
late Color selector;
|
||||
late Color red;
|
||||
late Color yellow;
|
||||
late Color green;
|
||||
const AppTheme({
|
||||
required this.lightTheme,
|
||||
required this.darkTheme,
|
||||
});
|
||||
|
||||
late Color shader1;
|
||||
late Color shader2;
|
||||
late Color shader3;
|
||||
late Color shader4;
|
||||
late Color shader5;
|
||||
late Color shader6;
|
||||
late Color shader7;
|
||||
|
||||
late Color bg1;
|
||||
late Color bg2;
|
||||
late Color bg3;
|
||||
late Color bg4;
|
||||
|
||||
late Color tint1;
|
||||
late Color tint2;
|
||||
late Color tint3;
|
||||
late Color tint4;
|
||||
late Color tint5;
|
||||
late Color tint6;
|
||||
late Color tint7;
|
||||
late Color tint8;
|
||||
late Color tint9;
|
||||
|
||||
late Color textColor;
|
||||
late Color iconColor;
|
||||
late Color disableIconColor;
|
||||
|
||||
late Color main1;
|
||||
late Color main2;
|
||||
|
||||
late Color shadow;
|
||||
|
||||
late String font;
|
||||
late String monospaceFont;
|
||||
|
||||
/// Default constructor
|
||||
AppTheme({this.brightness = Brightness.light});
|
||||
|
||||
factory AppTheme.fromBrightness({
|
||||
required Brightness brightness,
|
||||
required String font,
|
||||
required String monospaceFont,
|
||||
}) {
|
||||
switch (brightness) {
|
||||
case Brightness.light:
|
||||
return AppTheme(brightness: Brightness.light)
|
||||
..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(0xfff7f8fc)
|
||||
..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(0xff00bcf0)
|
||||
..main2 = const Color(0xff00b7ea)
|
||||
..textColor = _black
|
||||
..iconColor = _black
|
||||
..shadow = _black
|
||||
..disableIconColor = const Color(0xffbdbdbd)
|
||||
..font = font
|
||||
..monospaceFont = monospaceFont;
|
||||
|
||||
case Brightness.dark:
|
||||
return AppTheme(brightness: Brightness.dark)
|
||||
..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 = _black
|
||||
..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(0xff00bcf0)
|
||||
..main2 = const Color(0xff009cc7)
|
||||
..textColor = _white
|
||||
..iconColor = _white
|
||||
..shadow = _black
|
||||
..disableIconColor = const Color(0xff333333)
|
||||
..font = font
|
||||
..monospaceFont = monospaceFont;
|
||||
}
|
||||
}
|
||||
|
||||
ThemeData getThemeData(Locale locale) {
|
||||
// Poppins and SF Mono are not well supported in some languages, so use the
|
||||
// built-in font for the following languages.
|
||||
final useBuiltInFontLanguages = [
|
||||
const Locale('zh', 'CN'),
|
||||
const Locale('zh', 'TW'),
|
||||
];
|
||||
TextStyles textTheme;
|
||||
if (useBuiltInFontLanguages.contains(locale)) {
|
||||
textTheme = TextStyles(font: '', color: shader1);
|
||||
} else {
|
||||
textTheme = TextStyles(font: font, color: shader1);
|
||||
}
|
||||
return ThemeData(
|
||||
brightness: brightness,
|
||||
textTheme: textTheme.generateTextTheme(),
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
cursorColor: main2,
|
||||
selectionHandleColor: main2,
|
||||
),
|
||||
primaryIconTheme: IconThemeData(color: hover),
|
||||
iconTheme: IconThemeData(color: shader1),
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbColor: MaterialStateProperty.all(Colors.transparent),
|
||||
),
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
canvasColor: shader6,
|
||||
dividerColor: shader6,
|
||||
hintColor: shader3,
|
||||
disabledColor: shader4,
|
||||
highlightColor: main1,
|
||||
indicatorColor: main1,
|
||||
toggleableActiveColor: main1,
|
||||
colorScheme: ColorScheme(
|
||||
brightness: brightness,
|
||||
primary: main1,
|
||||
onPrimary: _white,
|
||||
primaryContainer: main2,
|
||||
onPrimaryContainer: _white,
|
||||
secondary: hover,
|
||||
onSecondary: shader1,
|
||||
secondaryContainer: selector,
|
||||
onSecondaryContainer: shader1,
|
||||
background: surface,
|
||||
onBackground: shader1,
|
||||
surface: surface,
|
||||
onSurface: shader1,
|
||||
onError: shader7,
|
||||
error: red,
|
||||
outline: shader4,
|
||||
surfaceVariant: bg1,
|
||||
shadow: shadow,
|
||||
),
|
||||
extensions: [
|
||||
AFThemeExtension(
|
||||
warning: yellow,
|
||||
success: green,
|
||||
tint1: tint1,
|
||||
tint2: tint2,
|
||||
tint3: tint3,
|
||||
tint4: tint4,
|
||||
tint5: tint5,
|
||||
tint6: tint6,
|
||||
tint7: tint7,
|
||||
tint8: tint8,
|
||||
tint9: tint9,
|
||||
greyHover: bg2,
|
||||
greySelect: bg3,
|
||||
lightGreyHover: shader6,
|
||||
toggleOffFill: shader5,
|
||||
code: textTheme.getFontStyle(fontFamily: monospaceFont),
|
||||
callout: textTheme.getFontStyle(
|
||||
fontSize: FontSizes.s11,
|
||||
fontColor: shader3,
|
||||
),
|
||||
caption: textTheme.getFontStyle(
|
||||
fontSize: FontSizes.s11,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontColor: shader3,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Color shift(Color c, double d) =>
|
||||
ColorUtils.shiftHsl(c, d * (brightness == Brightness.dark ? -1 : 1));
|
||||
}
|
||||
|
||||
class ColorUtils {
|
||||
static Color shiftHsl(Color c, [double amt = 0]) {
|
||||
var hslc = HSLColor.fromColor(c);
|
||||
return hslc.withLightness((hslc.lightness + amt).clamp(0.0, 1.0)).toColor();
|
||||
}
|
||||
|
||||
static Color parseHex(String value) =>
|
||||
Color(int.parse(value.substring(1, 7), radix: 16) + 0xFF000000);
|
||||
|
||||
static Color blend(Color dst, Color src, double opacity) {
|
||||
return Color.fromARGB(
|
||||
255,
|
||||
(dst.red.toDouble() * (1.0 - opacity) + src.red.toDouble() * opacity)
|
||||
.toInt(),
|
||||
(dst.green.toDouble() * (1.0 - opacity) + src.green.toDouble() * opacity)
|
||||
.toInt(),
|
||||
(dst.blue.toDouble() * (1.0 - opacity) + src.blue.toDouble() * opacity)
|
||||
.toInt(),
|
||||
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),
|
||||
// );
|
||||
// }
|
||||
return AppTheme(
|
||||
lightTheme: FlowyColorScheme.builtIn(themeName, Brightness.light),
|
||||
darkTheme: FlowyColorScheme.builtIn(themeName, Brightness.dark),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,10 @@ void main() {
|
||||
'default theme',
|
||||
build: () => AppearanceSettingsCubit(appearanceSetting),
|
||||
verify: (bloc) {
|
||||
expect(bloc.state.theme.brightness, Brightness.light);
|
||||
// expect(bloc.state.appTheme.info.name, "light");
|
||||
expect(bloc.state.font, 'Poppins');
|
||||
expect(bloc.state.monospaceFont, 'SF Mono');
|
||||
expect(bloc.state.themeMode, ThemeMode.system);
|
||||
},
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user