Browse Source

feat: save menu appearance (#1707)

* feat: save menu offset and menu visibility

* refactor: remove collapsedNotifier
abichinger 2 years ago
parent
commit
d36aea648c

+ 23 - 3
frontend/app_flowy/lib/workspace/application/appearance.dart

@@ -1,13 +1,13 @@
 import 'dart:async';
 
 import 'package:app_flowy/user/application/user_settings_service.dart';
+import 'package:appflowy_backend/log.dart';
+import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
+import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/size.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme_extension.dart';
-import 'package:appflowy_backend/log.dart';
-import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
 import 'package:flutter/material.dart';
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 
@@ -28,6 +28,8 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
           setting.font,
           setting.monospaceFont,
           setting.locale,
+          setting.isMenuCollapsed,
+          setting.menuOffset,
         ));
 
   /// Update selected theme in the user's settings and emit an updated state
@@ -64,6 +66,18 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
     }
   }
 
+  // Saves the menus current visibility
+  void saveIsMenuCollapsed(bool collapsed) {
+    _setting.isMenuCollapsed = collapsed;
+    _saveAppearanceSettings();
+  }
+
+  // Saves the current resize offset of the menu
+  void saveMenuOffset(double offset) {
+    _setting.menuOffset = offset;
+    _saveAppearanceSettings();
+  }
+
   /// Saves key/value setting to disk.
   /// Removes the key if the passed in value is null
   void setKeyValue(String key, String? value) {
@@ -151,6 +165,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
     required String font,
     required String monospaceFont,
     required Locale locale,
+    required bool isMenuCollapsed,
+    required double menuOffset,
   }) = _AppearanceSettingsState;
 
   factory AppearanceSettingsState.initial(
@@ -159,6 +175,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
     String font,
     String monospaceFont,
     LocaleSettingsPB localePB,
+    bool isMenuCollapsed,
+    double menuOffset,
   ) {
     return AppearanceSettingsState(
       appTheme: AppTheme.fromName(themeName),
@@ -166,6 +184,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
       monospaceFont: monospaceFont,
       themeMode: _themeModeFromPB(themeModePB),
       locale: Locale(localePB.languageCode, localePB.countryCode),
+      isMenuCollapsed: isMenuCollapsed,
+      menuOffset: menuOffset,
     );
   }
 

+ 21 - 14
frontend/app_flowy/lib/workspace/application/home/home_setting_bloc.dart

@@ -1,22 +1,30 @@
 import 'package:app_flowy/user/application/user_listener.dart';
+import 'package:app_flowy/workspace/application/appearance.dart';
 import 'package:app_flowy/workspace/application/edit_panel/edit_context.dart';
-import 'package:flowy_infra/time/duration.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'
     show WorkspaceSettingPB;
 import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_infra/time/duration.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:dartz/dartz.dart';
+
 part 'home_setting_bloc.freezed.dart';
 
 class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
   final UserWorkspaceListener _listener;
+  final AppearanceSettingsCubit _appearanceSettingsCubit;
 
   HomeSettingBloc(
     UserProfilePB user,
     WorkspaceSettingPB workspaceSetting,
+    AppearanceSettingsCubit appearanceSettingsCubit,
   )   : _listener = UserWorkspaceListener(userProfile: user),
