From c78f23e1c01cb0857f57b57957a62c1863eb6042 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 1 Jul 2024 14:43:57 +0800 Subject: [PATCH] fix: v0.6.2 issues (#5654) * fix: remove create button in move to menu * fix: add loading indicator when duplicating space * fix: sidebar header expand icon status * fix: text within select tag overflow * fix: callout block icon align issue * feat: sync the space icon when creating a space * fix: duplicated hover views * fix: cover image doesn't update --- .../desktop_grid_select_option_cell.dart | 6 +-- ...desktop_row_detail_select_option_cell.dart | 6 +-- .../widgets/cell_editor/extension.dart | 1 - .../select_option_cell_editor.dart | 12 ++--- .../cell_editor/select_option_text_field.dart | 5 +- .../document/application/document_bloc.dart | 15 ------ .../callout/callout_block_component.dart | 3 +- .../header/document_header_node_widget.dart | 7 ++- .../migration/editor_migration.dart | 7 ++- .../application/sidebar/space/space_bloc.dart | 43 +++++++-------- .../workspace/application/view/view_ext.dart | 6 +-- .../workspace/workspace_service.dart | 5 ++ .../menu/sidebar/move_to/move_page_menu.dart | 1 + .../home/menu/sidebar/sidebar.dart | 14 ++++- .../menu/sidebar/space/shared_widget.dart | 12 +++-- .../sidebar/space/sidebar_space_header.dart | 1 + .../sidebar/space/sidebar_space_menu.dart | 27 ++++++---- .../home/menu/view/view_item.dart | 53 +++++++++++-------- .../event-integration-test/src/chat_event.rs | 1 + .../src/database_event.rs | 3 ++ .../src/document/document_event.rs | 1 + .../src/document_event.rs | 1 + .../src/folder_event.rs | 2 + .../tests/folder/local_test/script.rs | 1 + .../flowy-folder/src/entities/view.rs | 7 ++- 25 files changed, 142 insertions(+), 98 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart index 45b43efcec7e1..ee283d6cccc8b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_select_option_cell.dart @@ -1,8 +1,8 @@ +import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; -import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; -import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_bloc.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; +import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -56,7 +56,7 @@ class DesktopGridSelectOptionCellSkin extends IEditableSelectOptionCellSkin { child: SelectOptionTag( option: option, padding: const EdgeInsets.symmetric( - vertical: 1, + vertical: 4, horizontal: 8, ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart index 0e8c6fdffaa12..31dc63abe4995 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_select_option_cell.dart @@ -1,8 +1,8 @@ import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; -import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_bloc.dart'; +import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart'; import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart'; +import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -67,7 +67,7 @@ class DesktopRowDetailSelectOptionCellSkin return SelectOptionTag( option: option, padding: const EdgeInsets.symmetric( - vertical: 1, + vertical: 4, horizontal: 8, ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart index d4d93d4f4b000..a92fba5e24f57 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/extension.dart @@ -96,7 +96,6 @@ class SelectOptionTag extends StatelessWidget { ); return Container( - height: 20, padding: onRemove == null ? padding : padding.copyWith(right: 2.0), decoration: BoxDecoration( color: optionColor, diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart index a2653a53896fc..8fdb99769aec0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart @@ -1,10 +1,6 @@ import 'dart:collection'; import 'dart:io'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart'; @@ -14,12 +10,14 @@ import 'package:appflowy_popover/appflowy_popover.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/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../grid/presentation/layout/sizes.dart'; import '../../grid/presentation/widgets/common/type_option_separator.dart'; import '../field/type_option_editor/select/select_option_editor.dart'; - import 'extension.dart'; import 'select_option_text_field.dart'; @@ -476,11 +474,11 @@ class SelectOptionTagCell extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric( horizontal: 6.0, - vertical: 4.0, ), child: SelectOptionTag( option: option, - padding: const EdgeInsets.symmetric(horizontal: 8), + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 4), ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart index f16500f6019a3..2a4b8daa37d62 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart @@ -132,7 +132,10 @@ class _SelectOptionTextFieldState extends State { (option) => SelectOptionTag( option: option, onRemove: (option) => widget.onRemove(option), - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1), + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), ), ) .toList(); diff --git a/frontend/appflowy_flutter/lib/plugins/document/application/document_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/application/document_bloc.dart index 121582e1f313c..a50c7cac2d2a9 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/application/document_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/application/document_bloc.dart @@ -8,7 +8,6 @@ import 'package:appflowy/plugins/document/application/document_data_pb_extension import 'package:appflowy/plugins/document/application/document_listener.dart'; import 'package:appflowy/plugins/document/application/document_service.dart'; import 'package:appflowy/plugins/document/application/editor_transaction_adapter.dart'; -import 'package:appflowy/plugins/document/presentation/editor_plugins/migration/editor_migration.dart'; import 'package:appflowy/plugins/trash/application/trash_service.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; @@ -19,7 +18,6 @@ import 'package:appflowy/util/color_to_hex_string.dart'; import 'package:appflowy/util/debounce.dart'; import 'package:appflowy/util/throttle.dart'; import 'package:appflowy/workspace/application/view/view_listener.dart'; -import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; @@ -118,11 +116,6 @@ class DocumentBloc extends Bloc { final result = await _fetchDocumentState(); _onViewChanged(); _onDocumentChanged(); - result.onSuccess((s) { - if (s != null) { - _migrateCover(s); - } - }); final newState = await result.fold( (s) async { final userProfilePB = @@ -390,14 +383,6 @@ class DocumentBloc extends Bloc { metadata: jsonEncode(metadata.toJson()), ); } - - // from version 0.5.5, the cover is stored in the view.ext - Future _migrateCover(EditorState editorState) async { - final view = await ViewBackendService.getView(documentId); - view.onSuccess((s) { - return EditorMigration.migrateCoverIfNeeded(s, editorState); - }); - } } @freezed diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart index e025dd6d276a2..a7bfe2da41f28 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart @@ -196,6 +196,7 @@ class _CalloutBlockComponentWidgetState ), // force to refresh the popover state title: '', emoji: emoji, + emojiSize: 16.0, onSubmitted: (emoji, controller) { setEmoji(emoji); controller?.close(); @@ -204,7 +205,7 @@ class _CalloutBlockComponentWidgetState ), Flexible( child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), + padding: const EdgeInsets.symmetric(vertical: 6.0), child: buildCalloutBlockComponent(context, textDirection), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart index aa15ea7419949..40e4d54855a3f 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart @@ -91,6 +91,7 @@ class _DocumentCoverWidgetState extends State { String viewIcon = ''; PageStyleCover? cover; + late ViewPB view; late final ViewListener viewListener; @override @@ -99,6 +100,7 @@ class _DocumentCoverWidgetState extends State { final value = widget.view.icon.value; viewIcon = value.isNotEmpty ? value : icon ?? ''; cover = widget.view.cover; + view = widget.view; widget.node.addListener(_reload); viewListener = ViewListener( viewId: widget.view.id, @@ -107,6 +109,7 @@ class _DocumentCoverWidgetState extends State { setState(() { viewIcon = p0.icon.value; cover = p0.cover; + view = p0; }); }, ); @@ -137,7 +140,7 @@ class _DocumentCoverWidgetState extends State { ), if (hasCover) DocumentCover( - view: widget.view, + view: view, editorState: widget.editorState, node: widget.node, coverType: coverType, @@ -204,7 +207,7 @@ class _DocumentCoverWidgetState extends State { // compatible with version > 0.5.5. EditorMigration.migrateCoverIfNeeded( widget.view, - widget.editorState, + attributes, overwrite: true, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart index 664e2143b6ddc..545fe9dd4aa21 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart @@ -164,18 +164,17 @@ class EditorMigration { // Now, the cover is stored in the view.ext. static void migrateCoverIfNeeded( ViewPB view, - EditorState editorState, { + Attributes attributes, { bool overwrite = false, }) async { if (view.extra.isNotEmpty && !overwrite) { return; } - final root = editorState.document.root; final coverType = CoverType.fromString( - root.attributes[DocumentHeaderBlockKeys.coverType], + attributes[DocumentHeaderBlockKeys.coverType], ); - final coverDetails = root.attributes[DocumentHeaderBlockKeys.coverDetails]; + final coverDetails = attributes[DocumentHeaderBlockKeys.coverDetails]; Map extra = {}; diff --git a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart index f6a2226e6a58a..611908cb1a383 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart @@ -297,11 +297,16 @@ class SpaceBloc extends Bloc { if (currentSpace == null) { return; } + emit(state.copyWith(isDuplicatingSpace: true)); + final newSpace = await _duplicateSpace(currentSpace); // open the duplicated space if (newSpace != null) { + add(const SpaceEvent.didReceiveSpaceUpdate()); add(SpaceEvent.open(newSpace)); } + + emit(state.copyWith(isDuplicatingSpace: false)); }, ); }, @@ -346,25 +351,22 @@ class SpaceBloc extends Bloc { SpacePermission.private => ViewSectionPB.Private, }; + final extra = { + ViewExtKeys.isSpaceKey: true, + ViewExtKeys.spaceIconKey: icon, + ViewExtKeys.spaceIconColorKey: iconColor, + ViewExtKeys.spacePermissionKey: permission.index, + ViewExtKeys.spaceCreatedAtKey: DateTime.now().millisecondsSinceEpoch, + }; final result = await _workspaceService.createView( name: name, viewSection: section, - setAsCurrent: false, + setAsCurrent: true, viewId: viewId, + extra: jsonEncode(extra), ); return await result.fold((space) async { Log.info('Space created: $space'); - final extra = { - ViewExtKeys.isSpaceKey: true, - ViewExtKeys.spaceIconKey: icon, - ViewExtKeys.spaceIconColorKey: iconColor, - ViewExtKeys.spacePermissionKey: permission.index, - ViewExtKeys.spaceCreatedAtKey: DateTime.now().millisecondsSinceEpoch, - }; - await ViewBackendService.updateView( - viewId: space.id, - extra: jsonEncode(extra), - ); return space; }, (error) { Log.error('Failed to create space: $error'); @@ -620,19 +622,17 @@ class SpaceBloc extends Bloc { } for (final view in space.childViews) { - unawaited( - ViewBackendService.duplicate( - view: view, - openAfterDuplicate: true, - includeChildren: true, - parentViewId: newSpace.id, - suffix: '', - ), + await ViewBackendService.duplicate( + view: view, + openAfterDuplicate: true, + includeChildren: true, + parentViewId: newSpace.id, + suffix: '', ); } Log.info('Space duplicated: $newSpace'); - add(const SpaceEvent.didReceiveSpaceUpdate()); + return newSpace; } } @@ -688,6 +688,7 @@ class SpaceState with _$SpaceState { @Default(null) ViewPB? lastCreatedPage, FlowyResult? createPageResult, @Default(false) bool shouldShowUpgradeDialog, + @Default(false) bool isDuplicatingSpace, }) = _SpaceState; factory SpaceState.initial() => const SpaceState(); diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart index cfb1690e5e8ef..888f91897a868 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -133,13 +133,13 @@ extension ViewExtension on ViewPB { } } - FlowySvg get spaceIconSvg { + FlowySvg? get spaceIconSvg { try { final ext = jsonDecode(extra); final icon = ext[ViewExtKeys.spaceIconKey]; final color = ext[ViewExtKeys.spaceIconColorKey]; if (icon == null || color == null) { - return const FlowySvg(FlowySvgs.space_icon_s, blendMode: null); + return null; } return FlowySvg( FlowySvgData('assets/flowy_icons/16x/$icon.svg'), @@ -147,7 +147,7 @@ extension ViewExtension on ViewPB { blendMode: BlendMode.srcOut, ); } catch (e) { - return const FlowySvg(FlowySvgs.space_icon_s, blendMode: null); + return null; } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart index 8da9ad4854835..067767a9e1029 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart @@ -19,6 +19,7 @@ class WorkspaceService { ViewLayoutPB? layout, bool? setAsCurrent, String? viewId, + String? extra, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = workspaceId @@ -42,6 +43,10 @@ class WorkspaceService { payload.viewId = viewId; } + if (extra != null) { + payload.extra = extra; + } + return FolderEventCreateView(payload).send(); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart index 36352864e8d38..4225f81ad26f0 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart @@ -117,6 +117,7 @@ class _MovePageMenuState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SpacePopup( + showCreateButton: false, child: CurrentSpace( space: space, ), 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 a47d9db8629f7..f2abaecc1d504 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 @@ -5,6 +5,7 @@ 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/blank/blank.dart'; +import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart'; import 'package:appflowy/shared/feature_flags.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart'; @@ -38,6 +39,8 @@ import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +Loading? _duplicateSpaceLoading; + /// Home Sidebar is the left side bar of the home page. /// /// in the sidebar, we have: @@ -136,7 +139,8 @@ class HomeSideBar extends StatelessWidget { ), BlocListener( listenWhen: (p, c) => - p.lastCreatedPage?.id != c.lastCreatedPage?.id, + p.lastCreatedPage?.id != c.lastCreatedPage?.id || + p.isDuplicatingSpace != c.isDuplicatingSpace, listener: (context, state) { final page = state.lastCreatedPage; if (page == null || page.id.isEmpty) { @@ -153,6 +157,14 @@ class HomeSideBar extends StatelessWidget { ), ); } + + if (state.isDuplicatingSpace) { + _duplicateSpaceLoading ??= Loading(context); + _duplicateSpaceLoading?.start(); + } else if (_duplicateSpaceLoading != null) { + _duplicateSpaceLoading?.stop(); + _duplicateSpaceLoading = null; + } }, ), BlocListener( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart index 1ae08c0abdd00..42168abc9e8d9 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart @@ -277,9 +277,11 @@ class DeleteSpacePopup extends StatelessWidget { class SpacePopup extends StatelessWidget { const SpacePopup({ super.key, + required this.showCreateButton, required this.child, }); + final bool showCreateButton; final Widget child; @override @@ -293,7 +295,9 @@ class SpacePopup extends StatelessWidget { offset: const Offset(0, 4), popupBuilder: (_) => BlocProvider.value( value: context.read(), - child: const SidebarSpaceMenu(), + child: SidebarSpaceMenu( + showCreateButton: showCreateButton, + ), ), child: FlowyButton( useIntrinsicWidth: true, @@ -333,8 +337,10 @@ class CurrentSpace extends StatelessWidget { ), ), const HSpace(4.0), - const FlowySvg( - FlowySvgs.workspace_drop_down_menu_show_s, + FlowySvg( + context.read().state.isExpanded + ? FlowySvgs.workspace_drop_down_menu_show_s + : FlowySvgs.workspace_drop_down_menu_hide_s, ), ], ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart index 181828090810d..9adcdb6822622 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart @@ -89,6 +89,7 @@ class _SidebarSpaceHeaderState extends State { bottom: 3, right: isHovered.value || onEditing ? 88 : 0, child: SpacePopup( + showCreateButton: true, child: _buildChild(), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart index 6db5f54d8126b..9ff798ee5de81 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart @@ -14,7 +14,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class SidebarSpaceMenu extends StatelessWidget { - const SidebarSpaceMenu({super.key}); + const SidebarSpaceMenu({ + super.key, + required this.showCreateButton, + }); + + final bool showCreateButton; @override Widget build(BuildContext context) { @@ -32,16 +37,18 @@ class SidebarSpaceMenu extends StatelessWidget { isSelected: state.currentSpace?.id == space.id, ), ), - const Padding( - padding: EdgeInsets.symmetric(vertical: 8.0), - child: Divider( - height: 0.5, + if (showCreateButton) ...[ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Divider( + height: 0.5, + ), ), - ), - const SizedBox( - height: HomeSpaceViewSizes.viewHeight, - child: _CreateSpaceButton(), - ), + const SizedBox( + height: HomeSpaceViewSizes.viewHeight, + child: _CreateSpaceButton(), + ), + ], ], ); }, 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 860a9e3e81e33..9145c9ac78236 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 @@ -257,26 +257,33 @@ class _InnerViewItemState extends State { @override Widget build(BuildContext context) { - Widget child = SingleInnerViewItem( - view: widget.view, - parentView: widget.parentView, - level: widget.level, - showActions: widget.showActions, - spaceType: widget.spaceType, - onSelected: widget.onSelected, - onTertiarySelected: widget.onTertiarySelected, - isExpanded: widget.isExpanded, - isDraggable: widget.isDraggable, - leftPadding: widget.leftPadding, - isFeedback: widget.isFeedback, - height: widget.height, - isPlaceholder: widget.isPlaceholder, - isHovered: widget.isHovered, - leftIconBuilder: widget.leftIconBuilder, - rightIconsBuilder: widget.rightIconsBuilder, - extendBuilder: widget.extendBuilder, - disableSelectedStatus: widget.disableSelectedStatus, - shouldIgnoreView: widget.shouldIgnoreView, + Widget child = ValueListenableBuilder( + valueListenable: getIt().notifier, + builder: (context, value, _) { + final isSelected = value?.id == widget.view.id; + return SingleInnerViewItem( + view: widget.view, + parentView: widget.parentView, + level: widget.level, + showActions: widget.showActions, + spaceType: widget.spaceType, + onSelected: widget.onSelected, + onTertiarySelected: widget.onTertiarySelected, + isExpanded: widget.isExpanded, + isDraggable: widget.isDraggable, + leftPadding: widget.leftPadding, + isFeedback: widget.isFeedback, + height: widget.height, + isPlaceholder: widget.isPlaceholder, + isHovered: widget.isHovered, + leftIconBuilder: widget.leftIconBuilder, + rightIconsBuilder: widget.rightIconsBuilder, + extendBuilder: widget.extendBuilder, + disableSelectedStatus: widget.disableSelectedStatus, + shouldIgnoreView: widget.shouldIgnoreView, + isSelected: isSelected, + ); + }, ); // if the view is expanded and has child views, render its child views @@ -403,6 +410,7 @@ class SingleInnerViewItem extends StatefulWidget { required this.extendBuilder, required this.disableSelectedStatus, required this.shouldIgnoreView, + required this.isSelected, }); final ViewPB view; @@ -430,6 +438,7 @@ class SingleInnerViewItem extends StatefulWidget { final List Function(ViewPB view)? extendBuilder; final bool Function(ViewPB view)? shouldIgnoreView; + final bool isSelected; @override State createState() => _SingleInnerViewItemState(); @@ -441,8 +450,8 @@ class _SingleInnerViewItemState extends State { @override Widget build(BuildContext context) { - var isSelected = - getIt().latestOpenView?.id == widget.view.id; + var isSelected = widget.isSelected; + if (widget.disableSelectedStatus == true) { isSelected = false; } diff --git a/frontend/rust-lib/event-integration-test/src/chat_event.rs b/frontend/rust-lib/event-integration-test/src/chat_event.rs index a02fc6805fe45..2371820f84e9a 100644 --- a/frontend/rust-lib/event-integration-test/src/chat_event.rs +++ b/frontend/rust-lib/event-integration-test/src/chat_event.rs @@ -22,6 +22,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration-test/src/database_event.rs b/frontend/rust-lib/event-integration-test/src/database_event.rs index 4b6968ec0666a..b16f9d5ab59aa 100644 --- a/frontend/rust-lib/event-integration-test/src/database_event.rs +++ b/frontend/rust-lib/event-integration-test/src/database_event.rs @@ -46,6 +46,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -78,6 +79,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -105,6 +107,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration-test/src/document/document_event.rs b/frontend/rust-lib/event-integration-test/src/document/document_event.rs index 8595ac056b373..4203dcc88cc17 100644 --- a/frontend/rust-lib/event-integration-test/src/document/document_event.rs +++ b/frontend/rust-lib/event-integration-test/src/document/document_event.rs @@ -66,6 +66,7 @@ impl DocumentEventTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(core.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration-test/src/document_event.rs b/frontend/rust-lib/event-integration-test/src/document_event.rs index 8374bc9de3eb1..6194e10ab7385 100644 --- a/frontend/rust-lib/event-integration-test/src/document_event.rs +++ b/frontend/rust-lib/event-integration-test/src/document_event.rs @@ -43,6 +43,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; let view = EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) diff --git a/frontend/rust-lib/event-integration-test/src/folder_event.rs b/frontend/rust-lib/event-integration-test/src/folder_event.rs index 0a13eb7f5bb71..be218fa89d191 100644 --- a/frontend/rust-lib/event-integration-test/src/folder_event.rs +++ b/frontend/rust-lib/event-integration-test/src/folder_event.rs @@ -238,6 +238,7 @@ impl EventIntegrationTest { index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -302,6 +303,7 @@ impl ViewTest { index: None, section: None, view_id: None, + extra: None, }; let view = EventBuilder::new(sdk.clone()) diff --git a/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs b/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs index 0ebbd64efa9b6..49fbc01384b40 100644 --- a/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs +++ b/frontend/rust-lib/event-integration-test/tests/folder/local_test/script.rs @@ -253,6 +253,7 @@ pub async fn create_view( index: None, section: None, view_id: None, + extra: None, }; EventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 79654602e8c8b..3a919e8ec44b6 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -261,6 +261,11 @@ pub struct CreateViewPayloadPB { #[pb(index = 11, one_of)] pub view_id: Option, + + // The extra data of the view. + // Refer to the extra field in the collab + #[pb(index = 12, one_of)] + pub extra: Option, } #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Default)] @@ -335,7 +340,7 @@ impl TryInto for CreateViewPayloadPB { index: self.index, section: self.section, icon: None, - extra: None, + extra: self.extra, }) } }