feat: save menu appearance (#1707)

* feat: save menu offset and menu visibility

* refactor: remove collapsedNotifier
This commit is contained in:
abichinger 2023-01-18 07:30:39 +01:00 committed by GitHub
parent 3d56a0a843
commit d36aea648c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 131 additions and 124 deletions

View File

@ -1,13 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'package:app_flowy/user/application/user_settings_service.dart'; 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/size.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra/theme_extension.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:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
@ -28,6 +28,8 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
setting.font, setting.font,
setting.monospaceFont, setting.monospaceFont,
setting.locale, setting.locale,
setting.isMenuCollapsed,
setting.menuOffset,
)); ));
/// Update selected theme in the user's settings and emit an updated state /// 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. /// Saves key/value setting to disk.
/// Removes the key if the passed in value is null /// Removes the key if the passed in value is null
void setKeyValue(String key, String? value) { void setKeyValue(String key, String? value) {
@ -151,6 +165,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
required String font, required String font,
required String monospaceFont, required String monospaceFont,
required Locale locale, required Locale locale,
required bool isMenuCollapsed,
required double menuOffset,
}) = _AppearanceSettingsState; }) = _AppearanceSettingsState;
factory AppearanceSettingsState.initial( factory AppearanceSettingsState.initial(
@ -159,6 +175,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
String font, String font,
String monospaceFont, String monospaceFont,
LocaleSettingsPB localePB, LocaleSettingsPB localePB,
bool isMenuCollapsed,
double menuOffset,
) { ) {
return AppearanceSettingsState( return AppearanceSettingsState(
appTheme: AppTheme.fromName(themeName), appTheme: AppTheme.fromName(themeName),
@ -166,6 +184,8 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
monospaceFont: monospaceFont, monospaceFont: monospaceFont,
themeMode: _themeModeFromPB(themeModePB), themeMode: _themeModeFromPB(themeModePB),
locale: Locale(localePB.languageCode, localePB.countryCode), locale: Locale(localePB.languageCode, localePB.countryCode),
isMenuCollapsed: isMenuCollapsed,
menuOffset: menuOffset,
); );
} }

View File

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

View File

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

View File

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

View File

@ -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/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:app_flowy/workspace/presentation/home/toast.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.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:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:time/time.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'; import 'home_layout.dart';
typedef NavigationCallback = void Function(String id); typedef NavigationCallback = void Function(String id);
@ -111,7 +111,6 @@ abstract class NavigationItem {
class HomeStackNotifier extends ChangeNotifier { class HomeStackNotifier extends ChangeNotifier {
Plugin _plugin; Plugin _plugin;
PublishNotifier<bool> collapsedNotifier = PublishNotifier();
Widget get titleWidget => _plugin.display.leftBarItem; Widget get titleWidget => _plugin.display.leftBarItem;
@ -143,7 +142,6 @@ class HomeStackManager {
return _notifier.plugin.display.leftBarItem; return _notifier.plugin.display.leftBarItem;
} }
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
Plugin get plugin => _notifier.plugin; Plugin get plugin => _notifier.plugin;
void setPlugin(Plugin newPlugin) { void setPlugin(Plugin newPlugin) {

View File

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

View File

@ -1,40 +1,39 @@
export './app/header/header.dart';
export './app/menu_app.dart';
import 'dart:io' show Platform; 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/generated/locale_keys.g.dart';
import 'package:app_flowy/plugins/trash/menu.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/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_sizes.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/notifier.dart';
import 'package:flowy_infra/size.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/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.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: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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.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 '../navigation.dart';
import 'app/menu_app.dart';
import 'app/create_button.dart'; import 'app/create_button.dart';
import 'app/menu_app.dart';
import 'menu_user.dart'; import 'menu_user.dart';
export './app/header/header.dart';
export './app/menu_app.dart';
class HomeMenu extends StatelessWidget { class HomeMenu extends StatelessWidget {
final PublishNotifier<bool> _collapsedNotifier;
final UserProfilePB user; final UserProfilePB user;
final WorkspaceSettingPB workspaceSetting; final WorkspaceSettingPB workspaceSetting;
@ -42,9 +41,7 @@ class HomeMenu extends StatelessWidget {
Key? key, Key? key,
required this.user, required this.user,
required this.workspaceSetting, required this.workspaceSetting,
required PublishNotifier<bool> collapsedNotifier, }) : super(key: key);
}) : _collapsedNotifier = collapsedNotifier,
super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -69,12 +66,6 @@ class HomeMenu extends StatelessWidget {
getIt<HomeStackManager>().setPlugin(state.plugin); 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>( child: BlocBuilder<MenuBloc, MenuState>(
builder: (context, state) => _renderBody(context), builder: (context, state) => _renderBody(context),

View File

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

View File

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