diff --git a/frontend/.vscode/tasks.json b/frontend/.vscode/tasks.json index 2ed54bc78a..bb56606f1b 100644 --- a/frontend/.vscode/tasks.json +++ b/frontend/.vscode/tasks.json @@ -58,7 +58,7 @@ "label": "AF: Build Appflowy Core", "type": "shell", "windows": { - "command": "cargo make --profile development-windows appflowy-core-dev" + "command": "cargo make --profile development-windows-x86 appflowy-core-dev" }, "linux": { "command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev" diff --git a/frontend/app_flowy/lib/plugins/document/document.dart b/frontend/app_flowy/lib/plugins/document/document.dart index d50a18eed3..c33e62b5b4 100644 --- a/frontend/app_flowy/lib/plugins/document/document.dart +++ b/frontend/app_flowy/lib/plugins/document/document.dart @@ -34,7 +34,7 @@ class DocumentPluginBuilder extends PluginBuilder { PluginType get pluginType => PluginType.editor; @override - ViewDataFormatPB get dataFormatType => ViewDataFormatPB.TreeFormat; + ViewDataFormatPB get dataFormatType => ViewDataFormatPB.NodeFormat; } class DocumentPlugin extends Plugin { diff --git a/frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart b/frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart index f0a41aebcd..055615e817 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/cell/select_option_editor_bloc.dart @@ -147,8 +147,10 @@ class SelectOptionCellEditorBloc } void _filterOption(String optionName, Emitter emit) { - final _MakeOptionResult result = - _makeOptions(Some(optionName), state.allOptions); + final _MakeOptionResult result = _makeOptions( + Some(optionName), + state.allOptions, + ); emit(state.copyWith( filter: Some(optionName), options: result.options, @@ -159,6 +161,7 @@ class SelectOptionCellEditorBloc Future _loadOptions() async { final result = await _selectOptionService.getOptionContext(); if (isClosed) { + Log.warn("Unexpected closing the bloc"); return; } @@ -177,7 +180,9 @@ class SelectOptionCellEditorBloc } _MakeOptionResult _makeOptions( - Option filter, List allOptions) { + Option filter, + List allOptions, + ) { final List options = List.from(allOptions); Option createOption = filter; diff --git a/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart b/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart index c126cd006e..95e7261348 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/field/type_option/type_option_data_controller.dart @@ -12,7 +12,7 @@ import 'type_option_context.dart'; class TypeOptionDataController { final String databaseId; final IFieldTypeOptionLoader loader; - late TypeOptionPB _data; + late TypeOptionPB _typeOptiondata; final PublishNotifier _fieldNotifier = PublishNotifier(); /// Returns a [TypeOptionDataController] used to modify the specified @@ -27,7 +27,7 @@ class TypeOptionDataController { FieldInfo? fieldInfo, }) { if (fieldInfo != null) { - _data = TypeOptionPB.create() + _typeOptiondata = TypeOptionPB.create() ..databaseId = databaseId ..field_2 = fieldInfo.field; } @@ -38,7 +38,7 @@ class TypeOptionDataController { return result.fold( (data) { data.freeze(); - _data = data; + _typeOptiondata = data; _fieldNotifier.value = data.field_2; return left(data); }, @@ -50,28 +50,28 @@ class TypeOptionDataController { } FieldPB get field { - return _data.field_2; + return _typeOptiondata.field_2; } T getTypeOption(TypeOptionDataParser parser) { - return parser.fromBuffer(_data.typeOptionData); + return parser.fromBuffer(_typeOptiondata.typeOptionData); } set fieldName(String name) { - _data = _data.rebuild((rebuildData) { + _typeOptiondata = _typeOptiondata.rebuild((rebuildData) { rebuildData.field_2 = rebuildData.field_2.rebuild((rebuildField) { rebuildField.name = name; }); }); - _fieldNotifier.value = _data.field_2; + _fieldNotifier.value = _typeOptiondata.field_2; FieldService(databaseId: databaseId, fieldId: field.id) .updateField(name: name); } set typeOptionData(List typeOptionData) { - _data = _data.rebuild((rebuildData) { + _typeOptiondata = _typeOptiondata.rebuild((rebuildData) { if (typeOptionData.isNotEmpty) { rebuildData.typeOptionData = typeOptionData; } diff --git a/frontend/app_flowy/lib/startup/plugin/plugin.dart b/frontend/app_flowy/lib/startup/plugin/plugin.dart index d7ae8f378f..d199f78783 100644 --- a/frontend/app_flowy/lib/startup/plugin/plugin.dart +++ b/frontend/app_flowy/lib/startup/plugin/plugin.dart @@ -52,7 +52,7 @@ abstract class PluginBuilder { PluginType get pluginType; - ViewDataFormatPB get dataFormatType => ViewDataFormatPB.TreeFormat; + ViewDataFormatPB get dataFormatType => ViewDataFormatPB.NodeFormat; ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Document; } diff --git a/frontend/app_flowy/lib/workspace/application/app/app_service.dart b/frontend/app_flowy/lib/workspace/application/app/app_service.dart index 7b477dbac3..abaf4ed229 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_service.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_service.dart @@ -76,7 +76,7 @@ class AppService { ..to = toIndex ..ty = MoveFolderItemType.MoveView; - return FolderEventMoveFolderItem(payload).send(); + return FolderEventMoveItem(payload).send(); } Future>>> fetchViews( diff --git a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart index 078988657c..3f32e4e9e3 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart @@ -65,6 +65,6 @@ class WorkspaceService { ..to = toIndex ..ty = MoveFolderItemType.MoveApp; - return FolderEventMoveFolderItem(payload).send(); + return FolderEventMoveItem(payload).send(); } } diff --git a/frontend/app_flowy/test/bloc_test/board_test/group_by_checkbox_field_test.dart b/frontend/app_flowy/test/bloc_test/board_test/group_by_checkbox_field_test.dart index 0a971cff0d..c9c0d1e566 100644 --- a/frontend/app_flowy/test/bloc_test/board_test/group_by_checkbox_field_test.dart +++ b/frontend/app_flowy/test/bloc_test/board_test/group_by_checkbox_field_test.dart @@ -33,7 +33,7 @@ void main() { final gridGroupBloc = GridGroupBloc( viewId: context.gridView.id, fieldController: context.fieldController, - ); + )..add(const GridGroupEvent.initial()); gridGroupBloc.add(GridGroupEvent.setGroupByField( checkboxField.id, checkboxField.fieldType, diff --git a/frontend/app_flowy/test/bloc_test/board_test/group_by_multi_select_field_test.dart b/frontend/app_flowy/test/bloc_test/board_test/group_by_multi_select_field_test.dart index f9f7af678e..748ec64f51 100644 --- a/frontend/app_flowy/test/bloc_test/board_test/group_by_multi_select_field_test.dart +++ b/frontend/app_flowy/test/bloc_test/board_test/group_by_multi_select_field_test.dart @@ -14,7 +14,7 @@ void main() { boardTest = await AppFlowyBoardTest.ensureInitialized(); }); - test('group by multi select with no options test', () async { + test('no status group name test', () async { final context = await boardTest.createTestBoard(); // create multi-select field @@ -27,7 +27,9 @@ void main() { final gridGroupBloc = GridGroupBloc( viewId: context.gridView.id, fieldController: context.fieldController, - ); + )..add(const GridGroupEvent.initial()); + await boardResponseFuture(); + gridGroupBloc.add(GridGroupEvent.setGroupByField( multiSelectField.id, multiSelectField.fieldType, @@ -72,7 +74,9 @@ void main() { final gridGroupBloc = GridGroupBloc( viewId: context.gridView.id, fieldController: context.fieldController, - ); + )..add(const GridGroupEvent.initial()); + await boardResponseFuture(); + gridGroupBloc.add(GridGroupEvent.setGroupByField( multiSelectField.id, multiSelectField.fieldType, diff --git a/frontend/app_flowy/test/bloc_test/grid_test/cell/select_option_cell_test.dart b/frontend/app_flowy/test/bloc_test/grid_test/cell/select_option_cell_test.dart index ca8e145bfa..44cc8f65a3 100644 --- a/frontend/app_flowy/test/bloc_test/grid_test/cell/select_option_cell_test.dart +++ b/frontend/app_flowy/test/bloc_test/grid_test/cell/select_option_cell_test.dart @@ -64,15 +64,24 @@ void main() { bloc.add(const SelectOptionEditorEvent.newOption("A")); await gridResponseFuture(); + assert(bloc.state.options.length == 1, + "Expect 1 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}"); + bloc.add(const SelectOptionEditorEvent.newOption("B")); await gridResponseFuture(); + assert(bloc.state.options.length == 2, + "Expect 2 but receive ${bloc.state.options.length}, Options: ${bloc.state.options}"); + bloc.add(const SelectOptionEditorEvent.newOption("C")); await gridResponseFuture(); + assert(bloc.state.options.length == 3, + "Expect 3 but receive ${bloc.state.options.length}. Options: ${bloc.state.options}"); bloc.add(const SelectOptionEditorEvent.deleteAllOptions()); await gridResponseFuture(); - assert(bloc.state.options.isEmpty); + assert(bloc.state.options.isEmpty, + "Expect empty but receive ${bloc.state.options.length}"); }); test('select/unselect option', () async { @@ -161,18 +170,41 @@ void main() { bloc.add(const SelectOptionEditorEvent.newOption("abcd")); await gridResponseFuture(); + expect( + bloc.state.options.length, + 1, + reason: "Options: ${bloc.state.options}", + ); bloc.add(const SelectOptionEditorEvent.newOption("aaaa")); await gridResponseFuture(); + expect( + bloc.state.options.length, + 2, + reason: "Options: ${bloc.state.options}", + ); bloc.add(const SelectOptionEditorEvent.newOption("defg")); await gridResponseFuture(); + expect( + bloc.state.options.length, + 3, + reason: "Options: ${bloc.state.options}", + ); bloc.add(const SelectOptionEditorEvent.filterOption("a")); await gridResponseFuture(); - expect(bloc.state.options.length, 2); - expect(bloc.state.allOptions.length, 3); + expect( + bloc.state.options.length, + 2, + reason: "Options: ${bloc.state.options}", + ); + expect( + bloc.state.allOptions.length, + 3, + reason: "Options: ${bloc.state.options}", + ); expect(bloc.state.createOption, const Some("a")); expect(bloc.state.filter, const Some("a")); }); diff --git a/frontend/app_flowy/test/bloc_test/grid_test/field/edit_field_test.dart b/frontend/app_flowy/test/bloc_test/grid_test/field/edit_field_test.dart index acf38e42a0..4086eefe4c 100644 --- a/frontend/app_flowy/test/bloc_test/grid_test/field/edit_field_test.dart +++ b/frontend/app_flowy/test/bloc_test/grid_test/field/edit_field_test.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:app_flowy/plugins/grid/application/prelude.dart'; -import 'package:bloc_test/bloc_test.dart'; import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart'; import 'package:flutter_test/flutter_test.dart'; import '../util.dart'; @@ -28,75 +27,69 @@ void main() { gridTest = await AppFlowyGridTest.ensureInitialized(); }); - group('$FieldEditorBloc', () { - late FieldEditorBloc editorBloc; + test('rename field', () async { + final editorBloc = await makeEditorBloc(gridTest); + editorBloc.add(const FieldEditorEvent.updateName('Hello world')); + await gridResponseFuture(); - setUp(() async { - final context = await gridTest.createTestGrid(); - final fieldInfo = context.singleSelectFieldContext(); - final loader = FieldTypeOptionLoader( - databaseId: context.gridView.id, - field: fieldInfo.field, - ); - - editorBloc = FieldEditorBloc( - databaseId: context.gridView.id, - fieldName: fieldInfo.name, - isGroupField: fieldInfo.isGroupField, - loader: loader, - )..add(const FieldEditorEvent.initial()); - - await gridResponseFuture(); - }); - - blocTest( - "rename field", - build: () => editorBloc, - act: (bloc) async { - editorBloc.add(const FieldEditorEvent.updateName('Hello world')); - }, - wait: gridResponseDuration(), - verify: (bloc) { - bloc.state.field.fold( - () => throw Exception("The field should not be none"), - (field) { - assert(field.name == 'Hello world'); - }, - ); + editorBloc.state.field.fold( + () => throw Exception("The field should not be none"), + (field) { + assert(field.name == 'Hello world'); }, ); + }); - blocTest( - "switch to text field", - build: () => editorBloc, - act: (bloc) async { - editorBloc - .add(const FieldEditorEvent.switchToField(FieldType.RichText)); - }, - wait: gridResponseDuration(), - verify: (bloc) { - bloc.state.field.fold( - () => throw Exception("The field should not be none"), - (field) { - // The default length of the fields is 3. The length of the fields - // should not change after switching to other field type - // assert(gridTest.fieldContexts.length == 3); - assert(field.fieldType == FieldType.RichText); - }, - ); + test('switch to text field', () async { + final editorBloc = await makeEditorBloc(gridTest); + + editorBloc.add(const FieldEditorEvent.switchToField(FieldType.RichText)); + await gridResponseFuture(); + + editorBloc.state.field.fold( + () => throw Exception("The field should not be none"), + (field) { + // The default length of the fields is 3. The length of the fields + // should not change after switching to other field type + // assert(gridTest.fieldContexts.length == 3); + assert(field.fieldType == FieldType.RichText); }, ); + }); - blocTest( - "delete field", - build: () => editorBloc, - act: (bloc) async { - editorBloc.add(const FieldEditorEvent.deleteField()); - }, - wait: gridResponseDuration(), - verify: (bloc) { - // assert(gridTest.fieldContexts.length == 2); + test('delete field', () async { + final editorBloc = await makeEditorBloc(gridTest); + editorBloc.add(const FieldEditorEvent.switchToField(FieldType.RichText)); + await gridResponseFuture(); + + editorBloc.state.field.fold( + () => throw Exception("The field should not be none"), + (field) { + // The default length of the fields is 3. The length of the fields + // should not change after switching to other field type + // assert(gridTest.fieldContexts.length == 3); + assert(field.fieldType == FieldType.RichText); }, ); }); } + +Future makeEditorBloc(AppFlowyGridTest gridTest) async { + final context = await gridTest.createTestGrid(); + final fieldInfo = context.singleSelectFieldContext(); + final loader = FieldTypeOptionLoader( + databaseId: context.gridView.id, + field: fieldInfo.field, + ); + + final editorBloc = FieldEditorBloc( + databaseId: context.gridView.id, + fieldName: fieldInfo.name, + isGroupField: fieldInfo.isGroupField, + loader: loader, + )..add(const FieldEditorEvent.initial()); + + await gridResponseFuture(); + + return editorBloc; +} diff --git a/frontend/app_flowy/test/bloc_test/grid_test/util.dart b/frontend/app_flowy/test/bloc_test/grid_test/util.dart index f868cf43f5..3e90577d00 100644 --- a/frontend/app_flowy/test/bloc_test/grid_test/util.dart +++ b/frontend/app_flowy/test/bloc_test/grid_test/util.dart @@ -210,7 +210,7 @@ class AppFlowyGridCellTest { Future makeSelectOptionCellController( FieldType fieldType, int rowIndex) async { - return context.makeSelectOptionCellController(fieldType, rowIndex); + return await context.makeSelectOptionCellController(fieldType, rowIndex); } } diff --git a/frontend/app_flowy/test/bloc_test/home_test/view_bloc_test.dart b/frontend/app_flowy/test/bloc_test/home_test/view_bloc_test.dart index f5c37d986e..082fe0fc21 100644 --- a/frontend/app_flowy/test/bloc_test/home_test/view_bloc_test.dart +++ b/frontend/app_flowy/test/bloc_test/home_test/view_bloc_test.dart @@ -46,7 +46,7 @@ void main() { viewBloc.add(const ViewEvent.duplicate()); await blocResponseFuture(); - assert(appBloc.state.views.length == 2); + expect(appBloc.state.views.length, 2); }); test('delete view test', () async { @@ -59,7 +59,7 @@ void main() { DocumentPluginBuilder(), )); await blocResponseFuture(); - assert(appBloc.state.views.length == 1); + expect(appBloc.state.views.length, 1); final viewBloc = ViewBloc(view: appBloc.state.views.first) ..add(const ViewEvent.initial()); diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 1d4d4c772d..914b99a9b4 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -211,7 +211,7 @@ impl ViewDataProcessor for DocumentViewDataProcessor { } fn data_types(&self) -> Vec { - vec![ViewDataFormatPB::DeltaFormat, ViewDataFormatPB::TreeFormat] + vec![ViewDataFormatPB::DeltaFormat, ViewDataFormatPB::NodeFormat] } } diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index d72f636457..063b67bff9 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -297,7 +297,7 @@ impl UserStatusListener { async fn did_sign_up(&self, user_profile: &UserProfile) -> FlowyResult<()> { let view_data_type = match self.config.document.version { DocumentVersionPB::V0 => ViewDataFormatPB::DeltaFormat, - DocumentVersionPB::V1 => ViewDataFormatPB::TreeFormat, + DocumentVersionPB::V1 => ViewDataFormatPB::NodeFormat, }; self.folder_manager .initialize_with_new_user(&user_profile.id, &user_profile.token, view_data_type) diff --git a/frontend/rust-lib/flowy-database/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database/src/services/filter/controller.rs index 11c758b2c5..f9e163d0ae 100644 --- a/frontend/rust-lib/flowy-database/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database/src/services/filter/controller.rs @@ -5,6 +5,7 @@ use crate::services::field::*; use crate::services::filter::{FilterChangeset, FilterResult, FilterResultNotification, FilterType}; use crate::services::row::DatabaseBlockRowRevision; use crate::services::view_editor::{GridViewChanged, GridViewChangedNotifier}; +use dashmap::DashMap; use flowy_error::FlowyResult; use flowy_task::{QualityOfService, Task, TaskContent, TaskDispatcher}; use grid_model::{CellRevision, FieldId, FieldRevision, FilterRevision, RowRevision}; @@ -34,7 +35,7 @@ pub struct FilterController { view_id: String, handler_id: String, delegate: Box, - result_by_row_id: HashMap, + result_by_row_id: DashMap, cell_data_cache: AtomicCellDataCache, cell_filter_cache: AtomicCellFilterCache, task_scheduler: Arc>, @@ -54,11 +55,11 @@ impl FilterController { where T: FilterDelegate + 'static, { - let mut this = Self { + let this = Self { view_id: view_id.to_string(), handler_id: handler_id.to_string(), delegate: Box::new(delegate), - result_by_row_id: HashMap::default(), + result_by_row_id: DashMap::default(), cell_data_cache, cell_filter_cache: AnyTypeCache::::new(), task_scheduler, @@ -83,7 +84,7 @@ impl FilterController { self.task_scheduler.write().await.add_task(task); } - pub async fn filter_row_revs(&mut self, row_revs: &mut Vec>) { + pub async fn filter_row_revs(&self, row_revs: &mut Vec>) { if self.cell_filter_cache.read().is_empty() { return; } @@ -91,7 +92,7 @@ impl FilterController { row_revs.iter().for_each(|row_rev| { let _ = filter_row( row_rev, - &mut self.result_by_row_id, + &self.result_by_row_id, &field_rev_by_field_id, &self.cell_data_cache, &self.cell_filter_cache, @@ -116,7 +117,7 @@ impl FilterController { } #[tracing::instrument(name = "process_filter_task", level = "trace", skip_all, fields(filter_result), err)] - pub async fn process(&mut self, predicate: &str) -> FlowyResult<()> { + pub async fn process(&self, predicate: &str) -> FlowyResult<()> { let event_type = FilterEvent::from_str(predicate).unwrap(); match event_type { FilterEvent::FilterDidChanged => self.filter_all_rows().await?, @@ -125,13 +126,13 @@ impl FilterController { Ok(()) } - async fn filter_row(&mut self, row_id: String) -> FlowyResult<()> { + async fn filter_row(&self, row_id: String) -> FlowyResult<()> { if let Some((_, row_rev)) = self.delegate.get_row_rev(&row_id).await { let field_rev_by_field_id = self.get_filter_revs_map().await; let mut notification = FilterResultNotification::new(self.view_id.clone(), row_rev.block_id.clone()); if let Some((row_id, is_visible)) = filter_row( &row_rev, - &mut self.result_by_row_id, + &self.result_by_row_id, &field_rev_by_field_id, &self.cell_data_cache, &self.cell_filter_cache, @@ -153,7 +154,7 @@ impl FilterController { Ok(()) } - async fn filter_all_rows(&mut self) -> FlowyResult<()> { + async fn filter_all_rows(&self) -> FlowyResult<()> { let field_rev_by_field_id = self.get_filter_revs_map().await; for block in self.delegate.get_blocks().await.into_iter() { // The row_ids contains the row that its visibility was changed. @@ -163,7 +164,7 @@ impl FilterController { for (index, row_rev) in block.row_revs.iter().enumerate() { if let Some((row_id, is_visible)) = filter_row( row_rev, - &mut self.result_by_row_id, + &self.result_by_row_id, &field_rev_by_field_id, &self.cell_data_cache, &self.cell_filter_cache, @@ -198,7 +199,7 @@ impl FilterController { } #[tracing::instrument(level = "trace", skip(self))] - pub async fn did_receive_changes(&mut self, changeset: FilterChangeset) -> Option { + pub async fn did_receive_changes(&self, changeset: FilterChangeset) -> Option { let mut notification: Option = None; if let Some(filter_type) = &changeset.insert_filter { if let Some(filter) = self.filter_from_filter_type(filter_type).await { @@ -258,7 +259,7 @@ impl FilterController { } #[tracing::instrument(level = "trace", skip_all)] - async fn refresh_filters(&mut self, filter_revs: Vec>) { + async fn refresh_filters(&self, filter_revs: Vec>) { for filter_rev in filter_revs { if let Some(field_rev) = self.delegate.get_field_rev(&filter_rev.field_id).await { let filter_type = FilterType::from(&field_rev); @@ -309,13 +310,13 @@ impl FilterController { #[tracing::instrument(level = "trace", skip_all)] fn filter_row( row_rev: &Arc, - result_by_row_id: &mut HashMap, + result_by_row_id: &DashMap, field_rev_by_field_id: &HashMap>, cell_data_cache: &AtomicCellDataCache, cell_filter_cache: &AtomicCellFilterCache, ) -> Option<(String, bool)> { // Create a filter result cache if it's not exist - let filter_result = result_by_row_id + let mut filter_result = result_by_row_id .entry(row_rev.id.clone()) .or_insert_with(FilterResult::default); let old_is_visible = filter_result.is_visible(); diff --git a/frontend/rust-lib/flowy-database/src/services/filter/task.rs b/frontend/rust-lib/flowy-database/src/services/filter/task.rs index 22c607a270..1ba83ff531 100644 --- a/frontend/rust-lib/flowy-database/src/services/filter/task.rs +++ b/frontend/rust-lib/flowy-database/src/services/filter/task.rs @@ -3,15 +3,14 @@ use flowy_task::{TaskContent, TaskHandler}; use lib_infra::future::BoxResultFuture; use std::collections::HashMap; use std::sync::Arc; -use tokio::sync::RwLock; pub struct FilterTaskHandler { handler_id: String, - filter_controller: Arc>, + filter_controller: Arc, } impl FilterTaskHandler { - pub fn new(handler_id: String, filter_controller: Arc>) -> Self { + pub fn new(handler_id: String, filter_controller: Arc) -> Self { Self { handler_id, filter_controller, @@ -33,8 +32,6 @@ impl TaskHandler for FilterTaskHandler { Box::pin(async move { if let TaskContent::Text(predicate) = content { filter_controller - .write() - .await .process(&predicate) .await .map_err(anyhow::Error::from)?; diff --git a/frontend/rust-lib/flowy-database/src/services/view_editor/editor.rs b/frontend/rust-lib/flowy-database/src/services/view_editor/editor.rs index 8870342ec6..f4c4607ea3 100644 --- a/frontend/rust-lib/flowy-database/src/services/view_editor/editor.rs +++ b/frontend/rust-lib/flowy-database/src/services/view_editor/editor.rs @@ -74,7 +74,7 @@ pub struct DatabaseViewRevisionEditor { rev_manager: Arc>>, delegate: Arc, group_controller: Arc>>, - filter_controller: Arc>, + filter_controller: Arc, sort_controller: Arc>, pub notifier: GridViewChangedNotifier, } @@ -156,7 +156,7 @@ impl DatabaseViewRevisionEditor { pub async fn close(&self) { self.rev_manager.generate_snapshot().await; self.rev_manager.close().await; - self.filter_controller.read().await.close().await; + self.filter_controller.close().await; self.sort_controller.read().await.close().await; } @@ -194,7 +194,7 @@ impl DatabaseViewRevisionEditor { } pub async fn filter_rows(&self, _block_id: &str, rows: &mut Vec>) { - self.filter_controller.write().await.filter_row_revs(rows).await; + self.filter_controller.filter_row_revs(rows).await; } pub async fn duplicate_view_data(&self) -> FlowyResult { @@ -286,7 +286,7 @@ impl DatabaseViewRevisionEditor { let sort_controller = self.sort_controller.clone(); let row_id = row_rev.id.clone(); tokio::spawn(async move { - filter_controller.read().await.did_receive_row_changed(&row_id).await; + filter_controller.did_receive_row_changed(&row_id).await; sort_controller.read().await.did_receive_row_changed(&row_id).await; }); } @@ -514,7 +514,7 @@ impl DatabaseViewRevisionEditor { condition: params.condition, content: params.content, }; - let mut filter_controller = self.filter_controller.write().await; + let filter_controller = self.filter_controller.clone(); let changeset = if is_exist { let old_filter_type = self .delegate @@ -555,8 +555,6 @@ impl DatabaseViewRevisionEditor { let filter_type = params.filter_type; let changeset = self .filter_controller - .write() - .await .did_receive_changes(FilterChangeset::from_delete(filter_type.clone())) .await; @@ -590,15 +588,14 @@ impl DatabaseViewRevisionEditor { .did_update_view_field_type_option(&field_rev) .await; - if let Some(changeset) = self - .filter_controller - .write() - .await - .did_receive_changes(filter_changeset) - .await - { - self.notify_did_update_filter(changeset).await; - } + let filter_controller = self.filter_controller.clone(); + let _ = tokio::spawn(async move { + if let Some(notification) = filter_controller.did_receive_changes(filter_changeset).await { + send_notification(¬ification.view_id, DatabaseNotification::DidUpdateFilter) + .payload(notification) + .send(); + } + }); } Ok(()) } @@ -830,7 +827,7 @@ async fn make_filter_controller( notifier: GridViewChangedNotifier, cell_data_cache: AtomicCellDataCache, pad: Arc>, -) -> Arc> { +) -> Arc { let field_revs = delegate.get_field_revs(None).await; let filter_revs = pad.read().await.get_all_filters(&field_revs); let task_scheduler = delegate.get_task_scheduler(); @@ -849,7 +846,7 @@ async fn make_filter_controller( notifier, ) .await; - let filter_controller = Arc::new(RwLock::new(filter_controller)); + let filter_controller = Arc::new(filter_controller); task_scheduler .write() .await @@ -861,7 +858,7 @@ async fn make_sort_controller( view_id: &str, delegate: Arc, notifier: GridViewChangedNotifier, - filter_controller: Arc>, + filter_controller: Arc, pad: Arc>, cell_data_cache: AtomicCellDataCache, ) -> Arc> { diff --git a/frontend/rust-lib/flowy-database/src/services/view_editor/trait_impl.rs b/frontend/rust-lib/flowy-database/src/services/view_editor/trait_impl.rs index e3ba647e52..8ebbd39e78 100644 --- a/frontend/rust-lib/flowy-database/src/services/view_editor/trait_impl.rs +++ b/frontend/rust-lib/flowy-database/src/services/view_editor/trait_impl.rs @@ -185,7 +185,7 @@ impl FilterDelegate for GridViewFilterDelegateImpl { pub(crate) struct GridViewSortDelegateImpl { pub(crate) editor_delegate: Arc, pub(crate) view_revision_pad: Arc>, - pub(crate) filter_controller: Arc>, + pub(crate) filter_controller: Arc, } impl SortDelegate for GridViewSortDelegateImpl { @@ -209,7 +209,7 @@ impl SortDelegate for GridViewSortDelegateImpl { let editor_delegate = self.editor_delegate.clone(); to_fut(async move { let mut row_revs = editor_delegate.get_row_revs(None).await; - filter_controller.write().await.filter_row_revs(&mut row_revs).await; + filter_controller.filter_row_revs(&mut row_revs).await; row_revs }) } diff --git a/frontend/rust-lib/flowy-folder/src/entities/mod.rs b/frontend/rust-lib/flowy-folder/src/entities/mod.rs index e75c8c13bd..d5370f0786 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/mod.rs @@ -2,11 +2,9 @@ pub mod app; mod parser; pub mod trash; pub mod view; -mod view_info; pub mod workspace; pub use app::*; pub use trash::*; pub use view::*; -pub use view_info::*; pub use workspace::*; diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index 129f4964bd..bfcea3a235 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -50,9 +50,13 @@ impl std::convert::From for ViewPB { #[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone)] pub enum ViewDataFormatPB { + /// Indicate this view is using `Delta` for the persistence data format, it's deprecated. DeltaFormat = 0, + /// Indicate this view is using `Database` for the persistence data format. It is used in AppFlowy database + /// views including Grid,Board, and Calendar. DatabaseFormat = 1, - TreeFormat = 2, + /// Indicate this view is using `Node` for the persistence data format. It is used in AppFlowy document + NodeFormat = 2, } impl std::default::Default for ViewDataFormatPB { @@ -66,7 +70,7 @@ impl std::convert::From for ViewDataFormatPB { match rev { ViewDataFormatRevision::DeltaFormat => ViewDataFormatPB::DeltaFormat, ViewDataFormatRevision::DatabaseFormat => ViewDataFormatPB::DatabaseFormat, - ViewDataFormatRevision::TreeFormat => ViewDataFormatPB::TreeFormat, + ViewDataFormatRevision::NodeFormat => ViewDataFormatPB::NodeFormat, } } } @@ -76,7 +80,7 @@ impl std::convert::From for ViewDataFormatRevision { match ty { ViewDataFormatPB::DeltaFormat => ViewDataFormatRevision::DeltaFormat, ViewDataFormatPB::DatabaseFormat => ViewDataFormatRevision::DatabaseFormat, - ViewDataFormatPB::TreeFormat => ViewDataFormatRevision::TreeFormat, + ViewDataFormatPB::NodeFormat => ViewDataFormatRevision::NodeFormat, } } } diff --git a/frontend/rust-lib/flowy-folder/src/entities/view_info.rs b/frontend/rust-lib/flowy-folder/src/entities/view_info.rs deleted file mode 100644 index e4031d0ecb..0000000000 --- a/frontend/rust-lib/flowy-folder/src/entities/view_info.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::entities::{RepeatedViewPB, ViewDataFormatPB}; -use flowy_derive::ProtoBuf; - -#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct ViewInfoPB { - #[pb(index = 1)] - pub id: String, - - #[pb(index = 2)] - pub belong_to_id: String, - - #[pb(index = 3)] - pub name: String, - - #[pb(index = 4)] - pub desc: String, - - #[pb(index = 5)] - pub data_type: ViewDataFormatPB, - - #[pb(index = 6)] - pub belongings: RepeatedViewPB, - - #[pb(index = 7)] - pub ext_data: String, -} diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index e657d3a0c7..3c8385b925 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -63,12 +63,11 @@ pub fn init(folder: Arc) -> AFPlugin { .event(FolderEvent::CreateView, create_view_handler) .event(FolderEvent::ReadView, read_view_handler) .event(FolderEvent::UpdateView, update_view_handler) - .event(FolderEvent::ReadViewInfo, read_view_info_handler) .event(FolderEvent::DeleteView, delete_view_handler) .event(FolderEvent::DuplicateView, duplicate_view_handler) .event(FolderEvent::SetLatestView, set_latest_view_handler) .event(FolderEvent::CloseView, close_view_handler) - .event(FolderEvent::MoveFolderItem, move_item_handler); + .event(FolderEvent::MoveItem, move_item_handler); // Trash plugin = plugin @@ -84,78 +83,99 @@ pub fn init(folder: Arc) -> AFPlugin { #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[event_err = "FlowyError"] pub enum FolderEvent { + /// Create a new workspace #[event(input = "CreateWorkspacePayloadPB", output = "WorkspacePB")] CreateWorkspace = 0, + /// Read the current opening workspace #[event(output = "WorkspaceSettingPB")] ReadCurrentWorkspace = 1, + /// Open the workspace and mark it as the current workspace #[event(input = "WorkspaceIdPB", output = "RepeatedWorkspacePB")] ReadWorkspaces = 2, + /// Delete the workspace #[event(input = "WorkspaceIdPB")] DeleteWorkspace = 3, + /// Open the workspace and mark it as the current workspace #[event(input = "WorkspaceIdPB", output = "WorkspacePB")] OpenWorkspace = 4, + /// Return a list of apps that belong to this workspace #[event(input = "WorkspaceIdPB", output = "RepeatedAppPB")] ReadWorkspaceApps = 5, + /// Create a new app #[event(input = "CreateAppPayloadPB", output = "AppPB")] CreateApp = 101, + /// Delete the app #[event(input = "AppIdPB")] DeleteApp = 102, + /// Read the app #[event(input = "AppIdPB", output = "AppPB")] ReadApp = 103, + /// Update the app's properties including the name,description, etc. #[event(input = "UpdateAppPayloadPB")] UpdateApp = 104, + /// Create a new view in the corresponding app #[event(input = "CreateViewPayloadPB", output = "ViewPB")] CreateView = 201, + /// Return the view info #[event(input = "ViewIdPB", output = "ViewPB")] ReadView = 202, + /// Update the view's properties including the name,description, etc. #[event(input = "UpdateViewPayloadPB", output = "ViewPB")] UpdateView = 203, + /// Move the view to the trash folder #[event(input = "RepeatedViewIdPB")] DeleteView = 204, + /// Duplicate the view #[event(input = "ViewPB")] DuplicateView = 205, + /// Close and release the resources that are used by this view. + /// It should get called when the 'View' page get destroy #[event(input = "ViewIdPB")] CloseView = 206, - #[event(input = "ViewIdPB", output = "ViewInfoPB")] - ReadViewInfo = 207, - #[event()] CopyLink = 220, + /// Set the current visiting view #[event(input = "ViewIdPB")] SetLatestView = 221, + /// Move the view or app to another place #[event(input = "MoveFolderItemPayloadPB")] - MoveFolderItem = 230, + MoveItem = 230, + /// Read the trash that was deleted by the user #[event(output = "RepeatedTrashPB")] ReadTrash = 300, + /// Put back the trash to the origin folder #[event(input = "TrashIdPB")] PutbackTrash = 301, + /// Delete the trash from the disk #[event(input = "RepeatedTrashIdPB")] DeleteTrash = 302, + /// Put back all the trash to its original folder #[event()] RestoreAllTrash = 303, + /// Delete all the trash from the disk #[event()] DeleteAllTrash = 304, } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs index a5bc92b178..1f913c6a63 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/view_sql.rs @@ -89,7 +89,7 @@ impl ViewTable { let data_type = match view_rev.data_format { ViewDataFormatRevision::DeltaFormat => SqlViewDataFormat::Delta, ViewDataFormatRevision::DatabaseFormat => SqlViewDataFormat::Database, - ViewDataFormatRevision::TreeFormat => SqlViewDataFormat::Tree, + ViewDataFormatRevision::NodeFormat => SqlViewDataFormat::Tree, }; ViewTable { @@ -113,7 +113,7 @@ impl std::convert::From for ViewRevision { let data_type = match table.view_type { SqlViewDataFormat::Delta => ViewDataFormatRevision::DeltaFormat, SqlViewDataFormat::Database => ViewDataFormatRevision::DatabaseFormat, - SqlViewDataFormat::Tree => ViewDataFormatRevision::TreeFormat, + SqlViewDataFormat::Tree => ViewDataFormatRevision::NodeFormat, }; ViewRevision { diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index f184da6ae1..2309c7b458 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -1,10 +1,10 @@ pub use crate::entities::view::ViewDataFormatPB; -use crate::entities::{AppPB, DeletedViewPB, ViewInfoPB, ViewLayoutTypePB}; +use crate::entities::{AppPB, DeletedViewPB, ViewLayoutTypePB}; use crate::manager::{ViewDataProcessor, ViewDataProcessorMap}; use crate::{ entities::{ trash::{RepeatedTrashIdPB, TrashType}, - view::{CreateViewParams, RepeatedViewPB, UpdateViewParams, ViewIdPB, ViewPB}, + view::{CreateViewParams, UpdateViewParams, ViewIdPB, ViewPB}, }, errors::{FlowyError, FlowyResult}, event_map::{FolderCouldServiceV1, WorkspaceUser}, @@ -139,35 +139,6 @@ impl ViewController { Ok(view_rev) } - #[tracing::instrument(level = "debug", skip(self, view_id), fields(view_id = %view_id.value), err)] - pub(crate) async fn read_view_pb(&self, view_id: ViewIdPB) -> Result { - let view_info = self - .persistence - .begin_transaction(|transaction| { - let view_rev = transaction.read_view(&view_id.value)?; - - let items: Vec = view_rev - .belongings - .into_iter() - .map(|view_rev| view_rev.into()) - .collect(); - - let view_info = ViewInfoPB { - id: view_rev.id, - belong_to_id: view_rev.app_id, - name: view_rev.name, - desc: view_rev.desc, - data_type: view_rev.data_format.into(), - belongings: RepeatedViewPB { items }, - ext_data: view_rev.ext_data, - }; - Ok(view_info) - }) - .await?; - - Ok(view_info) - } - pub(crate) async fn read_local_views(&self, ids: Vec) -> Result, FlowyError> { self.persistence .begin_transaction(|transaction| { diff --git a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs index a0e16c204e..03948b0e59 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs @@ -1,5 +1,4 @@ use crate::entities::view::{MoveFolderItemParams, MoveFolderItemPayloadPB, MoveFolderItemType}; -use crate::entities::ViewInfoPB; use crate::manager::FolderManager; use crate::services::{notify_workspace_setting_did_change, AppController}; use crate::{ @@ -35,15 +34,6 @@ pub(crate) async fn read_view_handler( data_result(view_rev.into()) } -pub(crate) async fn read_view_info_handler( - data: AFPluginData, - controller: AFPluginState>, -) -> DataResult { - let view_id: ViewIdPB = data.into_inner(); - let view_info = controller.read_view_pb(view_id.clone()).await?; - data_result(view_info) -} - #[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn update_view_handler( data: AFPluginData, diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index 55eadb6198..bc5a321e97 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -182,7 +182,7 @@ impl FolderTest { FolderScript::CreateView { name, desc, data_type } => { let layout = match data_type { ViewDataFormatPB::DeltaFormat => ViewLayoutTypePB::Document, - ViewDataFormatPB::TreeFormat => ViewLayoutTypePB::Document, + ViewDataFormatPB::NodeFormat => ViewLayoutTypePB::Document, ViewDataFormatPB::DatabaseFormat => ViewLayoutTypePB::Grid, }; let view = create_view(sdk, &self.app.id, &name, &desc, data_type, layout).await; diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 827de47fdc..49d8e43bd4 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -58,7 +58,7 @@ impl ViewTest { pub async fn new_document_view(sdk: &FlowySDKTest) -> Self { let view_data_format = match sdk.document_version() { DocumentVersionPB::V0 => ViewDataFormatPB::DeltaFormat, - DocumentVersionPB::V1 => ViewDataFormatPB::TreeFormat, + DocumentVersionPB::V1 => ViewDataFormatPB::NodeFormat, }; Self::new(sdk, view_data_format, ViewLayoutTypePB::Document, vec![]).await } diff --git a/shared-lib/folder-model/src/view_rev.rs b/shared-lib/folder-model/src/view_rev.rs index 7906be39cd..8cb9f5a866 100644 --- a/shared-lib/folder-model/src/view_rev.rs +++ b/shared-lib/folder-model/src/view_rev.rs @@ -59,7 +59,7 @@ impl std::convert::From for TrashRevision { pub enum ViewDataFormatRevision { DeltaFormat = 0, DatabaseFormat = 1, - TreeFormat = 2, + NodeFormat = 2, } impl std::default::Default for ViewDataFormatRevision {