From 5de716b19d19dca54ad74546a3fb45bd6a6a9968 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 3 Oct 2024 09:39:52 +0800 Subject: [PATCH] feat: update workspace icon style on desktop (#6452) * feat: update workspace icon style on desktop * fix: unable to insert two referenced link at the same doc --- .../document/document_with_database_test.dart | 51 ++++++++++ .../home/mobile_home_page_header.dart | 2 +- .../workspace_menu_bottom_sheet.dart | 2 +- .../base/link_to_page_widget.dart | 7 +- .../inline_actions/inline_actions_menu.dart | 4 +- .../workspace/_sidebar_workspace_icon.dart | 98 +------------------ .../workspace/_sidebar_workspace_menu.dart | 51 +++++----- .../sidebar/workspace/sidebar_workspace.dart | 9 +- .../pages/settings_workspace_view.dart | 14 ++- 9 files changed, 95 insertions(+), 143 deletions(-) diff --git a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_database_test.dart b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_database_test.dart index eb07a2e7a8..ede3627598 100644 --- a/frontend/appflowy_flutter/integration_test/desktop/document/document_with_database_test.dart +++ b/frontend/appflowy_flutter/integration_test/desktop/document/document_with_database_test.dart @@ -60,6 +60,57 @@ void main() { ); }); + testWidgets('insert multiple referenced boards', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapAnonymousSignInButton(); + + // create a new grid + final id = uuid(); + final name = '${ViewLayoutPB.Board.name}_$id'; + await tester.createNewPageWithNameUnderParent( + name: name, + layout: ViewLayoutPB.Board, + openAfterCreated: false, + ); + // create a new document + await tester.createNewPageWithNameUnderParent( + name: 'insert_a_reference_${ViewLayoutPB.Board.name}', + ); + // tap the first line of the document + await tester.editor.tapLineOfEditorAt(0); + // insert a referenced view + await tester.editor.showSlashMenu(); + await tester.editor.tapSlashMenuItemWithName( + ViewLayoutPB.Board.slashMenuLinkedName, + ); + final referencedDatabase1 = find.descendant( + of: find.byType(InlineActionsHandler), + matching: find.findTextInFlowyText(name), + ); + expect(referencedDatabase1, findsOneWidget); + await tester.tapButton(referencedDatabase1); + + await tester.editor.tapLineOfEditorAt(1); + await tester.editor.showSlashMenu(); + await tester.editor.tapSlashMenuItemWithName( + ViewLayoutPB.Board.slashMenuLinkedName, + ); + final referencedDatabase2 = find.descendant( + of: find.byType(InlineActionsHandler), + matching: find.findTextInFlowyText(name), + ); + expect(referencedDatabase2, findsOneWidget); + await tester.tapButton(referencedDatabase2); + + expect( + find.descendant( + of: find.byType(AppFlowyEditor), + matching: find.byType(DesktopBoardPage), + ), + findsNWidgets(2), + ); + }); + testWidgets('insert a referenced calendar', (tester) async { await tester.initializeAppFlowy(); await tester.tapAnonymousSignInButton(); diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index 57cf55b50c..4069acf623 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -121,7 +121,7 @@ class _MobileWorkspace extends StatelessWidget { }, child: Row( children: [ - WorkspaceIconV2( + WorkspaceIcon( workspace: currentWorkspace, iconSize: 36, fontSize: 18.0, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart index f9ff5cd1eb..7ce32ccf3d 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart @@ -272,7 +272,7 @@ class _WorkspaceMenuItemIcon extends StatelessWidget { Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 4.0), - child: WorkspaceIconV2( + child: WorkspaceIcon( enableEdit: false, iconSize: 36, emojiSize: 24.0, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/link_to_page_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/link_to_page_widget.dart index 0dcb8dd3e6..5b3ca8270e 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/link_to_page_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/link_to_page_widget.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/inline_actions/handlers/inline_page_reference.dart'; import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart'; @@ -8,6 +6,7 @@ import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; InlineActionsMenuService? _actionsMenuService; Future showLinkToPageMenu( @@ -15,6 +14,8 @@ Future showLinkToPageMenu( SelectionMenuService menuService, ViewLayoutPB pageType, ) async { + keepEditorFocusNotifier.increase(); + menuService.dismiss(); _actionsMenuService?.dismiss(); @@ -27,7 +28,7 @@ Future showLinkToPageMenu( context: rootContext, handlers: [ InlinePageReferenceService( - currentViewId: "", + currentViewId: '', viewLayout: pageType, customTitle: titleFromPageType(pageType), insertPage: pageType != ViewLayoutPB.Document, diff --git a/frontend/appflowy_flutter/lib/plugins/inline_actions/inline_actions_menu.dart b/frontend/appflowy_flutter/lib/plugins/inline_actions/inline_actions_menu.dart index 3521a889e8..e31d7c2ef0 100644 --- a/frontend/appflowy_flutter/lib/plugins/inline_actions/inline_actions_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/inline_actions/inline_actions_menu.dart @@ -1,9 +1,8 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart'; import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart'; import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; abstract class InlineActionsMenuService { InlineActionsMenuStyle get style; @@ -40,6 +39,7 @@ class InlineActionsMenu extends InlineActionsMenuService { if (_menuEntry != null) { editorState.service.keyboardService?.enable(); editorState.service.scrollService?.enable(); + keepEditorFocusNotifier.decrease(); } _menuEntry?.remove(); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index 3afda42efd..fd044e0aa6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart'; import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart'; @@ -24,96 +22,6 @@ class WorkspaceIcon extends StatefulWidget { this.emojiSize, this.alignment, required this.figmaLineHeight, - }); - - final UserWorkspacePB workspace; - final double iconSize; - final bool enableEdit; - final double fontSize; - final double? emojiSize; - final void Function(EmojiPickerResult) onSelected; - final double borderRadius; - final Alignment? alignment; - final double figmaLineHeight; - - @override - State createState() => _WorkspaceIconState(); -} - -class _WorkspaceIconState extends State { - final controller = PopoverController(); - - @override - Widget build(BuildContext context) { - Widget child = widget.workspace.icon.isNotEmpty - ? Container( - width: widget.iconSize, - alignment: widget.alignment ?? Alignment.center, - child: FlowyText.emoji( - widget.workspace.icon, - fontSize: widget.emojiSize ?? widget.iconSize, - figmaLineHeight: widget.figmaLineHeight, - optimizeEmojiAlign: true, - ), - ) - : Container( - alignment: Alignment.center, - width: widget.iconSize, - height: min(widget.iconSize, 24), - decoration: BoxDecoration( - color: ColorGenerator(widget.workspace.name).toColor(), - borderRadius: BorderRadius.circular(widget.borderRadius), - border: Border.all( - color: const Color(0xa1717171), - width: 0.5, - ), - ), - child: FlowyText.semibold( - widget.workspace.name.isEmpty - ? '' - : widget.workspace.name.substring(0, 1), - fontSize: widget.fontSize, - color: Colors.black, - ), - ); - - if (widget.enableEdit) { - child = AppFlowyPopover( - offset: const Offset(0, 8), - controller: controller, - direction: PopoverDirection.bottomWithLeftAligned, - constraints: BoxConstraints.loose(const Size(364, 356)), - clickHandler: PopoverClickHandler.gestureDetector, - margin: const EdgeInsets.all(0), - popupBuilder: (_) => FlowyIconEmojiPicker( - onSelectedEmoji: (result) { - widget.onSelected(result); - controller.close(); - }, - ), - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: child, - ), - ); - } - return child; - } -} - -// The v2 supports the built-in color set -class WorkspaceIconV2 extends StatefulWidget { - const WorkspaceIconV2({ - super.key, - required this.workspace, - required this.enableEdit, - required this.iconSize, - required this.fontSize, - required this.onSelected, - this.borderRadius = 4, - this.emojiSize, - this.alignment, - required this.figmaLineHeight, this.showBorder = true, }); @@ -129,10 +37,10 @@ class WorkspaceIconV2 extends StatefulWidget { final bool showBorder; @override - State createState() => _WorkspaceIconV2State(); + State createState() => _WorkspaceIconState(); } -class _WorkspaceIconV2State extends State { +class _WorkspaceIconState extends State { final controller = PopoverController(); @override @@ -178,7 +86,7 @@ class _WorkspaceIconV2State extends State { Widget _buildEditableIcon(Widget child) { if (UniversalPlatform.isDesktopOrWeb) { - AppFlowyPopover( + return AppFlowyPopover( offset: const Offset(0, 8), controller: controller, direction: PopoverDirection.bottomWithLeftAligned, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart index 97ee729e52..96b59cdb06 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart @@ -153,31 +153,22 @@ class _WorkspaceMenuItemState extends State { } Widget _buildLeftIcon(BuildContext context) { - return Container( - width: 32.0, - height: 32.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - border: Border.all( - color: const Color(0x01717171).withOpacity(0.12), - width: 0.8, - ), - ), - child: FlowyTooltip( - message: LocaleKeys.document_plugins_cover_changeIcon.tr(), - child: WorkspaceIcon( - workspace: widget.workspace, - iconSize: 22, - fontSize: 16, - figmaLineHeight: 32.0, - enableEdit: true, - onSelected: (result) => context.read().add( - UserWorkspaceEvent.updateWorkspaceIcon( - widget.workspace.workspaceId, - result.emoji, - ), + return FlowyTooltip( + message: LocaleKeys.document_plugins_cover_changeIcon.tr(), + child: WorkspaceIcon( + workspace: widget.workspace, + iconSize: 36, + emojiSize: 24.0, + fontSize: 18.0, + figmaLineHeight: 26.0, + borderRadius: 12.0, + enableEdit: true, + onSelected: (result) => context.read().add( + UserWorkspaceEvent.updateWorkspaceIcon( + widget.workspace.workspaceId, + result.emoji, ), - ), + ), ), ); } @@ -321,8 +312,10 @@ class _CreateWorkspaceButton extends StatelessWidget { text: Row( children: [ _buildLeftIcon(context), - const HSpace(10.0), - FlowyText.regular(LocaleKeys.workspace_create.tr()), + const HSpace(8.0), + FlowyText.regular( + LocaleKeys.workspace_create.tr(), + ), ], ), ), @@ -331,11 +324,11 @@ class _CreateWorkspaceButton extends StatelessWidget { Widget _buildLeftIcon(BuildContext context) { return Container( - width: 32.0, - height: 32.0, + width: 36.0, + height: 36.0, padding: const EdgeInsets.all(7.0), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(12), border: Border.all( color: const Color(0x01717171).withOpacity(0.12), width: 0.8, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart index 55c6da4d43..57bc05ec03 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart @@ -273,12 +273,13 @@ class _SideBarSwitchWorkspaceButtonChild extends StatelessWidget { const HSpace(4.0), WorkspaceIcon( workspace: currentWorkspace, - iconSize: 24, + iconSize: 26, fontSize: 16, - emojiSize: 18, + emojiSize: 20, enableEdit: false, borderRadius: 8.0, - figmaLineHeight: 21.0, + figmaLineHeight: 18.0, + showBorder: false, onSelected: (result) => context.read().add( UserWorkspaceEvent.updateWorkspaceIcon( currentWorkspace.workspaceId, @@ -286,7 +287,7 @@ class _SideBarSwitchWorkspaceButtonChild extends StatelessWidget { ), ), ), - const HSpace(8), + const HSpace(6), Flexible( child: FlowyText.medium( currentWorkspace.name, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart index e93397bed6..8c6ac3e1e1 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart @@ -345,20 +345,18 @@ class _WorkspaceIconSetting extends StatelessWidget { ); } - return Container( + return SizedBox( height: 64, width: 64, - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).colorScheme.outline), - borderRadius: BorderRadius.circular(8), - ), child: Padding( padding: const EdgeInsets.all(1), child: WorkspaceIcon( workspace: workspace!, - iconSize: workspace!.icon.isNotEmpty == true ? 46 : 20, - fontSize: 16.0, - figmaLineHeight: 46, + iconSize: 36, + emojiSize: 24.0, + fontSize: 24.0, + figmaLineHeight: 26.0, + borderRadius: 18.0, enableEdit: true, onSelected: (r) => context .read()