mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-11-09 23:46:19 +03:00
feat: switch between light and dark theme based on system settings (#1523)
* feat: allow listening to system for light/dark theme * chore: implement UI for theme mode setting * chore: fix translations
This commit is contained in:
parent
f81d5eb23e
commit
442dfe7ef8
@ -138,12 +138,16 @@
|
|||||||
"open": "Obrir la configuració"
|
"open": "Obrir la configuració"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Mode Clar",
|
"themeMode": {
|
||||||
"darkLabel": "Mode Fosc"
|
"label": "Theme Mode",
|
||||||
|
"light": "Mode Clar",
|
||||||
|
"dark": "Mode Fosc",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -158,8 +158,12 @@
|
|||||||
"open": "Open Settings"
|
"open": "Open Settings"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Light Mode",
|
"themeMode": {
|
||||||
"darkLabel": "Dark Mode"
|
"label": "Theme Mode",
|
||||||
|
"light": "Light Mode",
|
||||||
|
"dark": "Dark Mode",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -144,8 +144,12 @@
|
|||||||
"open": "Abrir ajustes"
|
"open": "Abrir ajustes"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Modo Claro",
|
"themeMode": {
|
||||||
"darkLabel": "Modo Oscuro"
|
"label": "Theme Mode",
|
||||||
|
"light": "Modo Claro",
|
||||||
|
"dark": "Modo Oscuro",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
@ -218,9 +222,9 @@
|
|||||||
"openSidebar": "Abrir panel lateral",
|
"openSidebar": "Abrir panel lateral",
|
||||||
"closeSidebar": "Cerrar panel lateral"
|
"closeSidebar": "Cerrar panel lateral"
|
||||||
},
|
},
|
||||||
"board": {
|
"board": {
|
||||||
"column": {
|
"column": {
|
||||||
"create_new_card": "Nuevo"
|
"create_new_card": "Nuevo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -138,12 +138,16 @@
|
|||||||
"open": "Ouvrir les paramètres"
|
"open": "Ouvrir les paramètres"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Mode clair",
|
"themeMode": {
|
||||||
"darkLabel": "Mode sombre"
|
"label": "Theme Mode",
|
||||||
|
"light": "Mode clair",
|
||||||
|
"dark": "Mode sombre",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -152,8 +152,12 @@
|
|||||||
"open": "Ouvrir les paramètres"
|
"open": "Ouvrir les paramètres"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Mode clair",
|
"themeMode": {
|
||||||
"darkLabel": "Mode sombre"
|
"label": "Theme Mode",
|
||||||
|
"light": "Mode clair",
|
||||||
|
"dark": "Mode sombre",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -138,12 +138,16 @@
|
|||||||
"open": "Beállítások megnyitása"
|
"open": "Beállítások megnyitása"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Világos mód",
|
"themeMode": {
|
||||||
"darkLabel": "Éjjeli mód"
|
"label": "Theme Mode",
|
||||||
|
"light": "Világos mód",
|
||||||
|
"dark": "Éjjeli mód",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -145,8 +145,12 @@
|
|||||||
"open": "Buka Pengaturan"
|
"open": "Buka Pengaturan"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Mode Terang",
|
"themeMode": {
|
||||||
"darkLabel": "Mode Gelap"
|
"label": "Theme Mode",
|
||||||
|
"light": "Mode Terang",
|
||||||
|
"dark": "Mode Gelap",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -138,18 +138,22 @@
|
|||||||
"open": "aprire le impostazioni"
|
"open": "aprire le impostazioni"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Modalità Chiara",
|
"themeMode": {
|
||||||
"darkLabel": "Modalità Scura"
|
"label": "Theme Mode",
|
||||||
|
"light": "Modalità Chiara",
|
||||||
|
"dark": "Modalità Scura",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
"menuName":"Griglia"
|
"menuName": "Griglia"
|
||||||
},
|
},
|
||||||
"document":{
|
"document": {
|
||||||
"menuName":"Documento"
|
"menuName": "Documento"
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -138,8 +138,12 @@
|
|||||||
"open": "設定"
|
"open": "設定"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "ライトモード",
|
"themeMode": {
|
||||||
"darkLabel": "ダークモード"
|
"label": "Theme Mode",
|
||||||
|
"light": "ライトモード",
|
||||||
|
"dark": "ダークモード",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -138,12 +138,16 @@
|
|||||||
"open": "Otwórz Ustawienia"
|
"open": "Otwórz Ustawienia"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Tryb Jasny",
|
"themeMode": {
|
||||||
"darkLabel": "Tryb Ciemny"
|
"label": "Theme Mode",
|
||||||
|
"light": "Tryb Jasny",
|
||||||
|
"dark": "Tryb Ciemny",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -152,8 +152,12 @@
|
|||||||
"open": "Abrir as Configurações"
|
"open": "Abrir as Configurações"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Modo Claro",
|
"themeMode": {
|
||||||
"darkLabel": "Modo Escuro"
|
"label": "Theme Mode",
|
||||||
|
"light": "Modo Claro",
|
||||||
|
"dark": "Modo Escuro",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -151,8 +151,12 @@
|
|||||||
"open": "Открыть настройки"
|
"open": "Открыть настройки"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Светлая",
|
"themeMode": {
|
||||||
"darkLabel": "Тёмная"
|
"label": "Theme Mode",
|
||||||
|
"light": "Светлая",
|
||||||
|
"dark": "Тёмная",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -152,8 +152,12 @@
|
|||||||
"open": "Öppna inställningarna"
|
"open": "Öppna inställningarna"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Ljust läge",
|
"themeMode": {
|
||||||
"darkLabel": "Mörkt läge"
|
"label": "Theme Mode",
|
||||||
|
"light": "Ljust läge",
|
||||||
|
"dark": "Mörkt läge",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
@ -232,4 +236,4 @@
|
|||||||
"create_new_card": "Nytt"
|
"create_new_card": "Nytt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -138,12 +138,16 @@
|
|||||||
"open": "Ayarları Aç"
|
"open": "Ayarları Aç"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "Aydınlık Mod",
|
"themeMode": {
|
||||||
"darkLabel": "Karanlık Mod"
|
"label": "Theme Mode",
|
||||||
|
"light": "Aydınlık Mod",
|
||||||
|
"dark": "Karanlık Mod",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"sideBar": {
|
||||||
"openSidebar": "Open sidebar",
|
"openSidebar": "Open sidebar",
|
||||||
"closeSidebar": "Close sidebar"
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -152,8 +152,12 @@
|
|||||||
"open": "打开设置"
|
"open": "打开设置"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "日间模式",
|
"themeMode": {
|
||||||
"darkLabel": "夜间模式"
|
"label": "Theme Mode",
|
||||||
|
"light": "日间模式",
|
||||||
|
"dark": "夜间模式",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -145,8 +145,12 @@
|
|||||||
"open": "開啟設定"
|
"open": "開啟設定"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"lightLabel": "亮色模式",
|
"themeMode": {
|
||||||
"darkLabel": "暗色模式"
|
"label": "Theme Mode",
|
||||||
|
"light": "亮色模式",
|
||||||
|
"dark": "暗色模式",
|
||||||
|
"system": "Adapt to System"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grid": {
|
"grid": {
|
||||||
|
@ -83,6 +83,8 @@ class ApplicationWidget extends StatelessWidget {
|
|||||||
builder: overlayManagerBuilder(),
|
builder: overlayManagerBuilder(),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: state.theme.getThemeData(state.locale),
|
theme: state.theme.getThemeData(state.locale),
|
||||||
|
darkTheme: state.darkTheme.getThemeData(state.locale),
|
||||||
|
themeMode: state.themeMode,
|
||||||
localizationsDelegates: context.localizationDelegates +
|
localizationsDelegates: context.localizationDelegates +
|
||||||
[AppFlowyEditorLocalizations.delegate],
|
[AppFlowyEditorLocalizations.delegate],
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
|
@ -19,6 +19,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
: _setting = setting,
|
: _setting = setting,
|
||||||
super(AppearanceSettingsState.initial(
|
super(AppearanceSettingsState.initial(
|
||||||
setting.theme,
|
setting.theme,
|
||||||
|
setting.themeMode,
|
||||||
setting.font,
|
setting.font,
|
||||||
setting.monospaceFont,
|
setting.monospaceFont,
|
||||||
setting.locale,
|
setting.locale,
|
||||||
@ -26,21 +27,34 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
|
|
||||||
/// Updates the current theme and notify the listeners the theme was changed.
|
/// 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.
|
/// Do nothing if the passed in themeType equal to the current theme type.
|
||||||
void setTheme(Brightness brightness) {
|
// void setTheme(Brightness brightness) {
|
||||||
if (state.theme.brightness == brightness) {
|
// if (state.theme.brightness == brightness) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// _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.
|
||||||
|
void setThemeMode(ThemeMode themeMode) {
|
||||||
|
if (state.themeMode == themeMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_setting.theme = themeTypeToString(brightness);
|
_setting.themeMode = _themeModeToPB(themeMode);
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(themeMode: themeMode));
|
||||||
theme: AppTheme.fromName(
|
|
||||||
themeName: _setting.theme,
|
|
||||||
font: state.theme.font,
|
|
||||||
monospaceFont: state.theme.monospaceFont,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the current locale and notify the listeners the locale was changed
|
/// Updates the current locale and notify the listeners the locale was changed
|
||||||
@ -115,25 +129,58 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThemeMode _themeModeFromPB(ThemeModePB themeModePB) {
|
||||||
|
switch (themeModePB) {
|
||||||
|
case ThemeModePB.Light:
|
||||||
|
return ThemeMode.light;
|
||||||
|
case ThemeModePB.Dark:
|
||||||
|
return ThemeMode.dark;
|
||||||
|
case ThemeModePB.System:
|
||||||
|
default:
|
||||||
|
return ThemeMode.system;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeModePB _themeModeToPB(ThemeMode themeMode) {
|
||||||
|
switch (themeMode) {
|
||||||
|
case ThemeMode.light:
|
||||||
|
return ThemeModePB.Light;
|
||||||
|
case ThemeMode.dark:
|
||||||
|
return ThemeModePB.Dark;
|
||||||
|
case ThemeMode.system:
|
||||||
|
default:
|
||||||
|
return ThemeModePB.System;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class AppearanceSettingsState with _$AppearanceSettingsState {
|
class AppearanceSettingsState with _$AppearanceSettingsState {
|
||||||
const factory AppearanceSettingsState({
|
const factory AppearanceSettingsState({
|
||||||
required AppTheme theme,
|
required AppTheme theme,
|
||||||
|
required AppTheme darkTheme,
|
||||||
|
required ThemeMode themeMode,
|
||||||
required Locale locale,
|
required Locale locale,
|
||||||
}) = _AppearanceSettingsState;
|
}) = _AppearanceSettingsState;
|
||||||
|
|
||||||
factory AppearanceSettingsState.initial(
|
factory AppearanceSettingsState.initial(
|
||||||
String themeName,
|
String themeName,
|
||||||
|
ThemeModePB themeMode,
|
||||||
String font,
|
String font,
|
||||||
String monospaceFont,
|
String monospaceFont,
|
||||||
LocaleSettingsPB locale,
|
LocaleSettingsPB locale,
|
||||||
) =>
|
) =>
|
||||||
AppearanceSettingsState(
|
AppearanceSettingsState(
|
||||||
theme: AppTheme.fromName(
|
theme: AppTheme.fromBrightness(
|
||||||
themeName: themeName,
|
brightness: Brightness.light,
|
||||||
font: font,
|
font: font,
|
||||||
monospaceFont: monospaceFont,
|
monospaceFont: monospaceFont,
|
||||||
),
|
),
|
||||||
|
darkTheme: AppTheme.fromBrightness(
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
font: font,
|
||||||
|
monospaceFont: monospaceFont,
|
||||||
|
),
|
||||||
|
themeMode: _themeModeFromPB(themeMode),
|
||||||
locale: Locale(locale.languageCode, locale.countryCode),
|
locale: Locale(locale.languageCode, locale.countryCode),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,99 @@
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle_style.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_ui/style_widget/text.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../../widgets/toggle/toggle.dart';
|
|
||||||
|
|
||||||
class SettingsAppearanceView extends StatelessWidget {
|
class SettingsAppearanceView extends StatelessWidget {
|
||||||
const SettingsAppearanceView({Key? key}) : super(key: key);
|
const SettingsAppearanceView({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: BlocBuilder<AppearanceSettingsCubit, AppearanceSettingsState>(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
builder: (context, state) {
|
||||||
children: [
|
return Column(
|
||||||
Row(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
FlowyText.medium(LocaleKeys.settings_appearance_lightLabel.tr()),
|
ThemeModeSetting(currentThemeMode: state.themeMode),
|
||||||
Toggle(
|
|
||||||
value: Theme.of(context).brightness == Brightness.dark,
|
|
||||||
onChanged: (_) => setTheme(context),
|
|
||||||
style: ToggleStyle.big,
|
|
||||||
),
|
|
||||||
FlowyText.medium(LocaleKeys.settings_appearance_darkLabel.tr())
|
|
||||||
],
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThemeModeSetting extends StatelessWidget {
|
||||||
|
final ThemeMode currentThemeMode;
|
||||||
|
const ThemeModeSetting({required this.currentThemeMode, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: FlowyText.medium(
|
||||||
|
LocaleKeys.settings_appearance_themeMode_label.tr(),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
AppFlowyPopover(
|
||||||
|
direction: PopoverDirection.bottomWithRightAligned,
|
||||||
|
child: FlowyTextButton(
|
||||||
|
_themeModeLabelText(currentThemeMode),
|
||||||
|
fillColor: Colors.transparent,
|
||||||
|
hoverColor: Theme.of(context).colorScheme.secondary,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
popupBuilder: (BuildContext context) {
|
||||||
|
return IntrinsicWidth(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_themeModeItemButton(context, ThemeMode.light),
|
||||||
|
_themeModeItemButton(context, ThemeMode.dark),
|
||||||
|
_themeModeItemButton(context, ThemeMode.system),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _themeModeItemButton(BuildContext context, ThemeMode themeMode) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 32,
|
||||||
|
child: FlowyButton(
|
||||||
|
text: FlowyText.medium(_themeModeLabelText(themeMode)),
|
||||||
|
rightIcon: currentThemeMode == themeMode
|
||||||
|
? svgWidget("grid/checkmark")
|
||||||
|
: const SizedBox(),
|
||||||
|
onTap: () {
|
||||||
|
if (currentThemeMode != themeMode) {
|
||||||
|
context.read<AppearanceSettingsCubit>().setThemeMode(themeMode);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTheme(BuildContext context) {
|
String _themeModeLabelText(ThemeMode themeMode) {
|
||||||
if (Theme.of(context).brightness == Brightness.dark) {
|
switch (themeMode) {
|
||||||
context.read<AppearanceSettingsCubit>().setTheme(Brightness.light);
|
case (ThemeMode.light):
|
||||||
} else {
|
return LocaleKeys.settings_appearance_themeMode_light.tr();
|
||||||
context.read<AppearanceSettingsCubit>().setTheme(Brightness.dark);
|
case (ThemeMode.dark):
|
||||||
|
return LocaleKeys.settings_appearance_themeMode_dark.tr();
|
||||||
|
case (ThemeMode.system):
|
||||||
|
return LocaleKeys.settings_appearance_themeMode_system.tr();
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,12 @@ class AppTheme {
|
|||||||
/// Default constructor
|
/// Default constructor
|
||||||
AppTheme({this.brightness = Brightness.light});
|
AppTheme({this.brightness = Brightness.light});
|
||||||
|
|
||||||
factory AppTheme.fromName({
|
factory AppTheme.fromBrightness({
|
||||||
required String themeName,
|
required Brightness brightness,
|
||||||
required String font,
|
required String font,
|
||||||
required String monospaceFont,
|
required String monospaceFont,
|
||||||
}) {
|
}) {
|
||||||
switch (themeTypeFromString(themeName)) {
|
switch (brightness) {
|
||||||
case Brightness.light:
|
case Brightness.light:
|
||||||
return AppTheme(brightness: Brightness.light)
|
return AppTheme(brightness: Brightness.light)
|
||||||
..surface = Colors.white
|
..surface = Colors.white
|
||||||
|
@ -63,7 +63,9 @@ class FlowyButton extends StatelessWidget {
|
|||||||
children.add(Expanded(child: text));
|
children.add(Expanded(child: text));
|
||||||
|
|
||||||
if (rightIcon != null) {
|
if (rightIcon != null) {
|
||||||
children.add(rightIcon!);
|
children.add(const HSpace(6));
|
||||||
|
children.add(
|
||||||
|
SizedBox.fromSize(size: const Size.square(16), child: rightIcon!));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget child = Row(
|
Widget child = Row(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -17,26 +17,43 @@ pub struct AppearanceSettingsPB {
|
|||||||
pub theme: String,
|
pub theme: String,
|
||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub font: String,
|
#[serde(default)]
|
||||||
|
pub theme_mode: ThemeModePB,
|
||||||
|
|
||||||
#[pb(index = 3)]
|
#[pb(index = 3)]
|
||||||
pub monospace_font: String,
|
pub font: String,
|
||||||
|
|
||||||
#[pb(index = 4)]
|
#[pb(index = 4)]
|
||||||
|
pub monospace_font: String,
|
||||||
|
|
||||||
|
#[pb(index = 5)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub locale: LocaleSettingsPB,
|
pub locale: LocaleSettingsPB,
|
||||||
|
|
||||||
#[pb(index = 5)]
|
#[pb(index = 6)]
|
||||||
#[serde(default = "DEFAULT_RESET_VALUE")]
|
#[serde(default = "DEFAULT_RESET_VALUE")]
|
||||||
pub reset_to_default: bool,
|
pub reset_to_default: bool,
|
||||||
|
|
||||||
#[pb(index = 6)]
|
#[pb(index = 7)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub setting_key_value: HashMap<String, String>,
|
pub setting_key_value: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_RESET_VALUE: fn() -> bool = || APPEARANCE_RESET_AS_DEFAULT;
|
const DEFAULT_RESET_VALUE: fn() -> bool = || APPEARANCE_RESET_AS_DEFAULT;
|
||||||
|
|
||||||
|
#[derive(ProtoBuf_Enum, Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub enum ThemeModePB {
|
||||||
|
Light = 0,
|
||||||
|
Dark = 1,
|
||||||
|
System = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for ThemeModePB {
|
||||||
|
fn default() -> Self {
|
||||||
|
ThemeModePB::System
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Serialize, Deserialize, Debug, Clone)]
|
#[derive(ProtoBuf, Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct LocaleSettingsPB {
|
pub struct LocaleSettingsPB {
|
||||||
#[pb(index = 1)]
|
#[pb(index = 1)]
|
||||||
@ -64,6 +81,7 @@ impl std::default::Default for AppearanceSettingsPB {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
AppearanceSettingsPB {
|
AppearanceSettingsPB {
|
||||||
theme: APPEARANCE_DEFAULT_THEME.to_owned(),
|
theme: APPEARANCE_DEFAULT_THEME.to_owned(),
|
||||||
|
theme_mode: ThemeModePB::default(),
|
||||||
font: APPEARANCE_DEFAULT_FONT.to_owned(),
|
font: APPEARANCE_DEFAULT_FONT.to_owned(),
|
||||||
monospace_font: APPEARANCE_DEFAULT_MONOSPACE_FONT.to_owned(),
|
monospace_font: APPEARANCE_DEFAULT_MONOSPACE_FONT.to_owned(),
|
||||||
locale: LocaleSettingsPB::default(),
|
locale: LocaleSettingsPB::default(),
|
||||||
|
Loading…
Reference in New Issue
Block a user