-        super(HomeSettingState.initial(workspaceSetting)) {
+        _appearanceSettingsCubit = appearanceSettingsCubit,
+        super(HomeSettingState.initial(
+          workspaceSetting,
+          appearanceSettingsCubit.state,
+        )) {
     on<HomeSettingEvent>(
       (event, emit) async {
         await event.map(
@@ -27,14 +35,13 @@ class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
           dismissEditPanel: (value) async {
             emit(state.copyWith(panelContext: none()));
           },
-          forceCollapse: (e) async {
-            emit(state.copyWith(forceCollapse: e.forceCollapse));
-          },
           didReceiveWorkspaceSetting: (_DidReceiveWorkspaceSetting value) {
             emit(state.copyWith(workspaceSetting: value.setting));
           },
           collapseMenu: (_CollapseMenu e) {
-            emit(state.copyWith(isMenuCollapsed: !state.isMenuCollapsed));
+            var isMenuCollapsed = !state.isMenuCollapsed;
+            _appearanceSettingsCubit.saveIsMenuCollapsed(isMenuCollapsed);
+            emit(state.copyWith(isMenuCollapsed: isMenuCollapsed));
           },
           editPanelResizeStart: (_EditPanelResizeStart e) {
             emit(state.copyWith(
@@ -50,6 +57,7 @@ class HomeSettingBloc extends Bloc<HomeSettingEvent, HomeSettingState> {
             }
           },
           editPanelResizeEnd: (_EditPanelResizeEnd e) {
+            _appearanceSettingsCubit.saveMenuOffset(state.resizeOffset);
             emit(state.copyWith(resizeType: MenuResizeType.slide));
           },
         );
@@ -83,8 +91,6 @@ extension MenuResizeTypeExtension on MenuResizeType {
 @freezed
 class HomeSettingEvent with _$HomeSettingEvent {
   const factory HomeSettingEvent.initial() = _Initial;
-  const factory HomeSettingEvent.forceCollapse(bool forceCollapse) =
-      _ForceCollapse;
   const factory HomeSettingEvent.setEditPanel(EditPanelContext editContext) =
       _ShowEditPanel;
   const factory HomeSettingEvent.dismissEditPanel() = _DismissEditPanel;
@@ -100,7 +106,6 @@ class HomeSettingEvent with _$HomeSettingEvent {
 @freezed
 class HomeSettingState with _$HomeSettingState {
   const factory HomeSettingState({
-    required bool forceCollapse,
     required Option<EditPanelContext> panelContext,
     required WorkspaceSettingPB workspaceSetting,
     required bool unauthorized,
@@ -110,14 +115,16 @@ class HomeSettingState with _$HomeSettingState {
     required MenuResizeType resizeType,
   }) = _HomeSettingState;
 
-  factory HomeSettingState.initial(WorkspaceSettingPB workspaceSetting) =>
+  factory HomeSettingState.initial(
+    WorkspaceSettingPB workspaceSetting,
+    AppearanceSettingsState appearanceSettingsState,
+  ) =>
       HomeSettingState(
-        forceCollapse: false,
         panelContext: none(),
         workspaceSetting: workspaceSetting,
         unauthorized: false,
-        isMenuCollapsed: false,
-        resizeOffset: 0,
+        isMenuCollapsed: appearanceSettingsState.isMenuCollapsed,
+        resizeOffset: appearanceSettingsState.menuOffset,
         resizeStart: 0,
         resizeType: MenuResizeType.slide,
       );

+ 2 - 2
frontend/app_flowy/lib/workspace/presentation/home/home_layout.dart

@@ -3,9 +3,9 @@ import 'dart:io' show Platform;
 import 'package:app_flowy/workspace/application/home/home_setting_bloc.dart';
 import 'package:flowy_infra/size.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 // ignore: import_of_legacy_library_into_null_safe
 import 'package:sized_context/sized_context.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'home_sizes.dart';
 
@@ -32,7 +32,7 @@ class HomeLayout {
 
     menuWidth += homeSetting.resizeOffset;
 
-    if (homeSetting.forceCollapse) {
+    if (homeSetting.isMenuCollapsed) {
       showMenu = false;
     } else {
       showMenu = true;

+ 10 - 17
frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart

@@ -1,26 +1,25 @@
 import 'package:app_flowy/plugins/blank/blank.dart';
 import 'package:app_flowy/startup/plugin/plugin.dart';
+import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/workspace/application/appearance.dart';
 import 'package:app_flowy/workspace/application/home/home_bloc.dart';
 import 'package:app_flowy/workspace/application/home/home_service.dart';
 import 'package:app_flowy/workspace/application/home/home_setting_bloc.dart';
-
-import 'package:app_flowy/workspace/presentation/home/hotkeys.dart';
 import 'package:app_flowy/workspace/application/view/view_ext.dart';
+import 'package:app_flowy/workspace/presentation/home/hotkeys.dart';
 import 'package:app_flowy/workspace/presentation/widgets/edit_panel/panel_animation.dart';
 import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
-import 'package:app_flowy/startup/startup.dart';
 import 'package:appflowy_backend/log.dart';
-import 'package:flowy_infra_ui/style_widget/container.dart';
+import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
 import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
     show UserProfilePB;
-import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
+import 'package:flowy_infra_ui/style_widget/container.dart';
 import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';
 
 import '../widgets/edit_panel/edit_panel.dart';
-
 import 'home_layout.dart';
 import 'home_stack.dart';
 import 'menu/menu.dart';
@@ -48,8 +47,11 @@ class _HomeScreenState extends State<HomeScreen> {
         ),
         BlocProvider<HomeSettingBloc>(
           create: (context) {
-            return HomeSettingBloc(widget.user, widget.workspaceSetting)
-              ..add(const HomeSettingEvent.initial());
+            return HomeSettingBloc(
+              widget.user,
+              widget.workspaceSetting,
+              context.read<AppearanceSettingsCubit>(),
+            )..add(const HomeSettingEvent.initial());
           },
         ),
       ],
@@ -87,16 +89,8 @@ class _HomeScreenState extends State<HomeScreen> {
           child: BlocBuilder<HomeSettingBloc, HomeSettingState>(
             buildWhen: (previous, current) => previous != current,
             builder: (context, state) {
-              final collapsedNotifier =
-                  getIt<HomeStackManager>().collapsedNotifier;
-              collapsedNotifier.addPublishListener((isCollapsed) {
-                context
-                    .read<HomeSettingBloc>()
-                    .add(HomeSettingEvent.forceCollapse(isCollapsed));
-              });
               return FlowyContainer(
                 Theme.of(context).colorScheme.surface,
-                // Colors.white,
                 child: _buildBody(context),
               );
             },
@@ -146,7 +140,6 @@ class _HomeScreenState extends State<HomeScreen> {
     final homeMenu = HomeMenu(
       user: widget.user,
       workspaceSetting: workspaceSetting,
-      collapsedNotifier: getIt<HomeStackManager>().collapsedNotifier,
     );
 
     return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));

+ 8 - 10
frontend/app_flowy/lib/workspace/presentation/home/home_stack.dart

@@ -1,17 +1,17 @@
-import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/core/frameless_window.dart';
 import 'package:app_flowy/plugins/blank/blank.dart';
+import 'package:app_flowy/startup/plugin/plugin.dart';
+import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
+import 'package:app_flowy/workspace/presentation/home/navigation.dart';
 import 'package:app_flowy/workspace/presentation/home/toast.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
+import 'package:flowy_infra_ui/style_widget/extension.dart';
+import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:time/time.dart';
-import 'package:app_flowy/startup/plugin/plugin.dart';
-import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
-import 'package:app_flowy/workspace/presentation/home/navigation.dart';
-import 'package:app_flowy/core/frameless_window.dart';
-import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_infra_ui/style_widget/extension.dart';
-import 'package:flowy_infra/notifier.dart';
+
 import 'home_layout.dart';
 
 typedef NavigationCallback = void Function(String id);
@@ -111,7 +111,6 @@ abstract class NavigationItem {
 
 class HomeStackNotifier extends ChangeNotifier {
   Plugin _plugin;
-  PublishNotifier<bool> collapsedNotifier = PublishNotifier();
 
   Widget get titleWidget => _plugin.display.leftBarItem;
 
@@ -143,7 +142,6 @@ class HomeStackManager {
     return _notifier.plugin.display.leftBarItem;
   }
 
-  PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
   Plugin get plugin => _notifier.plugin;
 
   void setPlugin(Plugin newPlugin) {

+ 0 - 4
frontend/app_flowy/lib/workspace/presentation/home/hotkeys.dart

@@ -1,8 +1,6 @@
 import 'dart:io';
 
-import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/home/home_setting_bloc.dart';
-import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
 import 'package:flutter/material.dart';
 import 'package:hotkey_manager/hotkey_manager.dart';
 import 'package:provider/provider.dart';
@@ -25,8 +23,6 @@ class HomeHotKeys extends StatelessWidget {
         context
             .read<HomeSettingBloc>()
             .add(const HomeSettingEvent.collapseMenu());
-        getIt<HomeStackManager>().collapsedNotifier.value =
-            !getIt<HomeStackManager>().collapsedNotifier.currentValue!;
       },
     );
     return child;

+ 18 - 27
frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart

@@ -1,40 +1,39 @@
-export './app/header/header.dart';
-export './app/menu_app.dart';
-
 import 'dart:io' show Platform;
+
+import 'package:app_flowy/core/frameless_window.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/plugins/trash/menu.dart';
+import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/home/home_setting_bloc.dart';
+import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
 import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
 import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
+import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
+import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
+import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
+    show UserProfilePB;
 import 'package:easy_localization/easy_localization.dart';
-import 'package:flowy_infra/notifier.dart';
+import 'package:expandable/expandable.dart';
+// import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
+import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/size.dart';
+import 'package:flowy_infra/time/duration.dart';
+import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
-    show UserProfilePB;
-import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
-import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';
-import 'package:expandable/expandable.dart';
-import 'package:flowy_infra/time/duration.dart';
-import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
-import 'package:app_flowy/core/frameless_window.dart';
-// import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
-import 'package:flowy_infra/image.dart';
-import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 
 import '../navigation.dart';
-import 'app/menu_app.dart';
 import 'app/create_button.dart';
+import 'app/menu_app.dart';
 import 'menu_user.dart';
 
+export './app/header/header.dart';
+export './app/menu_app.dart';
+
 class HomeMenu extends StatelessWidget {
-  final PublishNotifier<bool> _collapsedNotifier;
   final UserProfilePB user;
   final WorkspaceSettingPB workspaceSetting;
 
@@ -42,9 +41,7 @@ class HomeMenu extends StatelessWidget {
     Key? key,
     required this.user,
     required this.workspaceSetting,
-    required PublishNotifier<bool> collapsedNotifier,
-  })  : _collapsedNotifier = collapsedNotifier,
-        super(key: key);
+  }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -69,12 +66,6 @@ class HomeMenu extends StatelessWidget {
               getIt<HomeStackManager>().setPlugin(state.plugin);
             },
           ),
-          BlocListener<HomeSettingBloc, HomeSettingState>(
-            listenWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
-            listener: (context, state) {
-              _collapsedNotifier.value = state.isMenuCollapsed;
-            },
-          )
         ],
         child: BlocBuilder<MenuBloc, MenuState>(
           builder: (context, state) => _renderBody(context),

+ 35 - 45
frontend/app_flowy/lib/workspace/presentation/home/navigation.dart

@@ -3,25 +3,23 @@ import 'dart:io';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/workspace/application/home/home_setting_bloc.dart';
 import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
-import 'package:flowy_infra/theme_extension.dart';
+import 'package:easy_localization/easy_localization.dart';
 import 'package:flowy_infra/image.dart';
-import 'package:flowy_infra/notifier.dart';
 import 'package:flowy_infra/size.dart';
+import 'package:flowy_infra/theme_extension.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
-import 'package:easy_localization/easy_localization.dart';
 import 'package:textstyle_extensions/textstyle_extensions.dart';
 
 typedef NaviAction = void Function();
 
 class NavigationNotifier with ChangeNotifier {
   List<NavigationItem> navigationItems;
-  PublishNotifier<bool> collapasedNotifier;
-  NavigationNotifier(
-      {required this.navigationItems, required this.collapasedNotifier});
+  NavigationNotifier({required this.navigationItems});
 
   void update(HomeStackNotifier notifier) {
     bool shouldNotify = false;
@@ -46,16 +44,12 @@ class FlowyNavigation extends StatelessWidget {
         final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
         return NavigationNotifier(
           navigationItems: notifier.plugin.display.navigationItems,
-          collapasedNotifier: notifier.collapsedNotifier,
         );
       },
       update: (_, notifier, controller) => controller!..update(notifier),
       child: Expanded(
         child: Row(children: [
-          Selector<NavigationNotifier, PublishNotifier<bool>>(
-              selector: (context, notifier) => notifier.collapasedNotifier,
-              builder: (ctx, collapsedNotifier, child) =>
-                  _renderCollapse(ctx, collapsedNotifier)),
+          _renderCollapse(context),
           Selector<NavigationNotifier, List<NavigationItem>>(
             selector: (context, notifier) => notifier.navigationItems,
             builder: (ctx, items, child) => Expanded(
@@ -70,41 +64,37 @@ class FlowyNavigation extends StatelessWidget {
     );
   }
 
-  Widget _renderCollapse(
-      BuildContext context, PublishNotifier<bool> collapsedNotifier) {
-    return ChangeNotifierProvider.value(
-      value: collapsedNotifier,
-      child: Consumer(
-        builder: (ctx, PublishNotifier<bool> notifier, child) {
-          if (notifier.currentValue ?? false) {
-            return RotationTransition(
-              turns: const AlwaysStoppedAnimation(180 / 360),
-              child: Tooltip(
-                  richMessage: sidebarTooltipTextSpan(
-                    context,
-                    LocaleKeys.sideBar_openSidebar.tr(),
+  Widget _renderCollapse(BuildContext context) {
+    return BlocBuilder<HomeSettingBloc, HomeSettingState>(
+      buildWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
+      builder: (context, state) {
+        if (state.isMenuCollapsed) {
+          return RotationTransition(
+            turns: const AlwaysStoppedAnimation(180 / 360),
+            child: Tooltip(
+                richMessage: sidebarTooltipTextSpan(
+                  context,
+                  LocaleKeys.sideBar_openSidebar.tr(),
+                ),
+                child: FlowyIconButton(
+                  width: 24,
+                  hoverColor: Colors.transparent,
+                  onPressed: () {
+                    context
+                        .read<HomeSettingBloc>()
+                        .add(const HomeSettingEvent.collapseMenu());
+                  },
+                  iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
+                  icon: svgWidget(
+                    "home/hide_menu",
+                    color: Theme.of(context).colorScheme.onSurface,
                   ),
-                  child: FlowyIconButton(
-                    width: 24,
-                    hoverColor: Colors.transparent,
-                    onPressed: () {
-                      notifier.value = false;
-                      ctx
-                          .read<HomeSettingBloc>()
-                          .add(const HomeSettingEvent.collapseMenu());
-                    },
-                    iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
-                    icon: svgWidget(
-                      "home/hide_menu",
-                      color: Theme.of(context).colorScheme.onSurface,
-                    ),
-                  )),
-            );
-          } else {
-            return Container();
-          }
-        },
-      ),
+                )),
+          );
+        } else {
+          return Container();
+        }
+      },
     );
   }
 

+ 12 - 0
frontend/rust-lib/flowy-user/src/entities/user_setting.rs

@@ -37,6 +37,14 @@ pub struct AppearanceSettingsPB {
     #[pb(index = 7)]
     #[serde(default)]
     pub setting_key_value: HashMap<String, String>,
+
+    #[pb(index = 8)]
+    #[serde(default)]
+    pub is_menu_collapsed: bool,
+
+    #[pb(index = 9)]
+    #[serde(default)]
+    pub menu_offset: f64,
 }
 
 const DEFAULT_RESET_VALUE: fn() -> bool = || APPEARANCE_RESET_AS_DEFAULT;
@@ -76,6 +84,8 @@ pub const APPEARANCE_DEFAULT_THEME: &str = "light";
 pub const APPEARANCE_DEFAULT_FONT: &str = "Poppins";
 pub const APPEARANCE_DEFAULT_MONOSPACE_FONT: &str = "SF Mono";
 const APPEARANCE_RESET_AS_DEFAULT: bool = true;
+const APPEARANCE_DEFAULT_IS_MENU_COLLAPSED: bool = false;
+const APPEARANCE_DEFAULT_MENU_OFFSET: f64 = 0.0;
 
 impl std::default::Default for AppearanceSettingsPB {
     fn default() -> Self {
@@ -87,6 +97,8 @@ impl std::default::Default for AppearanceSettingsPB {
             locale: LocaleSettingsPB::default(),
             reset_to_default: APPEARANCE_RESET_AS_DEFAULT,
             setting_key_value: HashMap::default(),
+            is_menu_collapsed: APPEARANCE_DEFAULT_IS_MENU_COLLAPSED,
+            menu_offset: APPEARANCE_DEFAULT_MENU_OFFSET,
         }
     }
 }