From 59f9137130057caf0146df706e428fa6412075a3 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Fri, 21 Jun 2024 11:22:58 +0800 Subject: [PATCH 1/9] chore: merge release/0.6.1 --- frontend/Makefile.toml | 2 +- .../presentation/home/space/mobile_space.dart | 21 ++++ .../mobile_bottom_navigation_bar.dart | 49 +------- .../appflowy_mobile_toolbar.dart | 54 ++++---- .../application/sidebar/space/space_bloc.dart | 117 ++++++++++++------ .../application/view/view_service.dart | 5 + .../workspace/workspace_service.dart | 5 + .../packages/flowy_infra/lib/uuid.dart | 16 ++- frontend/appflowy_flutter/pubspec.lock | 4 +- frontend/appflowy_flutter/pubspec.yaml | 4 +- .../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 | 6 +- .../appimage/AppImageBuilder.yml | 2 - 18 files changed, 167 insertions(+), 127 deletions(-) diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index dbc74be7e4e4..6e433b75130b 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -APPFLOWY_VERSION = "0.6.0" +APPFLOWY_VERSION = "0.6.1" FLUTTER_DESKTOP_FEATURES = "dart" PRODUCT_NAME = "AppFlowy" MACOSX_DEPLOYMENT_TARGET = "11.0" diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/space/mobile_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/space/mobile_space.dart index 9d288c3411d3..69f5d8951ac3 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/space/mobile_space.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/space/mobile_space.dart @@ -4,6 +4,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/home/space/mobile_space_header.dart'; import 'package:appflowy/mobile/presentation/home/space/mobile_space_menu.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; +import 'package:appflowy/mobile/presentation/presentation.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; @@ -22,6 +23,18 @@ class MobileSpace extends StatefulWidget { } class _MobileSpaceState extends State { + @override + void initState() { + super.initState(); + createNewPageNotifier.addListener(_createNewPage); + } + + @override + void dispose() { + createNewPageNotifier.removeListener(_createNewPage); + super.dispose(); + } + @override Widget build(BuildContext context) { return BlocBuilder( @@ -81,6 +94,14 @@ class _MobileSpaceState extends State { }, ); } + + void _createNewPage() { + context.read().add( + SpaceEvent.createPage( + name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(), + ), + ); + } } class _Pages extends StatelessWidget { diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart index d50369e5f962..5d33dfa50055 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/mobile_bottom_navigation_bar.dart @@ -1,18 +1,15 @@ import 'dart:ui'; import 'package:appflowy/generated/flowy_svgs.g.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'; import 'package:appflowy/util/theme_extension.dart'; -import 'package:appflowy/workspace/application/workspace/workspace_service.dart'; -import 'package:appflowy_backend/dispatch/dispatch.dart'; -import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +final PropertyValueNotifier createNewPageNotifier = + PropertyValueNotifier(null); + const _homeLabel = 'home'; const _addLabel = 'add'; const _notificationLabel = 'notification'; @@ -93,7 +90,7 @@ class MobileBottomNavigationBar extends StatelessWidget { void _onTap(BuildContext context, int bottomBarIndex) { if (_items[bottomBarIndex].label == _addLabel) { // show an add dialog - _showCreatePageBottomSheet(context); + createNewPageNotifier.value = ViewLayoutPB.Document; return; } // When navigating to a new branch, it's recommended to use the goBranch @@ -108,40 +105,4 @@ class MobileBottomNavigationBar extends StatelessWidget { initialLocation: bottomBarIndex == navigationShell.currentIndex, ); } - - void _showCreatePageBottomSheet(BuildContext context) { - showMobileBottomSheet( - context, - showHeader: true, - title: LocaleKeys.sideBar_addAPage.tr(), - showDragHandle: true, - showCloseButton: true, - useRootNavigator: true, - builder: (sheetContext) { - return AddNewPageWidgetBottomSheet( - view: ViewPB(), - onAction: (layout) async { - Navigator.of(sheetContext).pop(); - final currentWorkspaceId = - await FolderEventReadCurrentWorkspace().send(); - await currentWorkspaceId.fold((s) async { - final workspaceService = WorkspaceService(workspaceId: s.id); - final result = await workspaceService.createView( - name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(), - viewSection: ViewSectionPB.Private, - layout: layout, - ); - result.fold((s) { - context.pushView(s); - }, (e) { - Log.error('Failed to create new page: $e'); - }); - }, (e) { - Log.error('Failed to read current workspace: $e'); - }); - }, - ); - }, - ); - } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart index f6a18ff45e41..95cd85566796 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar.dart @@ -73,8 +73,7 @@ class _AppFlowyMobileToolbarState extends State { ValueListenableBuilder( valueListenable: isKeyboardShow, builder: (context, isKeyboardShow, __) { - return AnimatedContainer( - duration: const Duration(milliseconds: 110), + return SizedBox( // only adding padding when the keyboard is triggered by editor height: isKeyboardShow && widget.editorState.selection != null ? widget.toolbarHeight @@ -383,37 +382,26 @@ class _MobileToolbarState extends State<_MobileToolbar> return ValueListenableBuilder( valueListenable: cachedKeyboardHeight, builder: (_, height, ___) { - var paddingHeight = height; - if (Platform.isAndroid) { - // use the viewInsets to get the keyboard height on Android - paddingHeight = MediaQuery.of(context).viewInsets.bottom; - // if the padding height is 0 and the keyboard height is not 0, - // use the keyboard height - if (paddingHeight == 0 && height != 0) { - paddingHeight = height + MediaQuery.of(context).viewPadding.bottom; - } - } - debugPrint('Keyboard height: $paddingHeight'); - return AnimatedContainer( - duration: const Duration(microseconds: 110), - height: paddingHeight, - child: ValueListenableBuilder( - valueListenable: showMenuNotifier, - builder: (_, showingMenu, __) { - return AnimatedContainer( - duration: const Duration(microseconds: 110), - height: height, - child: (showingMenu && selectedMenuIndex != null) - ? widget.toolbarItems[selectedMenuIndex!].menuBuilder?.call( - context, - widget.editorState, - this, - ) ?? - const SizedBox.shrink() - : const SizedBox.shrink(), - ); - }, - ), + return ValueListenableBuilder( + valueListenable: showMenuNotifier, + builder: (_, showingMenu, __) { + var paddingHeight = height; + if (Platform.isAndroid) { + paddingHeight = + height + MediaQuery.of(context).viewPadding.bottom; + } + return SizedBox( + height: paddingHeight, + child: (showingMenu && selectedMenuIndex != null) + ? widget.toolbarItems[selectedMenuIndex!].menuBuilder?.call( + context, + widget.editorState, + this, + ) ?? + const SizedBox.shrink() + : const SizedBox.shrink(), + ); + }, ); }, ); 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 3a390ac3e065..63872ff12fae 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 @@ -19,6 +19,7 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:appflowy_result/appflowy_result.dart'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/uuid.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:protobuf/protobuf.dart'; @@ -257,6 +258,10 @@ class SpaceBloc extends Bloc { ); }, reset: (userProfile, workspaceId) async { + if (workspaceId == _workspaceId) { + return; + } + _reset(userProfile, workspaceId); add( @@ -321,6 +326,7 @@ class SpaceBloc extends Bloc { required String icon, required String iconColor, required SpacePermission permission, + String? viewId, }) async { final section = switch (permission) { SpacePermission.publicToAll => ViewSectionPB.Public, @@ -331,6 +337,7 @@ class SpaceBloc extends Bloc { name: name, viewSection: section, setAsCurrent: false, + viewId: viewId, ); return await result.fold((space) async { Log.info('Space created: $space'); @@ -476,56 +483,82 @@ class SpaceBloc extends Bloc { if (members.items.length == 1 || isOwner) { // create a new public space and a new private space // move all the views in the workspace to the new public/private space - final publicViews = - await _workspaceService.getPublicViews().getOrThrow(); + var publicViews = await _workspaceService.getPublicViews().getOrThrow(); + final containsPublicSpace = publicViews.any( + (e) => e.isSpace && e.spacePermission == SpacePermission.publicToAll, + ); + publicViews = publicViews.where((e) => !e.isSpace).toList(); + // if there is already a public space, don't migrate the public space // only migrate the public space if there are any public views - if (publicViews.isNotEmpty) { - final publicSpace = await _createSpace( - name: 'Shared', - icon: builtInSpaceIcons.first, - iconColor: builtInSpaceColors.first, - permission: SpacePermission.publicToAll, - ); - - if (publicSpace != null) { - for (final view in publicViews.reversed) { - if (view.isSpace) { - continue; - } - await ViewBackendService.moveViewV2( - viewId: view.id, - newParentId: publicSpace.id, - prevViewId: view.parentViewId, - ); - } - } + if (publicViews.isEmpty || containsPublicSpace) { + return true; } - } - // create a new private space - final privateViews = - await _workspaceService.getPrivateViews().getOrThrow(); - // only migrate the private space if there are any private views - if (privateViews.isNotEmpty) { - final privateSpace = await _createSpace( - name: 'Private', - icon: builtInSpaceIcons.last, - iconColor: builtInSpaceColors.last, - permission: SpacePermission.private, + + final viewId = fixedUuid(user.id.toInt(), UuidType.publicSpace); + final publicSpace = await _createSpace( + name: 'Shared', + icon: builtInSpaceIcons.first, + iconColor: builtInSpaceColors.first, + permission: SpacePermission.publicToAll, + viewId: viewId, ); - if (privateSpace != null) { - for (final view in privateViews.reversed) { + + Log.info('migrating: created a new public space: ${publicSpace?.id}'); + + if (publicSpace != null) { + for (final view in publicViews.reversed) { if (view.isSpace) { continue; } await ViewBackendService.moveViewV2( viewId: view.id, - newParentId: privateSpace.id, - prevViewId: view.parentViewId, + newParentId: publicSpace.id, + prevViewId: null, + ); + Log.info( + 'migrating: migrate ${view.name}(${view.id}) to public space(${publicSpace.id})', ); } } } + // create a new private space + final viewId = fixedUuid(user.id.toInt(), UuidType.privateSpace); + var privateViews = await _workspaceService.getPrivateViews().getOrThrow(); + // if there is already a private space, don't migrate the private space + final containsPrivateSpace = privateViews.any( + (e) => e.isSpace && e.spacePermission == SpacePermission.private, + ); + privateViews = privateViews.where((e) => !e.isSpace).toList(); + if (privateViews.isEmpty || containsPrivateSpace) { + return true; + } + // only migrate the private space if there are any private views + final privateSpace = await _createSpace( + name: 'Private', + icon: builtInSpaceIcons.last, + iconColor: builtInSpaceColors.last, + permission: SpacePermission.private, + viewId: viewId, + ); + Log.info('migrating: created a new private space: ${privateSpace?.id}'); + + if (privateSpace != null) { + for (final view in privateViews.reversed) { + if (view.isSpace) { + continue; + } + await ViewBackendService.moveViewV2( + viewId: view.id, + newParentId: privateSpace.id, + prevViewId: null, + ); + Log.info( + 'migrating: migrate ${view.name}(${view.id}) to private space(${privateSpace.id})', + ); + } + } + return true; } catch (e) { Log.error('migrate space error: $e'); @@ -538,14 +571,16 @@ class SpaceBloc extends Bloc { required List publicViews, required List privateViews, }) async { - final publicSpaces = - spaces.where((e) => e.spacePermission == SpacePermission.publicToAll); + final publicSpaces = spaces.where( + (e) => e.spacePermission == SpacePermission.publicToAll, + ); if (publicSpaces.isEmpty && publicViews.isNotEmpty) { return true; } - final privateSpaces = - spaces.where((e) => e.spacePermission == SpacePermission.private); + final privateSpaces = spaces.where( + (e) => e.spacePermission == SpacePermission.private, + ); if (privateSpaces.isEmpty && privateViews.isNotEmpty) { return true; } diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index b85467d41f8b..d123e72c4fac 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -38,6 +38,7 @@ class ViewBackendService { /// If the index is null, the view will be added to the end of the list. int? index, ViewSectionPB? section, + final String? viewId, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = parentViewId @@ -63,6 +64,10 @@ class ViewBackendService { payload.section = section; } + if (viewId != null) { + payload.viewId = viewId; + } + return FolderEventCreateView(payload).send(); } 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 9931a1e4560b..8da9ad485483 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart @@ -18,6 +18,7 @@ class WorkspaceService { int? index, ViewLayoutPB? layout, bool? setAsCurrent, + String? viewId, }) { final payload = CreateViewPayloadPB.create() ..parentViewId = workspaceId @@ -37,6 +38,10 @@ class WorkspaceService { payload.setAsCurrent = setAsCurrent; } + if (viewId != null) { + payload.viewId = viewId; + } + return FolderEventCreateView(payload).send(); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/uuid.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/uuid.dart index df8aee9ddaa8..1f4c9036256c 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/uuid.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/uuid.dart @@ -1,5 +1,19 @@ +import 'package:uuid/data.dart'; +import 'package:uuid/rng.dart'; import 'package:uuid/uuid.dart'; +const _uuid = Uuid(); + String uuid() { - return const Uuid().v4(); + return _uuid.v4(); +} + +String fixedUuid(int seed, UuidType type) { + return _uuid.v4(config: V4Options(null, MathRNG(seed: seed + type.index))); +} + +enum UuidType { + // 0.6.0 + publicSpace, + privateSpace, } diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index a16b2e416380..e066d6e0dd02 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -2174,10 +2174,10 @@ packages: dependency: "direct overridden" description: name: uuid - sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 + sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" url: "https://pub.dev" source: hosted - version: "4.3.3" + version: "4.4.0" value_layout_builder: dependency: transitive description: diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 67241c3ec0f9..dffab82055ca 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.6.0 +version: 0.6.1 environment: flutter: ">=3.22.0" @@ -199,7 +199,7 @@ dependency_overrides: ref: e44458d path: sheet - uuid: ^4.1.0 + uuid: ^4.4.0 flutter_cache_manager: git: 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 60e8ba65b1a3..bb0090fe359a 100644 --- a/frontend/rust-lib/event-integration-test/src/chat_event.rs +++ b/frontend/rust-lib/event-integration-test/src/chat_event.rs @@ -21,6 +21,7 @@ impl EventIntegrationTest { set_as_current: true, index: None, section: None, + view_id: 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 79b8b528d297..4b6968ec0666 100644 --- a/frontend/rust-lib/event-integration-test/src/database_event.rs +++ b/frontend/rust-lib/event-integration-test/src/database_event.rs @@ -45,6 +45,7 @@ impl EventIntegrationTest { set_as_current: true, index: None, section: None, + view_id: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -76,6 +77,7 @@ impl EventIntegrationTest { set_as_current: true, index: None, section: None, + view_id: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -102,6 +104,7 @@ impl EventIntegrationTest { set_as_current: true, index: None, section: None, + view_id: 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 93d3ccc80faf..8595ac056b37 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 @@ -65,6 +65,7 @@ impl DocumentEventTest { set_as_current: true, index: None, section: None, + view_id: 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 6f99998e5048..8374bc9de3eb 100644 --- a/frontend/rust-lib/event-integration-test/src/document_event.rs +++ b/frontend/rust-lib/event-integration-test/src/document_event.rs @@ -42,6 +42,7 @@ impl EventIntegrationTest { set_as_current: true, index: None, section: None, + view_id: 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 af4de3f5d082..47c2bfa45c9c 100644 --- a/frontend/rust-lib/event-integration-test/src/folder_event.rs +++ b/frontend/rust-lib/event-integration-test/src/folder_event.rs @@ -230,6 +230,7 @@ impl EventIntegrationTest { set_as_current: false, index: None, section: None, + view_id: None, }; EventBuilder::new(self.clone()) .event(FolderEvent::CreateView) @@ -293,6 +294,7 @@ impl ViewTest { set_as_current: true, index: None, section: None, + view_id: 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 7be83964e3ac..0ebbd64efa9b 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 @@ -252,6 +252,7 @@ pub async fn create_view( set_as_current: true, index: None, section: None, + view_id: 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 d5945ccaa329..d0568995f681 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -258,6 +258,9 @@ pub struct CreateViewPayloadPB { // The view in private section will only be shown in the user's private view list. #[pb(index = 10, one_of)] pub section: Option, + + #[pb(index = 11, one_of)] + pub view_id: Option, } #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Default)] @@ -313,7 +316,8 @@ impl TryInto for CreateViewPayloadPB { fn try_into(self) -> Result { let name = ViewName::parse(self.name)?.0; let parent_view_id = ViewIdentify::parse(self.parent_view_id)?.0; - let view_id = gen_view_id().to_string(); + // if view_id is not provided, generate a new view_id + let view_id = self.view_id.unwrap_or_else(|| gen_view_id().to_string()); Ok(CreateViewParams { parent_view_id, diff --git a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml index a0da34dec96c..cd8103df9eb1 100644 --- a/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml +++ b/frontend/scripts/linux_distribution/appimage/AppImageBuilder.yml @@ -59,8 +59,6 @@ AppDir: - libwayland-cursor0:amd64 - libwayland-client0:amd64 - libwayland-egl1:amd64 - - libmpv-dev:amd64 - - mpv:amd64 files: include: [] exclude: From e7ba0b211ca7b1ef8df9d6e4031bb65e4b171efd Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 11:37:01 +0800 Subject: [PATCH 2/9] feat: support duplicating view with icon and cover --- .../sidebar/space/sidebar_space_header.dart | 1 + .../menu/sidebar/space/space_action_type.dart | 6 ++ .../menu/sidebar/space/space_more_popup.dart | 1 + frontend/resources/translations/en.json | 3 +- .../flowy-folder/src/entities/view.rs | 14 ++++- frontend/rust-lib/flowy-folder/src/manager.rs | 55 +++++++++++++++++++ .../rust-lib/flowy-folder/src/test_helper.rs | 3 + .../flowy-folder/src/view_operation.rs | 6 +- 8 files changed, 84 insertions(+), 5 deletions(-) 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 6c277736cc51..def556513d1f 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 @@ -211,6 +211,7 @@ class _SidebarSpaceHeaderState extends State { case SpaceMoreActionType.delete: _showDeleteSpaceDialog(context); break; + case SpaceMoreActionType.duplicate: case SpaceMoreActionType.divider: break; } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_action_type.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_action_type.dart index 83472b7a8057..5edf2d82b626 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_action_type.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_action_type.dart @@ -11,6 +11,7 @@ enum SpaceMoreActionType { divider, addNewSpace, manage, + duplicate, } extension ViewMoreActionTypeExtension on SpaceMoreActionType { @@ -28,6 +29,8 @@ extension ViewMoreActionTypeExtension on SpaceMoreActionType { return LocaleKeys.space_addNewSpace.tr(); case SpaceMoreActionType.manage: return LocaleKeys.space_manage.tr(); + case SpaceMoreActionType.duplicate: + return LocaleKeys.space_duplicate.tr(); case SpaceMoreActionType.divider: return ''; } @@ -47,6 +50,8 @@ extension ViewMoreActionTypeExtension on SpaceMoreActionType { return const FlowySvg(FlowySvgs.space_add_s); case SpaceMoreActionType.manage: return const FlowySvg(FlowySvgs.space_manage_s); + case SpaceMoreActionType.duplicate: + return const FlowySvg(FlowySvgs.duplicate_s); case SpaceMoreActionType.divider: return const SizedBox.shrink(); } @@ -61,6 +66,7 @@ extension ViewMoreActionTypeExtension on SpaceMoreActionType { case SpaceMoreActionType.delete: case SpaceMoreActionType.addNewSpace: case SpaceMoreActionType.manage: + case SpaceMoreActionType.duplicate: return const SizedBox.shrink(); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart index 00b0bc3307eb..3ee4f215db95 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart @@ -69,6 +69,7 @@ class SpaceMorePopup extends StatelessWidget { SpaceMoreActionType.rename, SpaceMoreActionType.changeIcon, SpaceMoreActionType.manage, + SpaceMoreActionType.duplicate, SpaceMoreActionType.divider, SpaceMoreActionType.addNewSpace, SpaceMoreActionType.collapseAllPages, diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 985e17eee8d0..cbd376206901 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -2011,6 +2011,7 @@ "upgradeSpaceDescription": "Create multiple public and private Spaces to better organize your workspace.", "upgrade": "Update", "upgradeYourSpace": "Create multiple Spaces", - "quicklySwitch": "Quickly switch to the next space" + "quicklySwitch": "Quickly switch to the next space", + "duplicate": "Duplicate Space" } } \ No newline at end of file diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index d0568995f681..49bc3c41aa5a 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use std::ops::{Deref, DerefMut}; use std::sync::Arc; -use collab_folder::{View, ViewLayout}; +use collab_folder::{RepeatedViewIdentifier, View, ViewIcon, ViewLayout}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; @@ -308,6 +308,12 @@ pub struct CreateViewParams { pub index: Option, // The section of the view. pub section: Option, + // The icon of the view. + pub icon: Option, + // The child views of the view. + pub children: RepeatedViewIdentifier, + // The extra data of the view. + pub extra: Option, } impl TryInto for CreateViewPayloadPB { @@ -330,6 +336,9 @@ impl TryInto for CreateViewPayloadPB { set_as_current: self.set_as_current, index: self.index, section: self.section, + icon: None, + children: Default::default(), + extra: None, }) } } @@ -352,6 +361,9 @@ impl TryInto for CreateOrphanViewPayloadPB { set_as_current: false, index: None, section: None, + icon: None, + children: Default::default(), + extra: None, }) } } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index fc3994056977..3304e22071c4 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -779,6 +779,58 @@ impl FolderManager { set_as_current: true, index, section: Some(section), + extra: view.extra.clone(), + icon: view.icon.clone(), + children: Default::default(), + }; + + self.create_view_with_params(duplicate_params).await?; + Ok(()) + } + + async fn duplicate_view_with_parent_id( + &self, + view_id: &str, + parent_view_id: &str, + ) -> Result<(), FlowyError> { + let view = self + .with_folder(|| None, |folder| folder.views.get_view(view_id)) + .ok_or_else(|| FlowyError::record_not_found().with_context("Can't duplicate the view"))?; + + let handler = self.get_handler(&view.layout)?; + let view_data = handler.duplicate_view(&view.id).await?; + + // get the current view index in the parent view, because we need to insert the duplicated view below the current view. + let index = if let Some((_, __, views)) = self.get_view_relation(&view.parent_view_id).await { + views.iter().position(|id| id == view_id).map(|i| i as u32) + } else { + None + }; + + let is_private = self.with_folder( + || false, + |folder| folder.is_view_in_section(Section::Private, &view.id), + ); + let section = if is_private { + ViewSectionPB::Private + } else { + ViewSectionPB::Public + }; + + let duplicate_params = CreateViewParams { + parent_view_id: view.parent_view_id.clone(), + name: format!("{} (copy)", &view.name), + desc: view.desc.clone(), + layout: view.layout.clone().into(), + initial_data: view_data.to_vec(), + view_id: gen_view_id().to_string(), + meta: Default::default(), + set_as_current: false, + index, + section: Some(section), + extra: view.extra.clone(), + icon: view.icon.clone(), + children: Default::default(), }; self.create_view_with_params(duplicate_params).await?; @@ -1004,6 +1056,9 @@ impl FolderManager { set_as_current: false, index: None, section: None, + extra: None, + icon: None, + children: Default::default(), }; let view = create_view(self.user.user_id()?, params, import_data.view_layout); diff --git a/frontend/rust-lib/flowy-folder/src/test_helper.rs b/frontend/rust-lib/flowy-folder/src/test_helper.rs index 50e4b290ff43..46a6e7b0d173 100644 --- a/frontend/rust-lib/flowy-folder/src/test_helper.rs +++ b/frontend/rust-lib/flowy-folder/src/test_helper.rs @@ -48,6 +48,9 @@ impl FolderManager { set_as_current: true, index: None, section: Some(ViewSectionPB::Public), + icon: None, + children: Default::default(), + extra: None, }; self.create_view_with_params(params).await.unwrap(); view_id diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index 10d173394c0a..5261289e8fcd 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -127,14 +127,14 @@ pub(crate) fn create_view(uid: i64, params: CreateViewParams, layout: ViewLayout parent_view_id: params.parent_view_id, name: params.name, desc: params.desc, - children: Default::default(), + children: params.children, created_at: time, is_favorite: false, layout, - icon: None, + icon: params.icon, created_by: Some(uid), last_edited_time: 0, last_edited_by: Some(uid), - extra: None, + extra: params.extra, } } From 4b1b26a0cc30d1e79e0677c48879711eba531fc5 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 14:34:48 +0800 Subject: [PATCH 3/9] feat: support duplicating with children --- .../workspace/application/view/view_bloc.dart | 6 +- .../application/view/view_service.dart | 9 +- .../src/folder_event.rs | 2 + .../flowy-folder/src/entities/view.rs | 38 +++- .../flowy-folder/src/event_handler.rs | 6 +- .../rust-lib/flowy-folder/src/event_map.rs | 2 +- frontend/rust-lib/flowy-folder/src/manager.rs | 176 ++++++++++-------- .../rust-lib/flowy-folder/src/test_helper.rs | 1 - .../flowy-folder/src/view_operation.rs | 2 +- 9 files changed, 148 insertions(+), 94 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart index bf243f8a1c7b..26004225110b 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_bloc.dart @@ -154,7 +154,11 @@ class ViewBloc extends Bloc { ); }, duplicate: (e) async { - final result = await ViewBackendService.duplicate(view: view); + final result = await ViewBackendService.duplicate( + view: view, + openAfterDuplicate: true, + includeChildren: true, + ); emit( result.fold( (l) => diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart index d123e72c4fac..2e27ba364d44 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_service.dart @@ -138,8 +138,15 @@ class ViewBackendService { static Future> duplicate({ required ViewPB view, + required bool openAfterDuplicate, + // should include children views + required bool includeChildren, }) { - return FolderEventDuplicateView(view).send(); + final payload = DuplicateViewPayloadPB.create() + ..viewId = view.id + ..openAfterDuplicate = openAfterDuplicate + ..includeChildren = includeChildren; + return FolderEventDuplicateView(payload).send(); } static Future> favorite({ 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 47c2bfa45c9c..c299d5ab608f 100644 --- a/frontend/rust-lib/event-integration-test/src/folder_event.rs +++ b/frontend/rust-lib/event-integration-test/src/folder_event.rs @@ -126,6 +126,8 @@ impl EventIntegrationTest { set_as_current: false, index: None, section: None, + icon: view.icon, + extra: view.extra, }) .collect::>(); diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 49bc3c41aa5a..cff0a92b2fc8 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -310,8 +310,6 @@ pub struct CreateViewParams { pub section: Option, // The icon of the view. pub icon: Option, - // The child views of the view. - pub children: RepeatedViewIdentifier, // The extra data of the view. pub extra: Option, } @@ -337,7 +335,6 @@ impl TryInto for CreateViewPayloadPB { index: self.index, section: self.section, icon: None, - children: Default::default(), extra: None, }) } @@ -362,7 +359,6 @@ impl TryInto for CreateOrphanViewPayloadPB { index: None, section: None, icon: None, - children: Default::default(), extra: None, }) } @@ -578,6 +574,40 @@ pub struct UpdateViewVisibilityStatusPayloadPB { pub is_public: bool, } +#[derive(Default, ProtoBuf)] +pub struct DuplicateViewPayloadPB { + #[pb(index = 1)] + pub view_id: String, + + #[pb(index = 2)] + pub open_after_duplicate: bool, + + #[pb(index = 3)] + pub include_children: bool, +} + +#[derive(Debug)] +pub struct DuplicateViewParams { + pub view_id: String, + + pub open_after_duplicate: bool, + + pub include_children: bool, +} + +impl TryInto for DuplicateViewPayloadPB { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let view_id = ViewIdentify::parse(self.view_id)?.0; + Ok(DuplicateViewParams { + view_id, + open_after_duplicate: self.open_after_duplicate, + include_children: self.include_children, + }) + } +} + // impl<'de> Deserialize<'de> for ViewDataType { // fn deserialize(deserializer: D) -> Result>::Error> // where diff --git a/frontend/rust-lib/flowy-folder/src/event_handler.rs b/frontend/rust-lib/flowy-folder/src/event_handler.rs index 888c26d2a6d5..03b71fd2a91c 100644 --- a/frontend/rust-lib/flowy-folder/src/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/event_handler.rs @@ -266,12 +266,12 @@ pub(crate) async fn move_nested_view_handler( #[tracing::instrument(level = "debug", skip(data, folder), err)] pub(crate) async fn duplicate_view_handler( - data: AFPluginData, + data: AFPluginData, folder: AFPluginState>, ) -> Result<(), FlowyError> { let folder = upgrade_folder(folder)?; - let view: ViewPB = data.into_inner(); - folder.duplicate_view(&view.id).await?; + let params: DuplicateViewParams = data.into_inner().try_into()?; + folder.duplicate_view(params).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index febfc49b5ef1..aa8bf551a4c8 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -85,7 +85,7 @@ pub enum FolderEvent { DeleteView = 13, /// Duplicate the view - #[event(input = "ViewPB")] + #[event(input = "DuplicateViewPayloadPB")] DuplicateView = 14, /// Close and release the resources that are used by this view. diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 3304e22071c4..fa9c5c6425b5 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -1,9 +1,9 @@ use crate::entities::icon::UpdateViewIconParams; use crate::entities::{ view_pb_with_child_views, view_pb_without_child_views, view_pb_without_child_views_from_arc, - CreateViewParams, CreateWorkspaceParams, DeletedViewPB, FolderSnapshotPB, MoveNestedViewParams, - RepeatedTrashPB, RepeatedViewIdPB, RepeatedViewPB, UpdateViewParams, ViewPB, ViewSectionPB, - WorkspacePB, WorkspaceSettingPB, + CreateViewParams, CreateWorkspaceParams, DeletedViewPB, DuplicateViewParams, FolderSnapshotPB, + MoveNestedViewParams, RepeatedTrashPB, RepeatedViewIdPB, RepeatedViewPB, UpdateViewParams, + ViewPB, ViewSectionPB, WorkspacePB, WorkspaceSettingPB, }; use crate::manager_observer::{ notify_child_views_changed, notify_did_update_workspace, notify_parent_view_did_change, @@ -742,98 +742,111 @@ impl FolderManager { } /// Duplicate the view with the given view id. + /// + /// Including the view data (icon, cover, extra) and the child views. #[tracing::instrument(level = "debug", skip(self), err)] - pub(crate) async fn duplicate_view(&self, view_id: &str) -> Result<(), FlowyError> { + pub(crate) async fn duplicate_view(&self, params: DuplicateViewParams) -> Result<(), FlowyError> { let view = self - .with_folder(|| None, |folder| folder.views.get_view(view_id)) + .with_folder(|| None, |folder| folder.views.get_view(¶ms.view_id)) .ok_or_else(|| FlowyError::record_not_found().with_context("Can't duplicate the view"))?; - - let handler = self.get_handler(&view.layout)?; - let view_data = handler.duplicate_view(&view.id).await?; - - // get the current view index in the parent view, because we need to insert the duplicated view below the current view. - let index = if let Some((_, __, views)) = self.get_view_relation(&view.parent_view_id).await { - views.iter().position(|id| id == view_id).map(|i| i as u32) - } else { - None - }; - - let is_private = self.with_folder( - || false, - |folder| folder.is_view_in_section(Section::Private, &view.id), - ); - let section = if is_private { - ViewSectionPB::Private - } else { - ViewSectionPB::Public - }; - - let duplicate_params = CreateViewParams { - parent_view_id: view.parent_view_id.clone(), - name: format!("{} (copy)", &view.name), - desc: view.desc.clone(), - layout: view.layout.clone().into(), - initial_data: view_data.to_vec(), - view_id: gen_view_id().to_string(), - meta: Default::default(), - set_as_current: true, - index, - section: Some(section), - extra: view.extra.clone(), - icon: view.icon.clone(), - children: Default::default(), - }; - - self.create_view_with_params(duplicate_params).await?; - Ok(()) + self + .duplicate_view_with_parent_id( + &view.id, + &view.parent_view_id, + params.open_after_duplicate, + params.include_children, + ) + .await } - async fn duplicate_view_with_parent_id( + /// Duplicate the view with the given view id and parent view id. + /// + /// If the view id is the same as the parent view id, it will return an error. + /// If the view id is not found, it will return an error. + pub(crate) async fn duplicate_view_with_parent_id( &self, view_id: &str, parent_view_id: &str, + open_after_duplicated: bool, + include_children: bool, ) -> Result<(), FlowyError> { - let view = self - .with_folder(|| None, |folder| folder.views.get_view(view_id)) - .ok_or_else(|| FlowyError::record_not_found().with_context("Can't duplicate the view"))?; + if view_id == parent_view_id { + return Err(FlowyError::new( + ErrorCode::Internal, + format!("Can't duplicate the view({}) to itself", view_id), + )); + } - let handler = self.get_handler(&view.layout)?; - let view_data = handler.duplicate_view(&view.id).await?; + // only apply the `open_after_duplicated` and the `include_children` to the first view + let mut is_source_view = true; + // use a stack to duplicate the view and its children + let mut stack = vec![(view_id.to_string(), parent_view_id.to_string())]; - // get the current view index in the parent view, because we need to insert the duplicated view below the current view. - let index = if let Some((_, __, views)) = self.get_view_relation(&view.parent_view_id).await { - views.iter().position(|id| id == view_id).map(|i| i as u32) - } else { - None - }; + while let Some((current_view_id, current_parent_id)) = stack.pop() { + let view = self + .with_folder(|| None, |folder| folder.views.get_view(¤t_view_id)) + .ok_or_else(|| { + FlowyError::record_not_found() + .with_context(format!("Can't duplicate the view({})", view_id)) + })?; - let is_private = self.with_folder( - || false, - |folder| folder.is_view_in_section(Section::Private, &view.id), - ); - let section = if is_private { - ViewSectionPB::Private - } else { - ViewSectionPB::Public - }; + let handler = self.get_handler(&view.layout)?; + let view_data = handler.duplicate_view(&view.id).await?; - let duplicate_params = CreateViewParams { - parent_view_id: view.parent_view_id.clone(), - name: format!("{} (copy)", &view.name), - desc: view.desc.clone(), - layout: view.layout.clone().into(), - initial_data: view_data.to_vec(), - view_id: gen_view_id().to_string(), - meta: Default::default(), - set_as_current: false, - index, - section: Some(section), - extra: view.extra.clone(), - icon: view.icon.clone(), - children: Default::default(), - }; + let index = self + .get_view_relation(¤t_parent_id) + .await + .and_then(|(_, _, views)| { + views + .iter() + .position(|id| id == ¤t_view_id) + .map(|i| i as u32) + }); + + let section = self.with_folder( + || ViewSectionPB::Private, + |folder| { + if folder.is_view_in_section(Section::Private, &view.id) { + ViewSectionPB::Private + } else { + ViewSectionPB::Public + } + }, + ); + + let name = if is_source_view { + format!("{} (copy)", &view.name) + } else { + view.name.clone() + }; + let duplicate_params = CreateViewParams { + parent_view_id: current_parent_id.clone(), + name, + desc: view.desc.clone(), + layout: view.layout.clone().into(), + initial_data: view_data.to_vec(), + view_id: gen_view_id().to_string(), + meta: Default::default(), + set_as_current: is_source_view && open_after_duplicated, + index, + section: Some(section), + extra: view.extra.clone(), + icon: view.icon.clone(), + }; + + let duplicated_view = self.create_view_with_params(duplicate_params).await?; + + if is_source_view && include_children { + let child_views = self.get_views_belong_to(¤t_view_id).await?; + // reverse the child views to keep the order + for child_view in child_views.iter().rev() { + stack.push((child_view.id.clone(), duplicated_view.id.clone())); + } + } + + is_source_view = false + } - self.create_view_with_params(duplicate_params).await?; Ok(()) } @@ -1058,7 +1071,6 @@ impl FolderManager { section: None, extra: None, icon: None, - children: Default::default(), }; let view = create_view(self.user.user_id()?, params, import_data.view_layout); diff --git a/frontend/rust-lib/flowy-folder/src/test_helper.rs b/frontend/rust-lib/flowy-folder/src/test_helper.rs index 46a6e7b0d173..f7029568286e 100644 --- a/frontend/rust-lib/flowy-folder/src/test_helper.rs +++ b/frontend/rust-lib/flowy-folder/src/test_helper.rs @@ -49,7 +49,6 @@ impl FolderManager { index: None, section: Some(ViewSectionPB::Public), icon: None, - children: Default::default(), extra: None, }; self.create_view_with_params(params).await.unwrap(); diff --git a/frontend/rust-lib/flowy-folder/src/view_operation.rs b/frontend/rust-lib/flowy-folder/src/view_operation.rs index 5261289e8fcd..3132384e777b 100644 --- a/frontend/rust-lib/flowy-folder/src/view_operation.rs +++ b/frontend/rust-lib/flowy-folder/src/view_operation.rs @@ -127,7 +127,6 @@ pub(crate) fn create_view(uid: i64, params: CreateViewParams, layout: ViewLayout parent_view_id: params.parent_view_id, name: params.name, desc: params.desc, - children: params.children, created_at: time, is_favorite: false, layout, @@ -136,5 +135,6 @@ pub(crate) fn create_view(uid: i64, params: CreateViewParams, layout: ViewLayout last_edited_time: 0, last_edited_by: Some(uid), extra: params.extra, + children: Default::default(), } } From dc3ae42e55d2a4361ae7f9abf2c8f05d3ae31de4 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 14:51:39 +0800 Subject: [PATCH 4/9] feat: support duplicating all the child views --- frontend/rust-lib/flowy-folder/src/manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index fa9c5c6425b5..da627a26da94 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -836,7 +836,7 @@ impl FolderManager { let duplicated_view = self.create_view_with_params(duplicate_params).await?; - if is_source_view && include_children { + if include_children { let child_views = self.get_views_belong_to(¤t_view_id).await?; // reverse the child views to keep the order for child_view in child_views.iter().rev() { From e16925bc7cfc16ded16a44592e75980613899bc2 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 15:38:41 +0800 Subject: [PATCH 5/9] fix: cargo clippy --- frontend/rust-lib/flowy-folder/src/entities/view.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index cff0a92b2fc8..25c5e1c9abb3 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use std::ops::{Deref, DerefMut}; use std::sync::Arc; -use collab_folder::{RepeatedViewIdentifier, View, ViewIcon, ViewLayout}; +use collab_folder::{View, ViewIcon, ViewLayout}; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::ErrorCode; From fb102e880f30f93b38228609f5492df829eeacb9 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 16:52:59 +0800 Subject: [PATCH 6/9] feat: add duplicate space entry --- .../application/sidebar/space/space_bloc.dart | 13 +++++++++++++ .../menu/sidebar/space/sidebar_space_header.dart | 2 ++ frontend/rust-lib/flowy-folder/src/manager.rs | 13 +++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) 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 63872ff12fae..3fd4afd4877e 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 @@ -291,6 +291,18 @@ class SpaceBloc extends Bloc { final nextSpace = spaces[nextIndex]; add(SpaceEvent.open(nextSpace)); }, + duplicate: () async { + final currentSpace = state.currentSpace; + if (currentSpace == null) { + return; + } + await ViewBackendService.duplicate( + view: currentSpace, + openAfterDuplicate: false, + includeChildren: true, + ); + add(const SpaceEvent.didReceiveSpaceUpdate()); + }, ); }, ); @@ -606,6 +618,7 @@ class SpaceEvent with _$SpaceEvent { const factory SpaceEvent.rename(ViewPB space, String name) = _Rename; const factory SpaceEvent.changeIcon(String icon, String iconColor) = _ChangeIcon; + const factory SpaceEvent.duplicate() = _Duplicate; const factory SpaceEvent.update({ String? name, String? icon, 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 def556513d1f..65ad86d77cbb 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 @@ -212,6 +212,8 @@ class _SidebarSpaceHeaderState extends State { _showDeleteSpaceDialog(context); break; case SpaceMoreActionType.duplicate: + context.read().add(const SpaceEvent.duplicate()); + break; case SpaceMoreActionType.divider: break; } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index da627a26da94..b171ed02fa7e 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -777,6 +777,11 @@ impl FolderManager { )); } + let filtered_view_ids = self.with_folder( + || vec![], + |folder| self.get_view_ids_should_be_filtered(folder), + ); + // only apply the `open_after_duplicated` and the `include_children` to the first view let mut is_source_view = true; // use a stack to duplicate the view and its children @@ -799,7 +804,8 @@ impl FolderManager { .and_then(|(_, _, views)| { views .iter() - .position(|id| id == ¤t_view_id) + .filter(|id| filtered_view_ids.contains(id)) + .position(|id| id.to_string() == current_view_id) .map(|i| i as u32) }); @@ -840,7 +846,10 @@ impl FolderManager { let child_views = self.get_views_belong_to(¤t_view_id).await?; // reverse the child views to keep the order for child_view in child_views.iter().rev() { - stack.push((child_view.id.clone(), duplicated_view.id.clone())); + // skip the view_id should be filtered and the child_view is the duplicated view + if !filtered_view_ids.contains(&child_view.id) { + stack.push((child_view.id.clone(), duplicated_view.id.clone())); + } } } From b4d1ee452682a0e32805b7f34734878491ff230b Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 17:32:54 +0800 Subject: [PATCH 7/9] chore: upgrade collab repo --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 14 +++++++------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 14 +++++++------- frontend/appflowy_web/wasm-libs/Cargo.toml | 14 +++++++------- frontend/appflowy_web_app/src-tauri/Cargo.lock | 14 +++++++------- frontend/appflowy_web_app/src-tauri/Cargo.toml | 14 +++++++------- frontend/rust-lib/Cargo.lock | 14 +++++++------- frontend/rust-lib/Cargo.toml | 14 +++++++------- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index aa07be5eebcd..6ca09491cae8 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -904,7 +904,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -928,7 +928,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -958,7 +958,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", @@ -978,7 +978,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "bytes", @@ -993,7 +993,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "chrono", @@ -1031,7 +1031,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-stream", @@ -1112,7 +1112,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index bae84180da55..f8bdb1d823d9 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -106,10 +106,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 9816e6ef9484..2dc5b9a11211 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -67,10 +67,10 @@ opt-level = 3 codegen-units = 1 [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index a4a230c51476..edf953de3e63 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -887,7 +887,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -941,7 +941,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", @@ -961,7 +961,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "bytes", @@ -976,7 +976,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "chrono", @@ -1014,7 +1014,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-stream", @@ -1095,7 +1095,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index ddf01dabc564..feaf5a162612 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -107,10 +107,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index ce749cbe0ca7..145a5339be0a 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -765,7 +765,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -789,7 +789,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-trait", @@ -819,7 +819,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", @@ -839,7 +839,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "bytes", @@ -854,7 +854,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "chrono", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "async-stream", @@ -973,7 +973,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3a58d95#3a58d95a202b2814920650fa71c458fb0b49293d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5048762#5048762dbb01abcbe75237e86c0d090e2f1d7c23" dependencies = [ "anyhow", "collab", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 27342183192f..53cb8a25e3e4 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -137,10 +137,10 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3a58d95" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5048762" } From b27014d8bbe3c2295d121d3a09dc7d9990bd6c4c Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 24 Jun 2024 22:02:53 +0800 Subject: [PATCH 8/9] fix: cargo clippy --- frontend/rust-lib/flowy-folder/src/manager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index b171ed02fa7e..7b1ff3974244 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -778,7 +778,7 @@ impl FolderManager { } let filtered_view_ids = self.with_folder( - || vec![], + || Vec::new(), |folder| self.get_view_ids_should_be_filtered(folder), ); @@ -805,7 +805,7 @@ impl FolderManager { views .iter() .filter(|id| filtered_view_ids.contains(id)) - .position(|id| id.to_string() == current_view_id) + .position(|id| *id == current_view_id) .map(|i| i as u32) }); From 5f3055a6a901179cd3803e8107a08a0d7e799cb5 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 25 Jun 2024 09:34:06 +0800 Subject: [PATCH 9/9] fix: cargo clippy --- frontend/rust-lib/flowy-folder/src/manager.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index 7b1ff3974244..28d802b6dbf5 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -777,10 +777,9 @@ impl FolderManager { )); } - let filtered_view_ids = self.with_folder( - || Vec::new(), - |folder| self.get_view_ids_should_be_filtered(folder), - ); + let filtered_view_ids = self.with_folder(Vec::new, |folder| { + self.get_view_ids_should_be_filtered(folder) + }); // only apply the `open_after_duplicated` and the `include_children` to the first view let mut is_source_view = true;