From 8588afcda6bf27971a964d1a0df690e0feac8fc2 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Fri, 10 Feb 2023 22:24:34 +0800 Subject: [PATCH] feat: support create document with initial data (#1841) --- .../document/application/doc_bloc.dart | 4 +- .../document/application/doc_service.dart | 6 +- .../grid/application/row/row_listener.dart | 46 --------------- .../application/app/app_service.dart | 58 +++---------------- .../src/deps_resolve/folder_deps.rs | 15 ++++- .../rust-lib/flowy-document/src/entities.rs | 8 +-- .../flowy-document/src/event_handler.rs | 12 ++-- .../rust-lib/flowy-document/src/event_map.rs | 2 +- .../flowy-folder/src/entities/view.rs | 6 +- frontend/rust-lib/flowy-folder/src/manager.rs | 2 +- .../src/services/view/controller.rs | 14 ++--- .../flowy-folder/tests/workspace/script.rs | 2 +- frontend/rust-lib/flowy-test/src/helper.rs | 2 +- 13 files changed, 49 insertions(+), 128 deletions(-) delete mode 100644 frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart diff --git a/frontend/app_flowy/lib/plugins/document/application/doc_bloc.dart b/frontend/app_flowy/lib/plugins/document/application/doc_bloc.dart index 35898f982f..b8be9c1493 100644 --- a/frontend/app_flowy/lib/plugins/document/application/doc_bloc.dart +++ b/frontend/app_flowy/lib/plugins/document/application/doc_bloc.dart @@ -75,8 +75,8 @@ class DocumentBloc extends Bloc { Future _initial(Initial value, Emitter emit) async { final result = await _documentService.openDocument(view: view); result.fold( - (block) { - final document = Document.fromJson(jsonDecode(block.snapshot)); + (documentData) { + final document = Document.fromJson(jsonDecode(documentData.content)); editorState = EditorState(document: document); _listenOnDocumentChange(); emit( diff --git a/frontend/app_flowy/lib/plugins/document/application/doc_service.dart b/frontend/app_flowy/lib/plugins/document/application/doc_service.dart index 542aecabb2..0523df505b 100644 --- a/frontend/app_flowy/lib/plugins/document/application/doc_service.dart +++ b/frontend/app_flowy/lib/plugins/document/application/doc_service.dart @@ -6,14 +6,14 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart'; class DocumentService { - Future> openDocument({ + Future> openDocument({ required ViewPB view, }) async { await FolderEventSetLatestView(ViewIdPB(value: view.id)).send(); - final payload = OpenDocumentContextPB() + final payload = OpenDocumentPayloadPB() ..documentId = view.id - ..documentVersion = DocumentVersionPB.V1; + ..version = DocumentVersionPB.V1; // switch (view.dataFormat) { // case ViewDataFormatPB.DeltaFormat: // payload.documentVersion = DocumentVersionPB.V0; diff --git a/frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart b/frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart deleted file mode 100644 index f4ad88e423..0000000000 --- a/frontend/app_flowy/lib/plugins/grid/application/row/row_listener.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:app_flowy/core/grid_notification.dart'; -import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database/notification.pb.dart'; -import 'package:flowy_infra/notifier.dart'; -import 'dart:async'; -import 'dart:typed_data'; -import 'package:dartz/dartz.dart'; -import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart'; -import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart'; - -typedef UpdateRowNotifiedValue = Either; -typedef UpdateFieldNotifiedValue = Either, FlowyError>; - -class RowListener { - final String rowId; - PublishNotifier? updateRowNotifier = - PublishNotifier(); - DatabaseNotificationListener? _listener; - - RowListener({required this.rowId}); - - void start() { - _listener = - DatabaseNotificationListener(objectId: rowId, handler: _handler); - } - - void _handler(DatabaseNotification ty, Either result) { - switch (ty) { - case DatabaseNotification.DidUpdateRow: - result.fold( - (payload) => - updateRowNotifier?.value = left(RowPB.fromBuffer(payload)), - (error) => updateRowNotifier?.value = right(error), - ); - break; - default: - break; - } - } - - Future stop() async { - await _listener?.stop(); - updateRowNotifier?.dispose(); - updateRowNotifier = null; - } -} 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 5de1fcc69b..1ebe8a75e4 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_service.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_service.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart'; import 'package:dartz/dartz.dart'; @@ -23,13 +24,18 @@ class AppService { required ViewDataFormatPB dataFormatType, required PluginType pluginType, required ViewLayoutTypePB layoutType, + + /// The initial data should be the JSON of the doucment + /// For example: {"document":{"type":"editor","children":[]}} + String? initialData, }) { - var payload = CreateViewPayloadPB.create() + final payload = CreateViewPayloadPB.create() ..belongToId = appId ..name = name ..desc = desc ?? "" ..dataFormat = dataFormatType - ..layout = layoutType; + ..layout = layoutType + ..initialData = utf8.encode(initialData ?? ""); return FolderEventCreateView(payload).send(); } @@ -118,54 +124,6 @@ class AppService { } } -extension AppFlowy on Either { - T? getLeftOrNull() { - if (isLeft()) { - final result = fold((l) => l, (r) => null); - return result; - } - return null; - } - - Future>>> fetchViews( - ViewLayoutTypePB layoutType) async { - final result = >>[]; - return FolderEventReadCurrentWorkspace().send().then((value) async { - final workspaces = value.getLeftOrNull(); - if (workspaces != null) { - final apps = workspaces.workspace.apps.items; - for (var app in apps) { - final views = await getViews(appId: app.id).then( - (value) => value - .getLeftOrNull>() - ?.where((e) => e.layout == layoutType) - .toList(), - ); - if (views != null && views.isNotEmpty) { - result.add(Tuple2(app, views)); - } - } - } - return result; - }); - } - - Future> getView( - String appID, - String viewID, - ) async { - final payload = AppIdPB.create()..value = appID; - return FolderEventReadApp(payload).send().then((result) { - return result.fold( - (app) => left( - app.belongings.items.firstWhere((e) => e.id == viewID), - ), - (error) => right(error), - ); - }); - } -} - extension AppFlowy on Either { T? getLeftOrNull() { if (isLeft()) { 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 dbcde909d9..e4bfa670a5 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 @@ -5,6 +5,7 @@ use flowy_client_ws::FlowyWebSocketConnect; use flowy_database::entities::LayoutTypePB; use flowy_database::manager::{make_database_view_data, DatabaseManager}; use flowy_database::util::{make_default_board, make_default_calendar, make_default_grid}; +use flowy_document::editor::make_transaction_from_document_content; use flowy_document::DocumentManager; use flowy_folder::entities::{ViewDataFormatPB, ViewLayoutTypePB, ViewPB}; use flowy_folder::manager::{ViewDataProcessor, ViewDataProcessorMap}; @@ -150,7 +151,15 @@ impl ViewDataProcessor for DocumentViewDataProcessor { ) -> FutureResult<(), FlowyError> { // Only accept Document type debug_assert_eq!(layout, ViewLayoutTypePB::Document); - let revision = Revision::initial_revision(view_id, view_data); + let view_data = match String::from_utf8(view_data.to_vec()) { + Ok(content) => match make_transaction_from_document_content(&content) { + Ok(transaction) => transaction.to_bytes().unwrap_or(vec![]), + Err(_) => vec![], + }, + Err(_) => vec![], + }; + + let revision = Revision::initial_revision(view_id, Bytes::from(view_data)); let view_id = view_id.to_string(); let manager = self.0.clone(); @@ -199,7 +208,7 @@ impl ViewDataProcessor for DocumentViewDataProcessor { }) } - fn create_view_from_delta_data( + fn create_view_with_data( &self, _user_id: &str, _view_id: &str, @@ -279,7 +288,7 @@ impl ViewDataProcessor for GridViewDataProcessor { }) } - fn create_view_from_delta_data( + fn create_view_with_data( &self, user_id: &str, view_id: &str, diff --git a/frontend/rust-lib/flowy-document/src/entities.rs b/frontend/rust-lib/flowy-document/src/entities.rs index 00f89d6511..8fc867be8a 100644 --- a/frontend/rust-lib/flowy-document/src/entities.rs +++ b/frontend/rust-lib/flowy-document/src/entities.rs @@ -58,13 +58,13 @@ impl TryInto for EditPayloadPB { } #[derive(Default, ProtoBuf)] -pub struct DocumentSnapshotPB { +pub struct DocumentDataPB { #[pb(index = 1)] pub doc_id: String, /// Encode in JSON format #[pb(index = 2)] - pub snapshot: String, + pub content: String, } #[derive(Default, ProtoBuf)] @@ -96,12 +96,12 @@ impl std::default::Default for DocumentVersionPB { } #[derive(Default, ProtoBuf)] -pub struct OpenDocumentContextPB { +pub struct OpenDocumentPayloadPB { #[pb(index = 1)] pub document_id: String, #[pb(index = 2)] - pub document_version: DocumentVersionPB, + pub version: DocumentVersionPB, } #[derive(Default, Debug)] diff --git a/frontend/rust-lib/flowy-document/src/event_handler.rs b/frontend/rust-lib/flowy-document/src/event_handler.rs index 9869f873da..091d3ed35c 100644 --- a/frontend/rust-lib/flowy-document/src/event_handler.rs +++ b/frontend/rust-lib/flowy-document/src/event_handler.rs @@ -1,5 +1,5 @@ use crate::entities::{ - DocumentSnapshotPB, EditParams, EditPayloadPB, ExportDataPB, ExportParams, ExportPayloadPB, OpenDocumentContextPB, + DocumentDataPB, EditParams, EditPayloadPB, ExportDataPB, ExportParams, ExportPayloadPB, OpenDocumentPayloadPB, }; use crate::DocumentManager; use flowy_error::FlowyError; @@ -9,15 +9,15 @@ use std::convert::TryInto; use std::sync::Arc; pub(crate) async fn get_document_handler( - data: AFPluginData, + data: AFPluginData, manager: AFPluginState>, -) -> DataResult { - let context: OpenDocumentContextPB = data.into_inner(); +) -> DataResult { + let context: OpenDocumentPayloadPB = data.into_inner(); let editor = manager.open_document_editor(&context.document_id).await?; let document_data = editor.export().await?; - data_result(DocumentSnapshotPB { + data_result(DocumentDataPB { doc_id: context.document_id, - snapshot: document_data, + content: document_data, }) } diff --git a/frontend/rust-lib/flowy-document/src/event_map.rs b/frontend/rust-lib/flowy-document/src/event_map.rs index 6c8e2f4113..fb8dea55c1 100644 --- a/frontend/rust-lib/flowy-document/src/event_map.rs +++ b/frontend/rust-lib/flowy-document/src/event_map.rs @@ -19,7 +19,7 @@ pub fn init(document_manager: Arc) -> AFPlugin { #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[event_err = "FlowyError"] pub enum DocumentEvent { - #[event(input = "OpenDocumentContextPB", output = "DocumentSnapshotPB")] + #[event(input = "OpenDocumentPayloadPB", output = "DocumentDataPB")] GetDocument = 0, #[event(input = "EditPayloadPB")] diff --git a/frontend/rust-lib/flowy-folder/src/entities/view.rs b/frontend/rust-lib/flowy-folder/src/entities/view.rs index bfcea3a235..01cbb5cf96 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/view.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/view.rs @@ -162,7 +162,7 @@ pub struct CreateViewPayloadPB { pub layout: ViewLayoutTypePB, #[pb(index = 7)] - pub view_content_data: Vec, + pub initial_data: Vec, } #[derive(Debug, Clone)] @@ -174,7 +174,7 @@ pub struct CreateViewParams { pub data_format: ViewDataFormatPB, pub layout: ViewLayoutTypePB, pub view_id: String, - pub view_content_data: Vec, + pub initial_data: Vec, } impl TryInto for CreateViewPayloadPB { @@ -197,7 +197,7 @@ impl TryInto for CreateViewPayloadPB { layout: self.layout, thumbnail, view_id, - view_content_data: self.view_content_data, + initial_data: self.initial_data, }) } } diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index fc9fd68217..036458e966 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -282,7 +282,7 @@ pub trait ViewDataProcessor { data_format: ViewDataFormatPB, ) -> FutureResult; - fn create_view_from_delta_data( + fn create_view_with_data( &self, user_id: &str, view_id: &str, 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 1d7b7aadab..f926025e7a 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -59,7 +59,7 @@ impl ViewController { ) -> Result { let processor = self.get_data_processor(params.data_format.clone())?; let user_id = self.user.user_id()?; - if params.view_content_data.is_empty() { + if params.initial_data.is_empty() { tracing::trace!("Create view with build-in data"); let view_data = processor .create_default_view( @@ -69,14 +69,14 @@ impl ViewController { params.data_format.clone(), ) .await?; - params.view_content_data = view_data.to_vec(); + params.initial_data = view_data.to_vec(); } else { tracing::trace!("Create view with view data"); - let delta_data = processor - .create_view_from_delta_data( + let view_data = processor + .create_view_with_data( &user_id, ¶ms.view_id, - params.view_content_data.clone(), + params.initial_data.clone(), params.layout.clone(), ) .await?; @@ -84,7 +84,7 @@ impl ViewController { ¶ms.view_id, params.data_format.clone(), params.layout.clone(), - delta_data, + view_data, ) .await?; }; @@ -232,7 +232,7 @@ impl ViewController { thumbnail: view_rev.thumbnail, data_format: view_rev.data_format.into(), layout: view_rev.layout.into(), - view_content_data: view_data.to_vec(), + initial_data: view_data.to_vec(), view_id: gen_view_id(), }; diff --git a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs index bc5a321e97..5cce7e4207 100644 --- a/frontend/rust-lib/flowy-folder/tests/workspace/script.rs +++ b/frontend/rust-lib/flowy-folder/tests/workspace/script.rs @@ -363,7 +363,7 @@ pub async fn create_view( thumbnail: None, data_format: data_type, layout, - view_content_data: vec![], + initial_data: vec![], }; FolderEventBuilder::new(sdk.clone()) .event(CreateView) diff --git a/frontend/rust-lib/flowy-test/src/helper.rs b/frontend/rust-lib/flowy-test/src/helper.rs index 49d8e43bd4..be94162d54 100644 --- a/frontend/rust-lib/flowy-test/src/helper.rs +++ b/frontend/rust-lib/flowy-test/src/helper.rs @@ -119,7 +119,7 @@ async fn create_view( thumbnail: Some("http://1.png".to_string()), data_format, layout, - view_content_data: data, + initial_data: data, }; FolderEventBuilder::new(sdk.clone())