From 442dfe7ef80eba8a4f8d8102659cb8d05ef3e07c Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:21:11 +0800 Subject: [PATCH] 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 --- .../app_flowy/assets/translations/ca-ES.json | 10 +- .../app_flowy/assets/translations/en.json | 8 +- .../app_flowy/assets/translations/es-VE.json | 12 ++- .../app_flowy/assets/translations/fr-CA.json | 10 +- .../app_flowy/assets/translations/fr-FR.json | 8 +- .../app_flowy/assets/translations/hu-HU.json | 10 +- .../app_flowy/assets/translations/id-ID.json | 8 +- .../app_flowy/assets/translations/it-IT.json | 16 +-- .../app_flowy/assets/translations/ja-JP.json | 8 +- .../app_flowy/assets/translations/pl-PL.json | 10 +- .../app_flowy/assets/translations/pt-BR.json | 8 +- .../app_flowy/assets/translations/ru-RU.json | 8 +- .../app_flowy/assets/translations/sv.json | 10 +- .../app_flowy/assets/translations/tr-TR.json | 10 +- .../app_flowy/assets/translations/zh-CN.json | 8 +- .../app_flowy/assets/translations/zh-TW.json | 8 +- .../lib/startup/tasks/app_widget.dart | 2 + .../lib/workspace/application/appearance.dart | 71 +++++++++++--- .../widgets/settings_appearance_view.dart | 98 +++++++++++++++---- .../packages/flowy_infra/lib/theme.dart | 6 +- .../lib/style_widget/button.dart | 4 +- .../flowy-user/src/entities/user_setting.rs | 28 +++++- 22 files changed, 275 insertions(+), 86 deletions(-) diff --git a/frontend/app_flowy/assets/translations/ca-ES.json b/frontend/app_flowy/assets/translations/ca-ES.json index 23ae51bd69..3c9c583e98 100644 --- a/frontend/app_flowy/assets/translations/ca-ES.json +++ b/frontend/app_flowy/assets/translations/ca-ES.json @@ -138,12 +138,16 @@ "open": "Obrir la configuració" }, "appearance": { - "lightLabel": "Mode Clar", - "darkLabel": "Mode Fosc" + "themeMode": { + "label": "Theme Mode", + "light": "Mode Clar", + "dark": "Mode Fosc", + "system": "Adapt to System" + } } }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 6d36ead2cf..7abd071e7d 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -158,8 +158,12 @@ "open": "Open Settings" }, "appearance": { - "lightLabel": "Light Mode", - "darkLabel": "Dark Mode" + "themeMode": { + "label": "Theme Mode", + "light": "Light Mode", + "dark": "Dark Mode", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/es-VE.json b/frontend/app_flowy/assets/translations/es-VE.json index f928c18cda..eb51cbbc14 100644 --- a/frontend/app_flowy/assets/translations/es-VE.json +++ b/frontend/app_flowy/assets/translations/es-VE.json @@ -144,8 +144,12 @@ "open": "Abrir ajustes" }, "appearance": { - "lightLabel": "Modo Claro", - "darkLabel": "Modo Oscuro" + "themeMode": { + "label": "Theme Mode", + "light": "Modo Claro", + "dark": "Modo Oscuro", + "system": "Adapt to System" + } } }, "grid": { @@ -218,9 +222,9 @@ "openSidebar": "Abrir panel lateral", "closeSidebar": "Cerrar panel lateral" }, - "board": { + "board": { "column": { "create_new_card": "Nuevo" } } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/fr-CA.json b/frontend/app_flowy/assets/translations/fr-CA.json index ff7f5ca251..829f2a7d89 100644 --- a/frontend/app_flowy/assets/translations/fr-CA.json +++ b/frontend/app_flowy/assets/translations/fr-CA.json @@ -138,12 +138,16 @@ "open": "Ouvrir les paramètres" }, "appearance": { - "lightLabel": "Mode clair", - "darkLabel": "Mode sombre" + "themeMode": { + "label": "Theme Mode", + "light": "Mode clair", + "dark": "Mode sombre", + "system": "Adapt to System" + } } }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/fr-FR.json b/frontend/app_flowy/assets/translations/fr-FR.json index 0900cafa2f..c93d51f441 100644 --- a/frontend/app_flowy/assets/translations/fr-FR.json +++ b/frontend/app_flowy/assets/translations/fr-FR.json @@ -152,8 +152,12 @@ "open": "Ouvrir les paramètres" }, "appearance": { - "lightLabel": "Mode clair", - "darkLabel": "Mode sombre" + "themeMode": { + "label": "Theme Mode", + "light": "Mode clair", + "dark": "Mode sombre", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/hu-HU.json b/frontend/app_flowy/assets/translations/hu-HU.json index 7428f48520..17034d3c7b 100644 --- a/frontend/app_flowy/assets/translations/hu-HU.json +++ b/frontend/app_flowy/assets/translations/hu-HU.json @@ -138,12 +138,16 @@ "open": "Beállítások megnyitása" }, "appearance": { - "lightLabel": "Világos mód", - "darkLabel": "Éjjeli mód" + "themeMode": { + "label": "Theme Mode", + "light": "Világos mód", + "dark": "Éjjeli mód", + "system": "Adapt to System" + } } }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/id-ID.json b/frontend/app_flowy/assets/translations/id-ID.json index 38f4e7d805..c0b83dc285 100644 --- a/frontend/app_flowy/assets/translations/id-ID.json +++ b/frontend/app_flowy/assets/translations/id-ID.json @@ -145,8 +145,12 @@ "open": "Buka Pengaturan" }, "appearance": { - "lightLabel": "Mode Terang", - "darkLabel": "Mode Gelap" + "themeMode": { + "label": "Theme Mode", + "light": "Mode Terang", + "dark": "Mode Gelap", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/it-IT.json b/frontend/app_flowy/assets/translations/it-IT.json index 3433eb4d8e..cf2e19d9e6 100644 --- a/frontend/app_flowy/assets/translations/it-IT.json +++ b/frontend/app_flowy/assets/translations/it-IT.json @@ -138,18 +138,22 @@ "open": "aprire le impostazioni" }, "appearance": { - "lightLabel": "Modalità Chiara", - "darkLabel": "Modalità Scura" + "themeMode": { + "label": "Theme Mode", + "light": "Modalità Chiara", + "dark": "Modalità Scura", + "system": "Adapt to System" + } } }, "grid": { - "menuName":"Griglia" + "menuName": "Griglia" }, - "document":{ - "menuName":"Documento" + "document": { + "menuName": "Documento" }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/ja-JP.json b/frontend/app_flowy/assets/translations/ja-JP.json index 793604212c..65e94de992 100644 --- a/frontend/app_flowy/assets/translations/ja-JP.json +++ b/frontend/app_flowy/assets/translations/ja-JP.json @@ -138,8 +138,12 @@ "open": "設定" }, "appearance": { - "lightLabel": "ライトモード", - "darkLabel": "ダークモード" + "themeMode": { + "label": "Theme Mode", + "light": "ライトモード", + "dark": "ダークモード", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/pl-PL.json b/frontend/app_flowy/assets/translations/pl-PL.json index ba6c4e1861..03e7cfd284 100644 --- a/frontend/app_flowy/assets/translations/pl-PL.json +++ b/frontend/app_flowy/assets/translations/pl-PL.json @@ -138,12 +138,16 @@ "open": "Otwórz Ustawienia" }, "appearance": { - "lightLabel": "Tryb Jasny", - "darkLabel": "Tryb Ciemny" + "themeMode": { + "label": "Theme Mode", + "light": "Tryb Jasny", + "dark": "Tryb Ciemny", + "system": "Adapt to System" + } } }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/pt-BR.json b/frontend/app_flowy/assets/translations/pt-BR.json index 65e5879673..991e8126d2 100644 --- a/frontend/app_flowy/assets/translations/pt-BR.json +++ b/frontend/app_flowy/assets/translations/pt-BR.json @@ -152,8 +152,12 @@ "open": "Abrir as Configurações" }, "appearance": { - "lightLabel": "Modo Claro", - "darkLabel": "Modo Escuro" + "themeMode": { + "label": "Theme Mode", + "light": "Modo Claro", + "dark": "Modo Escuro", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/ru-RU.json b/frontend/app_flowy/assets/translations/ru-RU.json index 6f53886f84..6f9fff0853 100644 --- a/frontend/app_flowy/assets/translations/ru-RU.json +++ b/frontend/app_flowy/assets/translations/ru-RU.json @@ -151,8 +151,12 @@ "open": "Открыть настройки" }, "appearance": { - "lightLabel": "Светлая", - "darkLabel": "Тёмная" + "themeMode": { + "label": "Theme Mode", + "light": "Светлая", + "dark": "Тёмная", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/sv.json b/frontend/app_flowy/assets/translations/sv.json index e6cf4c6ff2..34cda86e86 100644 --- a/frontend/app_flowy/assets/translations/sv.json +++ b/frontend/app_flowy/assets/translations/sv.json @@ -152,8 +152,12 @@ "open": "Öppna inställningarna" }, "appearance": { - "lightLabel": "Ljust läge", - "darkLabel": "Mörkt läge" + "themeMode": { + "label": "Theme Mode", + "light": "Ljust läge", + "dark": "Mörkt läge", + "system": "Adapt to System" + } } }, "grid": { @@ -232,4 +236,4 @@ "create_new_card": "Nytt" } } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/tr-TR.json b/frontend/app_flowy/assets/translations/tr-TR.json index aa2b1a3a39..5495c32102 100644 --- a/frontend/app_flowy/assets/translations/tr-TR.json +++ b/frontend/app_flowy/assets/translations/tr-TR.json @@ -138,12 +138,16 @@ "open": "Ayarları Aç" }, "appearance": { - "lightLabel": "Aydınlık Mod", - "darkLabel": "Karanlık Mod" + "themeMode": { + "label": "Theme Mode", + "light": "Aydınlık Mod", + "dark": "Karanlık Mod", + "system": "Adapt to System" + } } }, "sideBar": { "openSidebar": "Open sidebar", "closeSidebar": "Close sidebar" } -} +} \ No newline at end of file diff --git a/frontend/app_flowy/assets/translations/zh-CN.json b/frontend/app_flowy/assets/translations/zh-CN.json index 6271d138cd..8f8f2f7400 100644 --- a/frontend/app_flowy/assets/translations/zh-CN.json +++ b/frontend/app_flowy/assets/translations/zh-CN.json @@ -152,8 +152,12 @@ "open": "打开设置" }, "appearance": { - "lightLabel": "日间模式", - "darkLabel": "夜间模式" + "themeMode": { + "label": "Theme Mode", + "light": "日间模式", + "dark": "夜间模式", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/assets/translations/zh-TW.json b/frontend/app_flowy/assets/translations/zh-TW.json index faa2dea03e..101e93452a 100644 --- a/frontend/app_flowy/assets/translations/zh-TW.json +++ b/frontend/app_flowy/assets/translations/zh-TW.json @@ -145,8 +145,12 @@ "open": "開啟設定" }, "appearance": { - "lightLabel": "亮色模式", - "darkLabel": "暗色模式" + "themeMode": { + "label": "Theme Mode", + "light": "亮色模式", + "dark": "暗色模式", + "system": "Adapt to System" + } } }, "grid": { diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart index bacb38f7aa..4454cbd276 100644 --- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart @@ -83,6 +83,8 @@ class ApplicationWidget extends StatelessWidget { builder: overlayManagerBuilder(), debugShowCheckedModeBanner: false, theme: state.theme.getThemeData(state.locale), + darkTheme: state.darkTheme.getThemeData(state.locale), + themeMode: state.themeMode, localizationsDelegates: context.localizationDelegates + [AppFlowyEditorLocalizations.delegate], supportedLocales: context.supportedLocales, diff --git a/frontend/app_flowy/lib/workspace/application/appearance.dart b/frontend/app_flowy/lib/workspace/application/appearance.dart index 016559b1bc..335b609d9c 100644 --- a/frontend/app_flowy/lib/workspace/application/appearance.dart +++ b/frontend/app_flowy/lib/workspace/application/appearance.dart @@ -19,6 +19,7 @@ class AppearanceSettingsCubit extends Cubit { : _setting = setting, super(AppearanceSettingsState.initial( setting.theme, + setting.themeMode, setting.font, setting.monospaceFont, setting.locale, @@ -26,21 +27,34 @@ class AppearanceSettingsCubit extends Cubit { /// 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) { + // void setTheme(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; } - _setting.theme = themeTypeToString(brightness); + _setting.themeMode = _themeModeToPB(themeMode); _saveAppearanceSettings(); - emit(state.copyWith( - theme: AppTheme.fromName( - themeName: _setting.theme, - font: state.theme.font, - monospaceFont: state.theme.monospaceFont, - ), - )); + emit(state.copyWith(themeMode: themeMode)); } /// Updates the current locale and notify the listeners the locale was changed @@ -115,25 +129,58 @@ class AppearanceSettingsCubit extends Cubit { } } +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 class AppearanceSettingsState with _$AppearanceSettingsState { const factory AppearanceSettingsState({ required AppTheme theme, + required AppTheme darkTheme, + required ThemeMode themeMode, required Locale locale, }) = _AppearanceSettingsState; factory AppearanceSettingsState.initial( String themeName, + ThemeModePB themeMode, String font, String monospaceFont, LocaleSettingsPB locale, ) => AppearanceSettingsState( - theme: AppTheme.fromName( - themeName: themeName, + 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), ); } 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 2e7ddaa51c..bd3d3c0726 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 @@ -1,43 +1,99 @@ import 'package:app_flowy/generated/locale_keys.g.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: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_bloc/flutter_bloc.dart'; -import '../../widgets/toggle/toggle.dart'; - class SettingsAppearanceView extends StatelessWidget { const SettingsAppearanceView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( + child: BlocBuilder( + builder: (context, state) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - FlowyText.medium(LocaleKeys.settings_appearance_lightLabel.tr()), - Toggle( - value: Theme.of(context).brightness == Brightness.dark, - onChanged: (_) => setTheme(context), - style: ToggleStyle.big, - ), - FlowyText.medium(LocaleKeys.settings_appearance_darkLabel.tr()) + ThemeModeSetting(currentThemeMode: state.themeMode), ], + ); + }, + ), + ); + } +} + +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().setThemeMode(themeMode); + } + }, ), ); } - void setTheme(BuildContext context) { - if (Theme.of(context).brightness == Brightness.dark) { - context.read().setTheme(Brightness.light); - } else { - context.read().setTheme(Brightness.dark); + String _themeModeLabelText(ThemeMode themeMode) { + switch (themeMode) { + case (ThemeMode.light): + return LocaleKeys.settings_appearance_themeMode_light.tr(); + case (ThemeMode.dark): + return LocaleKeys.settings_appearance_themeMode_dark.tr(); + case (ThemeMode.system): + return LocaleKeys.settings_appearance_themeMode_system.tr(); + default: + return ""; } } } diff --git a/frontend/app_flowy/packages/flowy_infra/lib/theme.dart b/frontend/app_flowy/packages/flowy_infra/lib/theme.dart index 1e80c072bb..504ea8348e 100644 --- a/frontend/app_flowy/packages/flowy_infra/lib/theme.dart +++ b/frontend/app_flowy/packages/flowy_infra/lib/theme.dart @@ -73,12 +73,12 @@ class AppTheme { /// Default constructor AppTheme({this.brightness = Brightness.light}); - factory AppTheme.fromName({ - required String themeName, + factory AppTheme.fromBrightness({ + required Brightness brightness, required String font, required String monospaceFont, }) { - switch (themeTypeFromString(themeName)) { + switch (brightness) { case Brightness.light: return AppTheme(brightness: Brightness.light) ..surface = Colors.white diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 5c6e1e4474..02b39760ee 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -63,7 +63,9 @@ class FlowyButton extends StatelessWidget { children.add(Expanded(child: text)); 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( diff --git a/frontend/rust-lib/flowy-user/src/entities/user_setting.rs b/frontend/rust-lib/flowy-user/src/entities/user_setting.rs index d9364ddad8..535dc56f1e 100644 --- a/frontend/rust-lib/flowy-user/src/entities/user_setting.rs +++ b/frontend/rust-lib/flowy-user/src/entities/user_setting.rs @@ -1,4 +1,4 @@ -use flowy_derive::ProtoBuf; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -17,26 +17,43 @@ pub struct AppearanceSettingsPB { pub theme: String, #[pb(index = 2)] - pub font: String, + #[serde(default)] + pub theme_mode: ThemeModePB, #[pb(index = 3)] - pub monospace_font: String, + pub font: String, #[pb(index = 4)] + pub monospace_font: String, + + #[pb(index = 5)] #[serde(default)] pub locale: LocaleSettingsPB, - #[pb(index = 5)] + #[pb(index = 6)] #[serde(default = "DEFAULT_RESET_VALUE")] pub reset_to_default: bool, - #[pb(index = 6)] + #[pb(index = 7)] #[serde(default)] pub setting_key_value: HashMap, } 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)] pub struct LocaleSettingsPB { #[pb(index = 1)] @@ -64,6 +81,7 @@ impl std::default::Default for AppearanceSettingsPB { fn default() -> Self { AppearanceSettingsPB { theme: APPEARANCE_DEFAULT_THEME.to_owned(), + theme_mode: ThemeModePB::default(), font: APPEARANCE_DEFAULT_FONT.to_owned(), monospace_font: APPEARANCE_DEFAULT_MONOSPACE_FONT.to_owned(), locale: LocaleSettingsPB::default(),