From c4f6703b761d9ae4248066c28d484c1bc10497f0 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Mon, 6 May 2024 12:13:17 +0200 Subject: [PATCH] fix: launch review improvements (#5263) * fix: recent views fix * fix: text button font color * fix: sidebar scrollbar inset * fix: account settings launch review * fix: open + menu on mobile provider issue * fix: code review * fix: push view improvement --- .../lib/mobile/application/mobile_router.dart | 2 + .../favorite/mobile_favorite_folder.dart | 17 +- .../mobile_home_favorite_folder.dart | 7 +- .../mobile_home_recent_views.dart | 18 +- .../mobile_home_section_folder.dart | 7 +- .../page_item/mobile_view_item.dart | 3 +- .../widgets/setting/setting_button.dart | 10 +- .../document/presentation/editor_page.dart | 26 +-- .../base/emoji_picker_button.dart | 57 ++--- .../code_block/code_language_screen.dart | 8 +- .../font/customize_font_toolbar_item.dart | 8 +- .../add_block_toolbar_item.dart | 56 ++--- .../recent/cached_recent_service.dart | 7 +- .../application/recent/recent_views_bloc.dart | 10 +- .../presentation/home/home_stack.dart | 11 +- .../menu/sidebar/folder/_favorite_folder.dart | 8 +- .../menu/sidebar/folder/_folder_header.dart | 1 + .../home/menu/sidebar/sidebar.dart | 12 +- .../home/menu/sidebar/sidebar_folder.dart | 67 +++--- .../home/menu/view/view_item.dart | 3 +- .../settings/pages/settings_account_view.dart | 213 +++++++----------- .../files/settings_file_exporter_widget.dart | 11 +- .../font_family_setting.dart | 11 +- .../settings_customize_shortcuts_view.dart | 7 +- .../settings/widgets/settings_menu.dart | 41 +--- .../widgets/settings_menu_element.dart | 13 +- frontend/resources/translations/en.json | 2 +- 27 files changed, 271 insertions(+), 365 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart index 2c3b8f9d9b..600dace29f 100644 --- a/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart +++ b/frontend/appflowy_flutter/lib/mobile/application/mobile_router.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:flutter/material.dart'; import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart'; @@ -19,6 +20,7 @@ extension MobileRouter on BuildContext { queryParameters: view.queryParameters(arguments), ).toString(), ).then((value) { + getIt().latestOpenView = view; getIt().updateRecentViews([view.id], true); }); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart index 9d8cbf608e..f9fcba5754 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/favorite/mobile_favorite_folder.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart'; @@ -8,7 +10,6 @@ import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; @@ -28,23 +29,15 @@ class MobileFavoritePageFolder extends StatelessWidget { providers: [ BlocProvider( create: (_) => SidebarSectionsBloc() - ..add( - SidebarSectionsEvent.initial( - userProfile, - workspaceId, - ), - ), + ..add(SidebarSectionsEvent.initial(userProfile, workspaceId)), ), BlocProvider( create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()), ), ], child: BlocListener( - listener: (context, state) { - context.read().add( - const FavoriteEvent.initial(), - ); - }, + listener: (context, state) => + context.read().add(const FavoriteEvent.initial()), child: MultiBlocListener( listeners: [ BlocListener( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart index b91c172910..c56d369676 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder_header.dart'; @@ -5,7 +7,6 @@ import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class MobileFavoriteFolder extends StatelessWidget { @@ -62,9 +63,7 @@ class MobileFavoriteFolder extends StatelessWidget { isFeedback: false, view: view, level: 0, - onSelected: (view) async { - await context.pushView(view); - }, + onSelected: context.pushView, endActionPane: (context) => buildEndActionPane(context, [ view.isFavorite ? MobilePaneActionType.removeFromFavorites diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart index 2d6f4f6e32..4dc9f28155 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/mobile_home_recent_views.dart @@ -24,16 +24,16 @@ class _MobileRecentFolderState extends State { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => RecentViewsBloc() - ..add( - const RecentViewsEvent.initial(), - ), + create: (context) => + RecentViewsBloc()..add(const RecentViewsEvent.initial()), child: BlocListener( - listener: (context, state) { - context.read().add( - const RecentViewsEvent.fetchRecentViews(), - ); - }, + listenWhen: (previous, current) => + current.currentWorkspace != null && + previous.currentWorkspace?.workspaceId != + current.currentWorkspace!.workspaceId, + listener: (context, state) => context + .read() + .add(const RecentViewsEvent.resetRecentViews()), child: BlocBuilder( builder: (context, state) { final ids = {}; diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index 58e34c63d1..c9ea1453c9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; @@ -9,7 +11,6 @@ import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class MobileSectionFolder extends StatelessWidget { @@ -71,9 +72,7 @@ class MobileSectionFolder extends StatelessWidget { level: 0, leftPadding: 16, isFeedback: false, - onSelected: (view) async { - await context.pushView(view); - }, + onSelected: context.pushView, endActionPane: (context) { final view = context.read().state.view; return buildEndActionPane(context, [ diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index 44eba47bcb..34fd517613 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; @@ -10,7 +12,6 @@ import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_it import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_button.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_button.dart index 28dc6b0781..7e52303b33 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/setting/setting_button.dart @@ -11,10 +11,7 @@ import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; class SettingButton extends StatefulWidget { - const SettingButton({ - super.key, - required this.databaseController, - }); + const SettingButton({super.key, required this.databaseController}); final DatabaseController databaseController; @@ -44,9 +41,8 @@ class _SettingButtonState extends State { radius: Corners.s4Border, onPressed: _popoverController.show, ), - popupBuilder: (BuildContext context) => DatabaseSettingsList( - databaseController: widget.databaseController, - ), + popupBuilder: (_) => + DatabaseSettingsList(databaseController: widget.databaseController), ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 2a6e0ca917..0fe6347acc 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -325,24 +325,20 @@ class _AppFlowyEditorPageState extends State { final editorState = widget.editorState; if (PlatformExtension.isMobile) { - return BlocProvider.value( - value: documentBloc, - child: AppFlowyMobileToolbar( - toolbarHeight: 42.0, + return AppFlowyMobileToolbar( + toolbarHeight: 42.0, + editorState: editorState, + toolbarItemsBuilder: (sel) => buildMobileToolbarItems(editorState, sel), + child: MobileFloatingToolbar( editorState: editorState, - toolbarItemsBuilder: (selection) => - buildMobileToolbarItems(editorState, selection), - child: MobileFloatingToolbar( + editorScrollController: editorScrollController, + toolbarBuilder: (_, anchor, closeToolbar) => + CustomMobileFloatingToolbar( editorState: editorState, - editorScrollController: editorScrollController, - toolbarBuilder: (_, anchor, closeToolbar) => - CustomMobileFloatingToolbar( - editorState: editorState, - anchor: anchor, - closeToolbar: closeToolbar, - ), - child: editor, + anchor: anchor, + closeToolbar: closeToolbar, ), + child: editor, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart index 48eb53c32f..df78f6261e 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart @@ -1,10 +1,11 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class EmojiPickerButton extends StatelessWidget { @@ -41,7 +42,7 @@ class EmojiPickerButton extends StatelessWidget { ), offset: offset, direction: direction ?? PopoverDirection.rightWithTopAligned, - popupBuilder: (context) => Container( + popupBuilder: (_) => Container( width: emojiPickerSize.width, height: emojiPickerSize.height, padding: const EdgeInsets.all(4.0), @@ -54,7 +55,7 @@ class EmojiPickerButton extends StatelessWidget { ? FlowyButton( useIntrinsicWidth: true, text: defaultIcon!, - onTap: () => popoverController.show(), + onTap: popoverController.show, ) : FlowyTextButton( emoji, @@ -64,37 +65,29 @@ class EmojiPickerButton extends StatelessWidget { constraints: const BoxConstraints(minWidth: 35.0), fillColor: Colors.transparent, mainAxisAlignment: MainAxisAlignment.center, - onPressed: () { - popoverController.show(); - }, + onPressed: popoverController.show, ), ); - } else { - return FlowyTextButton( - emoji, - overflow: TextOverflow.visible, - fontSize: emojiSize, - padding: EdgeInsets.zero, - constraints: const BoxConstraints(minWidth: 35.0), - fillColor: Colors.transparent, - mainAxisAlignment: MainAxisAlignment.center, - onPressed: () async { - final result = await context.push( - Uri( - path: MobileEmojiPickerScreen.routeName, - queryParameters: { - MobileEmojiPickerScreen.pageTitle: title, - }, - ).toString(), - ); - if (result != null) { - onSubmitted( - result.emoji, - null, - ); - } - }, - ); } + return FlowyTextButton( + emoji, + overflow: TextOverflow.visible, + fontSize: emojiSize, + padding: EdgeInsets.zero, + constraints: const BoxConstraints(minWidth: 35.0), + fillColor: Colors.transparent, + mainAxisAlignment: MainAxisAlignment.center, + onPressed: () async { + final result = await context.push( + Uri( + path: MobileEmojiPickerScreen.routeName, + queryParameters: {MobileEmojiPickerScreen.pageTitle: title}, + ).toString(), + ); + if (result != null) { + onSubmitted(result.emoji, null); + } + }, + ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_language_screen.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_language_screen.dart index 79e6968171..8c4a239e20 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_language_screen.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_language_screen.dart @@ -16,11 +16,11 @@ class MobileCodeLanguagePickerScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: FlowyAppBar( - titleText: LocaleKeys.titleBar_language.tr(), - ), + appBar: FlowyAppBar(titleText: LocaleKeys.titleBar_language.tr()), body: SafeArea( child: ListView.separated( + separatorBuilder: (_, __) => const Divider(), + itemCount: defaultCodeBlockSupportedLanguages.length, itemBuilder: (context, index) { final language = defaultCodeBlockSupportedLanguages[index]; return SizedBox( @@ -35,8 +35,6 @@ class MobileCodeLanguagePickerScreen extends StatelessWidget { ), ); }, - separatorBuilder: (_, __) => const Divider(), - itemCount: defaultCodeBlockSupportedLanguages.length, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/font/customize_font_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/font/customize_font_toolbar_item.dart index c98f6ede38..ab64e4adeb 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/font/customize_font_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/font/customize_font_toolbar_item.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart'; @@ -6,7 +8,6 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; final customizeFontToolbarItem = ToolbarItem( id: 'editor.font', @@ -34,9 +35,8 @@ final customizeFontToolbarItem = ToolbarItem( Log.error('Failed to set font family: $e'); } }, - onResetFont: () async => editorState.formatDelta(selection, { - AppFlowyRichTextKeys.fontFamily: null, - }), + onResetFont: () async => editorState + .formatDelta(selection, {AppFlowyRichTextKeys.fontFamily: null}), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4.0), child: FlowyTooltip( diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart index 2a046165a2..d0be5af466 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/add_block_toolbar_item.dart @@ -6,7 +6,6 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/base/type_option_menu_item.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; -import 'package:appflowy/plugins/document/application/document_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_placeholder.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart'; @@ -14,11 +13,12 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mo import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_item/mobile_add_block_toolbar_item.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/tasks/app_widget.dart'; +import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; final addBlockToolbarItem = AppFlowyMobileToolbarItem( @@ -45,7 +45,6 @@ final addBlockToolbarItem = AppFlowyMobileToolbarItem( keepEditorFocusNotifier.increase(); final didAddBlock = await showAddBlockMenu( AppGlobals.rootNavKey.currentContext!, - documentBloc: context.read(), editorState: editorState, selection: selection!, ); @@ -60,33 +59,25 @@ final addBlockToolbarItem = AppFlowyMobileToolbarItem( Future showAddBlockMenu( BuildContext context, { - required DocumentBloc documentBloc, required EditorState editorState, required Selection selection, -}) async { - final theme = ToolbarColorExtension.of(context); - return showMobileBottomSheet( - context, - showHeader: true, - showDragHandle: true, - showCloseButton: true, - title: LocaleKeys.button_add.tr(), - barrierColor: Colors.transparent, - backgroundColor: theme.toolbarMenuBackgroundColor, - elevation: 20, - enableDraggableScrollable: true, - builder: (_) => Padding( - padding: EdgeInsets.all(16 * context.scale), - child: BlocProvider.value( - value: documentBloc, - child: _AddBlockMenu( - selection: selection, - editorState: editorState, - ), +}) async => + showMobileBottomSheet( + context, + showHeader: true, + showDragHandle: true, + showCloseButton: true, + title: LocaleKeys.button_add.tr(), + barrierColor: Colors.transparent, + backgroundColor: + ToolbarColorExtension.of(context).toolbarMenuBackgroundColor, + elevation: 20, + enableDraggableScrollable: true, + builder: (_) => Padding( + padding: EdgeInsets.all(16 * context.scale), + child: _AddBlockMenu(selection: selection, editorState: editorState), ), - ), - ); -} + ); class _AddBlockMenu extends StatelessWidget { const _AddBlockMenu({ @@ -99,12 +90,9 @@ class _AddBlockMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider.value( - value: context.read(), - child: TypeOptionMenu( - values: buildTypeOptionMenuItemValues(context), - scaleFactor: context.scale, - ), + return TypeOptionMenu( + values: buildTypeOptionMenuItemValues(context), + scaleFactor: context.scale, ); } @@ -226,7 +214,7 @@ class _AddBlockMenu extends StatelessWidget { onTap: (_, __) async { AppGlobals.rootNavKey.currentContext?.pop(true); - final currentViewId = context.read().documentId; + final currentViewId = getIt().latestOpenView?.id; final viewId = await showPageSelectorSheet( context, currentViewId: currentViewId, diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart index 1503383a89..8407ed841f 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/cached_recent_service.dart @@ -24,7 +24,10 @@ class CachedRecentService { Completer _completer = Completer(); ValueNotifier> notifier = ValueNotifier(const []); - List _recentViews = const []; + + List get _recentViews => notifier.value; + set _recentViews(List value) => notifier.value = value; + final _listener = RecentViewsListener(); Future> recentViews() async { @@ -35,7 +38,6 @@ class CachedRecentService { _listener.start(recentViewsUpdated: _recentViewsUpdated); final result = await _readRecentViews(); _recentViews = result.toNullable()?.items ?? const []; - notifier.value = _recentViews; _completer.complete(); return _recentViews; @@ -64,6 +66,7 @@ class CachedRecentService { } Future dispose() async { + notifier.dispose(); await _listener.stop(); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart index 4296b09f10..b43edfa2b1 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/recent/recent_views_bloc.dart @@ -37,6 +37,10 @@ class RecentViewsBloc extends Bloc { fetchRecentViews: (e) async { emit(state.copyWith(views: await _service.recentViews())); }, + resetRecentViews: (e) async { + await _service.reset(); + add(const RecentViewsEvent.fetchRecentViews()); + }, ); }, ); @@ -54,13 +58,13 @@ class RecentViewsEvent with _$RecentViewsEvent { const factory RecentViewsEvent.removeRecentViews(List viewIds) = RemoveRecentViews; const factory RecentViewsEvent.fetchRecentViews() = FetchRecentViews; + const factory RecentViewsEvent.resetRecentViews() = ResetRecentViews; } @freezed class RecentViewsState with _$RecentViewsState { - const factory RecentViewsState({ - required List views, - }) = _RecentViewsState; + const factory RecentViewsState({required List views}) = + _RecentViewsState; factory RecentViewsState.initial() => const RecentViewsState(views: []); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart index 535ff002de..517dede7c5 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:appflowy/core/frameless_window.dart'; import 'package:appflowy/plugins/blank/blank.dart'; @@ -110,9 +111,7 @@ class FadingIndexedStack extends StatefulWidget { super.key, required this.index, required this.children, - this.duration = const Duration( - milliseconds: 250, - ), + this.duration = const Duration(milliseconds: 250), }); final int index; @@ -135,8 +134,10 @@ class FadingIndexedStackState extends State { @override void didUpdateWidget(FadingIndexedStack oldWidget) { if (oldWidget.index == widget.index) return; - setState(() => _targetOpacity = 0); - Future.delayed(1.milliseconds, () => setState(() => _targetOpacity = 1)); + _targetOpacity = 0; + SchedulerBinding.instance.addPostFrameCallback( + (_) => setState(() => _targetOpacity = 1), + ); super.didUpdateWidget(oldWidget); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart index 82165b3518..364e12644c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart @@ -1,12 +1,14 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FavoriteFolder extends StatelessWidget { @@ -98,6 +100,8 @@ class _FavoriteHeaderState extends State { children: [ FlowyTextButton( LocaleKeys.sideBar_favorites.tr(), + fontColor: AFThemeExtension.of(context).textColor, + fontHoverColor: Theme.of(context).colorScheme.onSurface, tooltip: LocaleKeys.sideBar_clickToHideFavorites.tr(), constraints: const BoxConstraints(maxHeight: iconSize), padding: const EdgeInsets.all(4), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart index 8762833353..422003fdd9 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart @@ -43,6 +43,7 @@ class _FolderHeaderState extends State { minHeight: iconSize + textPadding * 2, ), fontColor: AFThemeExtension.of(context).textColor, + fontHoverColor: Theme.of(context).colorScheme.onSurface, padding: const EdgeInsets.all(textPadding), fillColor: Colors.transparent, onPressed: widget.onPressed, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 67b98b9060..8d798ef853 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -178,9 +178,7 @@ class HomeSideBar extends StatelessWidget { } class _Sidebar extends StatefulWidget { - const _Sidebar({ - required this.userProfile, - }); + const _Sidebar({required this.userProfile}); final UserProfilePB userProfile; @@ -222,10 +220,7 @@ class _SidebarState extends State<_Sidebar> { mainAxisSize: MainAxisSize.min, children: [ // top menu - const Padding( - padding: menuHorizontalInset, - child: SidebarTopMenu(), - ), + const Padding(padding: menuHorizontalInset, child: SidebarTopMenu()), // user or workspace, setting Padding( padding: menuHorizontalInset, @@ -245,8 +240,9 @@ class _SidebarState extends State<_Sidebar> { // scrollable document list Expanded( child: Padding( - padding: menuHorizontalInset, + padding: menuHorizontalInset - const EdgeInsets.only(right: 6), child: SingleChildScrollView( + padding: const EdgeInsets.only(right: 6), controller: _scrollController, physics: const ClampingScrollPhysics(), child: SidebarFolder( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart index 48370d9a58..dbbf3f0d0e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_folder.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; @@ -10,7 +12,6 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_sectio import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class SidebarFolder extends StatelessWidget { @@ -38,10 +39,7 @@ class SidebarFolder extends StatelessWidget { } return Padding( padding: const EdgeInsets.only(bottom: 10), - child: FavoriteFolder( - // remove the duplicate views - views: state.views, - ), + child: FavoriteFolder(views: state.views), ); }, ), @@ -52,30 +50,27 @@ class SidebarFolder extends StatelessWidget { final isCollaborativeWorkspace = context.read().state.isCollabWorkspaceOn; + // only show public and private section if the workspace is collaborative return Column( - children: - // only show public and private section if the workspace is collaborative - isCollaborativeWorkspace - ? [ - // public - const VSpace(10), - PublicSectionFolder( - views: state.section.publicViews, - ), + children: isCollaborativeWorkspace + ? [ + // public + const VSpace(10), + PublicSectionFolder(views: state.section.publicViews), - // private - const VSpace(10), - PrivateSectionFolder( - views: state.section.privateViews, - ), - ] - : [ - // personal - const VSpace(10), - PersonalSectionFolder( - views: state.section.publicViews, - ), - ], + // private + const VSpace(10), + PrivateSectionFolder( + views: state.section.privateViews, + ), + ] + : [ + // personal + const VSpace(10), + PersonalSectionFolder( + views: state.section.publicViews, + ), + ], ); }, ), @@ -87,10 +82,8 @@ class SidebarFolder extends StatelessWidget { } class PrivateSectionFolder extends SectionFolder { - PrivateSectionFolder({ - super.key, - required super.views, - }) : super( + PrivateSectionFolder({super.key, required super.views}) + : super( title: LocaleKeys.sideBar_private.tr(), categoryType: FolderCategoryType.private, expandButtonTooltip: LocaleKeys.sideBar_clickToHidePrivate.tr(), @@ -99,10 +92,8 @@ class PrivateSectionFolder extends SectionFolder { } class PublicSectionFolder extends SectionFolder { - PublicSectionFolder({ - super.key, - required super.views, - }) : super( + PublicSectionFolder({super.key, required super.views}) + : super( title: LocaleKeys.sideBar_workspace.tr(), categoryType: FolderCategoryType.public, expandButtonTooltip: LocaleKeys.sideBar_clickToHideWorkspace.tr(), @@ -111,10 +102,8 @@ class PublicSectionFolder extends SectionFolder { } class PersonalSectionFolder extends SectionFolder { - PersonalSectionFolder({ - super.key, - required super.views, - }) : super( + PersonalSectionFolder({super.key, required super.views}) + : super( title: LocaleKeys.sideBar_personal.tr(), categoryType: FolderCategoryType.public, expandButtonTooltip: LocaleKeys.sideBar_clickToHidePersonal.tr(), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index c9751d8ea9..057b3d8f99 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; @@ -24,7 +26,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; typedef ViewItemOnSelected = void Function(ViewPB, BuildContext); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart index aa3c7f8702..5eae1ef34c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:appflowy/env/cloud_env.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/plugins/base/emoji/emoji_picker.dart'; +import 'package:appflowy/plugins/base/icon/icon_picker.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; import 'package:appflowy/workspace/application/user/settings_user_bloc.dart'; @@ -14,18 +13,16 @@ import 'package:appflowy/workspace/presentation/settings/shared/settings_categor import 'package:appflowy/workspace/presentation/settings/shared/settings_category_spacer.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_header.dart'; import 'package:appflowy/workspace/presentation/settings/shared/settings_input_field.dart'; -import 'package:appflowy/workspace/presentation/settings/shared/single_setting_action.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/setting_third_party_login.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart'; import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart'; import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -51,15 +48,6 @@ class SettingsAccountView extends StatefulWidget { class _SettingsAccountViewState extends State { late String userName = widget.userProfile.name; - late final TextEditingController _emailController = TextEditingController( - text: widget.userProfile.email, - ); - - @override - void dispose() { - _emailController.dispose(); - super.dispose(); - } @override Widget build(BuildContext context) { @@ -67,11 +55,7 @@ class _SettingsAccountViewState extends State { create: (context) => getIt(param1: widget.userProfile) ..add(const SettingsUserEvent.initial()), - child: BlocConsumer( - listenWhen: (previous, current) => - previous.userProfile.email != current.userProfile.email, - listener: (context, state) => - _emailController.text = state.userProfile.email, + child: BlocBuilder( builder: (context, state) { return SettingsBody( children: [ @@ -97,45 +81,47 @@ class _SettingsAccountViewState extends State { ), ], ), - // Only show change email if the user is authenticated and not using local auth - if (isAuthEnabled && - state.userProfile.authenticator != AuthenticatorPB.Local) ...[ - const SettingsCategorySpacer(), - SettingsCategory( - title: LocaleKeys.settings_accountPage_email_title.tr(), - children: [ - SingleSettingAction( - label: state.userProfile.email, - buttonLabel: LocaleKeys - .settings_accountPage_email_actions_change - .tr(), - onPressed: () => SettingsAlertDialog( - title: LocaleKeys - .settings_accountPage_email_actions_change - .tr(), - confirmLabel: LocaleKeys.button_save.tr(), - confirm: () { - context.read().add( - SettingsUserEvent.updateUserEmail( - _emailController.text, - ), - ); - Navigator.of(context).pop(); - }, - children: [ - SettingsInputField( - label: LocaleKeys.settings_accountPage_email_title - .tr(), - value: state.userProfile.email, - hideActions: true, - textController: _emailController, - ), - ], - ).show(context), - ), - ], - ), - ], + + // Enable when/if we need change email feature + // // Only show change email if the user is authenticated and not using local auth + // if (isAuthEnabled && + // state.userProfile.authenticator != AuthenticatorPB.Local) ...[ + // const SettingsCategorySpacer(), + // SettingsCategory( + // title: LocaleKeys.settings_accountPage_email_title.tr(), + // children: [ + // SingleSettingAction( + // label: state.userProfile.email, + // buttonLabel: LocaleKeys + // .settings_accountPage_email_actions_change + // .tr(), + // onPressed: () => SettingsAlertDialog( + // title: LocaleKeys + // .settings_accountPage_email_actions_change + // .tr(), + // confirmLabel: LocaleKeys.button_save.tr(), + // confirm: () { + // context.read().add( + // SettingsUserEvent.updateUserEmail( + // _emailController.text, + // ), + // ); + // Navigator.of(context).pop(); + // }, + // children: [ + // SettingsInputField( + // label: LocaleKeys.settings_accountPage_email_title + // .tr(), + // value: state.userProfile.email, + // hideActions: true, + // textController: _emailController, + // ), + // ], + // ).show(context), + // ), + // ], + // ), + // ], /// Enable when we have change password feature and 2FA // const SettingsCategorySpacer(), @@ -259,7 +245,9 @@ class SignInOutButton extends StatelessWidget { hoverColor: const Color(0xFF005483), fontHoverColor: Colors.white, onPressed: () => SettingsAlertDialog( - title: LocaleKeys.settings_accountPage_login_loginLabel.tr(), + title: signIn + ? LocaleKeys.settings_accountPage_login_loginLabel.tr() + : LocaleKeys.settings_accountPage_login_logoutLabel.tr(), subtitle: signIn ? null : switch (userProfile.encryptionType) { @@ -303,6 +291,7 @@ class UserProfileSetting extends StatefulWidget { } class _UserProfileSettingState extends State { + late final _nameController = TextEditingController(text: widget.name); late final FocusNode focusNode; bool isEditing = false; bool isHovering = false; @@ -314,14 +303,20 @@ class _UserProfileSettingState extends State { onKeyEvent: (_, event) { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.escape && - isEditing) { + isEditing && + mounted) { setState(() => isEditing = false); return KeyEventResult.handled; } return KeyEventResult.ignored; }, - ); + )..addListener(() { + if (!focusNode.hasFocus && isEditing && mounted) { + widget.onSave?.call(_nameController.text); + setState(() => isEditing = false); + } + }); } @override @@ -335,69 +330,28 @@ class _UserProfileSettingState extends State { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Stack( - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => _showIconPickerDialog(context), - child: FlowyHover( - resetHoverOnRebuild: false, - onHover: (state) => setState(() => isHovering = state), - style: HoverStyle( - hoverColor: Colors.transparent, - borderRadius: BorderRadius.circular(100), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - UserAvatar( - iconUrl: widget.iconUrl, - name: widget.name, - isLarge: true, - isHovering: isHovering, - ), - const VSpace(4), - FlowyText.regular( - LocaleKeys - .settings_accountPage_general_changeProfilePicture - .tr(), - color: AFThemeExtension.of(context).textColor, - ), - ], - ), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => _showIconPickerDialog(context), + child: FlowyHover( + resetHoverOnRebuild: false, + onHover: (state) => setState(() => isHovering = state), + style: HoverStyle( + hoverColor: Colors.transparent, + borderRadius: BorderRadius.circular(100), + ), + child: FlowyTooltip( + message: LocaleKeys + .settings_accountPage_general_changeProfilePicture + .tr(), + child: UserAvatar( + iconUrl: widget.iconUrl, + name: widget.name, + isLarge: true, + isHovering: isHovering, ), ), - if (widget.iconUrl.isNotEmpty) - Positioned( - right: 0, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => context - .read() - .add(const SettingsUserEvent.removeUserIcon()), - child: DecoratedBox( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, - shape: BoxShape.circle, - ), - child: FlowyHover( - resetHoverOnRebuild: false, - style: const HoverStyle( - borderRadius: BorderRadius.all(Radius.circular(24)), - hoverColor: Color(0xFF005483), - ), - builder: (_, __) => Padding( - padding: const EdgeInsets.all(4), - child: FlowySvg( - FlowySvgs.close_s, - color: Theme.of(context).colorScheme.onPrimary, - ), - ), - ), - ), - ), - ), - ], + ), ), const HSpace(16), if (!isEditing) ...[ @@ -430,6 +384,7 @@ class _UserProfileSettingState extends State { ] else ...[ Flexible( child: SettingsInputField( + textController: _nameController, value: widget.name, focusNode: focusNode..requestFocus(), onCancel: () => setState(() => isEditing = false), @@ -448,20 +403,16 @@ class _UserProfileSettingState extends State { return showDialog( context: context, builder: (dialogContext) => SimpleDialog( - title: FlowyText.medium( - LocaleKeys.settings_user_selectAnIcon.tr(), - fontSize: FontSizes.s16, - ), children: [ Container( height: 380, width: 360, margin: const EdgeInsets.symmetric(horizontal: 12), - child: FlowyEmojiPicker( - onEmojiSelected: (_, emoji) { - context - .read() - .add(SettingsUserEvent.updateUserIcon(iconUrl: emoji)); + child: FlowyIconPicker( + onSelected: (result) { + context.read().add( + SettingsUserEvent.updateUserIcon(iconUrl: result.emoji), + ); Navigator.of(dialogContext).pop(); }, ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/files/settings_file_exporter_widget.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/files/settings_file_exporter_widget.dart index ea1cd98933..751599def3 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/files/settings_file_exporter_widget.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/files/settings_file_exporter_widget.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:flutter/material.dart'; + import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/export/document_exporter.dart'; import 'package:appflowy/workspace/application/settings/settings_file_exporter_cubit.dart'; @@ -13,8 +15,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/file_picker/file_picker_service.dart'; +import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart' hide WidgetBuilder; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:path/path.dart' as p; @@ -64,6 +66,7 @@ class _FileExporterWidgetState extends State { .every((element) => element) ? LocaleKeys.settings_files_deselectAll.tr() : LocaleKeys.settings_files_selectAll.tr(), + fontColor: AFThemeExtension.of(context).textColor, onPressed: () { context .read() @@ -93,13 +96,13 @@ class _FileExporterWidgetState extends State { const Spacer(), FlowyTextButton( LocaleKeys.button_cancel.tr(), - onPressed: () { - Navigator.of(context).pop(); - }, + fontColor: AFThemeExtension.of(context).textColor, + onPressed: () => Navigator.of(context).pop(), ), const HSpace(8), FlowyTextButton( LocaleKeys.button_ok.tr(), + fontColor: AFThemeExtension.of(context).textColor, onPressed: () async { await getIt() .getDirectoryPath() diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart index f88f3387d4..769071d55d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; @@ -8,8 +10,8 @@ import 'package:appflowy/workspace/application/settings/appearance/appearance_cu import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -208,9 +210,7 @@ class _FontFamilyDropDownState extends State { } class _ResetFontButton extends SliverPersistentHeaderDelegate { - _ResetFontButton({ - this.onPressed, - }); + _ResetFontButton({this.onPressed}); final VoidCallback? onPressed; @@ -224,6 +224,9 @@ class _ResetFontButton extends SliverPersistentHeaderDelegate { padding: const EdgeInsets.only(right: 8, bottom: 8.0), child: FlowyTextButton( LocaleKeys.document_toolbar_resetToDefaultFont.tr(), + fontColor: AFThemeExtension.of(context).textColor, + fontHoverColor: Theme.of(context).colorScheme.onSurface, + fontSize: 12, onPressed: onPressed, ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart index 169c53e802..00383e547d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart @@ -9,6 +9,7 @@ import 'package:appflowy/workspace/presentation/settings/shared/settings_body.da import 'package:appflowy/workspace/presentation/settings/shared/settings_header.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -75,6 +76,7 @@ class ShortcutsListView extends StatelessWidget { const Spacer(), FlowyTextButton( LocaleKeys.settings_shortcuts_resetToDefault.tr(), + fontColor: AFThemeExtension.of(context).textColor, onPressed: () => context.read().resetToDefault(), ), ], @@ -109,9 +111,8 @@ class ShortcutsListTile extends StatelessWidget { FlowyTextButton( shortcutEvent.command, fillColor: Colors.transparent, - onPressed: () { - showKeyListenerDialog(context); - }, + fontColor: AFThemeExtension.of(context).textColor, + onPressed: () => showKeyListenerDialog(context), ), ], ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart index 8dfa1217b2..c1b26df9b2 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -8,7 +8,6 @@ import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dar import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; class SettingsMenu extends StatelessWidget { @@ -59,60 +58,42 @@ class SettingsMenu extends StatelessWidget { page: SettingsPage.appearance, selectedPage: currentPage, label: LocaleKeys.settings_menu_appearance.tr(), - icon: Icon( - Icons.brightness_4, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.brightness_4), changeSelectedPage: changeSelectedPage, ), SettingsMenuElement( page: SettingsPage.language, selectedPage: currentPage, label: LocaleKeys.settings_menu_language.tr(), - icon: Icon( - Icons.translate, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.translate), changeSelectedPage: changeSelectedPage, ), SettingsMenuElement( page: SettingsPage.files, selectedPage: currentPage, label: LocaleKeys.settings_menu_files.tr(), - icon: Icon( - Icons.file_present_outlined, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.file_present_outlined), changeSelectedPage: changeSelectedPage, ), SettingsMenuElement( page: SettingsPage.notifications, selectedPage: currentPage, label: LocaleKeys.settings_menu_notifications.tr(), - icon: Icon( - Icons.notifications_outlined, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.notifications_outlined), changeSelectedPage: changeSelectedPage, ), SettingsMenuElement( page: SettingsPage.cloud, selectedPage: currentPage, label: LocaleKeys.settings_menu_cloudSettings.tr(), - icon: Icon( - Icons.sync, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.sync), changeSelectedPage: changeSelectedPage, ), SettingsMenuElement( page: SettingsPage.shortcuts, selectedPage: currentPage, label: LocaleKeys.settings_shortcuts_shortcutsLabel.tr(), - icon: Icon( - Icons.cut, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.cut), changeSelectedPage: changeSelectedPage, ), if (FeatureFlag.membersSettings.isOn && @@ -122,10 +103,7 @@ class SettingsMenu extends StatelessWidget { page: SettingsPage.member, selectedPage: currentPage, label: LocaleKeys.settings_appearance_members_label.tr(), - icon: Icon( - Icons.people, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.people), changeSelectedPage: changeSelectedPage, ), if (kDebugMode) @@ -134,10 +112,7 @@ class SettingsMenu extends StatelessWidget { page: SettingsPage.featureFlags, selectedPage: currentPage, label: 'Feature Flags', - icon: Icon( - Icons.flag, - color: AFThemeExtension.of(context).textColor, - ), + icon: const Icon(Icons.flag), changeSelectedPage: changeSelectedPage, ), ], diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart index d06b08d4db..b8cafe87a6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart @@ -31,9 +31,13 @@ class SettingsMenuElement extends StatelessWidget { hoverColor: AFThemeExtension.of(context).greySelect, borderRadius: BorderRadius.circular(4), ), - child: ListTile( + builder: (_, isHovering) => ListTile( dense: true, - leading: icon, + leading: iconWidget( + isHovering || page == selectedPage + ? Theme.of(context).colorScheme.onSurface + : AFThemeExtension.of(context).textColor, + ), onTap: () => changeSelectedPage(page), selected: page == selectedPage, selectedColor: Theme.of(context).colorScheme.onSurface, @@ -53,4 +57,9 @@ class SettingsMenuElement extends StatelessWidget { ), ); } + + Widget iconWidget(Color color) => IconTheme( + data: IconThemeData(color: color), + child: icon, + ); } diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 691bdf3d7b..b1b35ee0d4 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -324,7 +324,7 @@ "description": "Customize your profile, manage account security and AI API keys, or login into your account.", "general": { "title": "Account name & profile image", - "changeProfilePicture": "Change" + "changeProfilePicture": "Change profile picture" }, "email": { "title": "Email",