Ver Fonte

save doc file in user's doc dir

appflowy há 3 anos atrás
pai
commit
7e5c2cc62c

+ 4 - 1
app_flowy/lib/workspace/infrastructure/i_app_impl.dart

@@ -33,7 +33,10 @@ class IAppImpl extends IApp {
       case ViewType.Doc:
         final docRepo = DocRepository(docId: view.id);
         final result = await docRepo.createDoc(name: view.name, desc: "");
-        return result.fold((l) => left(view), (r) => left(view));
+        return result.fold((l) => left(view), (r) {
+          return right(
+              WorkspaceError(code: WorkspaceErrorCode.Unknown, msg: r.msg));
+        });
       default:
         return left(view);
     }

+ 2 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-editor/errors.pbenum.dart

@@ -17,6 +17,7 @@ class EditorErrorCode extends $pb.ProtobufEnum {
   static const EditorErrorCode DocViewIdInvalid = EditorErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocViewIdInvalid');
   static const EditorErrorCode DocDescTooLong = EditorErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocDescTooLong');
   static const EditorErrorCode DocFileError = EditorErrorCode._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocFileError');
+  static const EditorErrorCode EditorUserNotLoginYet = EditorErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EditorUserNotLoginYet');
 
   static const $core.List<EditorErrorCode> values = <EditorErrorCode> [
     Unknown,
@@ -26,6 +27,7 @@ class EditorErrorCode extends $pb.ProtobufEnum {
     DocViewIdInvalid,
     DocDescTooLong,
     DocFileError,
+    EditorUserNotLoginYet,
   ];
 
   static final $core.Map<$core.int, EditorErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);

+ 2 - 1
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-editor/errors.pbjson.dart

@@ -19,11 +19,12 @@ const EditorErrorCode$json = const {
     const {'1': 'DocViewIdInvalid', '2': 11},
     const {'1': 'DocDescTooLong', '2': 12},
     const {'1': 'DocFileError', '2': 13},
+    const {'1': 'EditorUserNotLoginYet', '2': 100},
   ],
 };
 
 /// Descriptor for `EditorErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List editorErrorCodeDescriptor = $convert.base64Decode('Cg9FZGl0b3JFcnJvckNvZGUSCwoHVW5rbm93bhAAEhkKFUVkaXRvckRCSW50ZXJuYWxFcnJvchABEhYKEkVkaXRvckRCQ29ubkZhaWxlZBACEhIKDkRvY05hbWVJbnZhbGlkEAoSFAoQRG9jVmlld0lkSW52YWxpZBALEhIKDkRvY0Rlc2NUb29Mb25nEAwSEAoMRG9jRmlsZUVycm9yEA0=');
+final $typed_data.Uint8List editorErrorCodeDescriptor = $convert.base64Decode('Cg9FZGl0b3JFcnJvckNvZGUSCwoHVW5rbm93bhAAEhkKFUVkaXRvckRCSW50ZXJuYWxFcnJvchABEhYKEkVkaXRvckRCQ29ubkZhaWxlZBACEhIKDkRvY05hbWVJbnZhbGlkEAoSFAoQRG9jVmlld0lkSW52YWxpZBALEhIKDkRvY0Rlc2NUb29Mb25nEAwSEAoMRG9jRmlsZUVycm9yEA0SGQoVRWRpdG9yVXNlck5vdExvZ2luWWV0EGQ=');
 @$core.Deprecated('Use editorErrorDescriptor instead')
 const EditorError$json = const {
   '1': 'EditorError',

+ 3 - 0
rust-lib/flowy-editor/src/errors.rs

@@ -44,6 +44,9 @@ pub enum EditorErrorCode {
 
     #[display(fmt = "DocDescTooLong")]
     DocFileError       = 13,
+
+    #[display(fmt = "EditorUserNotLoginYet")]
+    EditorUserNotLoginYet = 100,
 }
 
 impl std::default::Default for EditorErrorCode {

+ 5 - 1
rust-lib/flowy-editor/src/handlers/doc_handler.rs

@@ -14,7 +14,11 @@ pub async fn create_doc(
     manager: Unit<RwLock<FileManager>>,
 ) -> ResponseResult<DocDescription, EditorError> {
     let params: CreateDocParams = data.into_inner().try_into()?;
-    let path = manager.write().await.create_file(&params.id, &params.text);
+    let dir = manager.read().await.user.user_doc_dir()?;
+    let path = manager
+        .write()
+        .await
+        .create_file(&params.id, &dir, &params.text)?;
     let doc_desc = controller
         .create_doc(params, path.to_str().unwrap())
         .await?;

+ 5 - 13
rust-lib/flowy-editor/src/module.rs

@@ -4,7 +4,7 @@ use crate::{
     handlers::*,
     services::{
         doc_controller::DocController,
-        file_manager::{FileManager, FileManagerConfig},
+        file_manager::{create_dir_if_not_exist, FileManager},
     },
 };
 use flowy_database::DBConnection;
@@ -16,20 +16,12 @@ pub trait EditorDatabase: Send + Sync {
     fn db_connection(&self) -> Result<DBConnection, EditorError>;
 }
 
-pub struct EditorConfig {
-    root: String,
+pub trait EditorUser: Send + Sync {
+    fn user_doc_dir(&self) -> Result<String, EditorError>;
 }
 
-impl EditorConfig {
-    pub fn new(root: &str) -> Self {
-        Self {
-            root: root.to_owned(),
-        }
-    }
-}
-
-pub fn create(database: Arc<dyn EditorDatabase>, config: EditorConfig) -> Module {
-    let file_manager = RwLock::new(FileManager::new(FileManagerConfig::new(&config.root)));
+pub fn create(database: Arc<dyn EditorDatabase>, user: Arc<dyn EditorUser>) -> Module {
+    let file_manager = RwLock::new(FileManager::new(user.clone()));
     let doc_controller = DocController::new(database);
 
     Module::new()

+ 30 - 24
rust-lib/flowy-editor/src/protobuf/model/errors.rs

@@ -222,6 +222,7 @@ pub enum EditorErrorCode {
     DocViewIdInvalid = 11,
     DocDescTooLong = 12,
     DocFileError = 13,
+    EditorUserNotLoginYet = 100,
 }
 
 impl ::protobuf::ProtobufEnum for EditorErrorCode {
@@ -238,6 +239,7 @@ impl ::protobuf::ProtobufEnum for EditorErrorCode {
             11 => ::std::option::Option::Some(EditorErrorCode::DocViewIdInvalid),
             12 => ::std::option::Option::Some(EditorErrorCode::DocDescTooLong),
             13 => ::std::option::Option::Some(EditorErrorCode::DocFileError),
+            100 => ::std::option::Option::Some(EditorErrorCode::EditorUserNotLoginYet),
             _ => ::std::option::Option::None
         }
     }
@@ -251,6 +253,7 @@ impl ::protobuf::ProtobufEnum for EditorErrorCode {
             EditorErrorCode::DocViewIdInvalid,
             EditorErrorCode::DocDescTooLong,
             EditorErrorCode::DocFileError,
+            EditorErrorCode::EditorUserNotLoginYet,
         ];
         values
     }
@@ -281,33 +284,36 @@ impl ::protobuf::reflect::ProtobufValue for EditorErrorCode {
 static file_descriptor_proto_data: &'static [u8] = b"\
     \n\x0cerrors.proto\"E\n\x0bEditorError\x12$\n\x04code\x18\x01\x20\x01(\
     \x0e2\x10.EditorErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\
-    \x03msg*\xa1\x01\n\x0fEditorErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x19\
+    \x03msg*\xbc\x01\n\x0fEditorErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x19\
     \n\x15EditorDBInternalError\x10\x01\x12\x16\n\x12EditorDBConnFailed\x10\
     \x02\x12\x12\n\x0eDocNameInvalid\x10\n\x12\x14\n\x10DocViewIdInvalid\x10\
     \x0b\x12\x12\n\x0eDocDescTooLong\x10\x0c\x12\x10\n\x0cDocFileError\x10\r\
-    J\xcf\x03\n\x06\x12\x04\0\0\x0e\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
-    \n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\
-    \x13\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x1d\n\x0c\n\x05\x04\0\x02\0\
-    \x06\x12\x03\x03\x04\x13\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x14\x18\
-    \n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x1b\x1c\n\x0b\n\x04\x04\0\x02\
-    \x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\
-    \n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\
-    \x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0e\x01\n\n\n\
-    \x03\x05\0\x01\x12\x03\x06\x05\x14\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\
-    \x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\
-    \0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\
-    \x04\x1e\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x19\n\x0c\n\x05\
-    \x05\0\x02\x01\x02\x12\x03\x08\x1c\x1d\n\x0b\n\x04\x05\0\x02\x02\x12\x03\
-    \t\x04\x1b\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x16\n\x0c\n\x05\
-    \x05\0\x02\x02\x02\x12\x03\t\x19\x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\
-    \x04\x18\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x12\n\x0c\n\x05\x05\
-    \0\x02\x03\x02\x12\x03\n\x15\x17\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\
-    \x04\x1a\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x14\n\x0c\n\x05\
-    \x05\0\x02\x04\x02\x12\x03\x0b\x17\x19\n\x0b\n\x04\x05\0\x02\x05\x12\x03\
-    \x0c\x04\x18\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x12\n\x0c\n\
-    \x05\x05\0\x02\x05\x02\x12\x03\x0c\x15\x17\n\x0b\n\x04\x05\0\x02\x06\x12\
-    \x03\r\x04\x16\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x10\n\x0c\n\
-    \x05\x05\0\x02\x06\x02\x12\x03\r\x13\x15b\x06proto3\
+    \x12\x19\n\x15EditorUserNotLoginYet\x10dJ\xf8\x03\n\x06\x12\x04\0\0\x0f\
+    \x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\
+    \x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x13\n\x0b\n\x04\x04\0\x02\0\x12\
+    \x03\x03\x04\x1d\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\x13\n\x0c\n\
+    \x05\x04\0\x02\0\x01\x12\x03\x03\x14\x18\n\x0c\n\x05\x04\0\x02\0\x03\x12\
+    \x03\x03\x1b\x1c\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\
+    \x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\
+    \x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\
+    \n\n\x02\x05\0\x12\x04\x06\0\x0f\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\
+    \x14\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\
+    \x01\x12\x03\x07\x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\x0e\x0f\
+    \n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x1e\n\x0c\n\x05\x05\0\x02\x01\
+    \x01\x12\x03\x08\x04\x19\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x08\x1c\
+    \x1d\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x1b\n\x0c\n\x05\x05\0\x02\
+    \x02\x01\x12\x03\t\x04\x16\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\t\x19\
+    \x1a\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x18\n\x0c\n\x05\x05\0\x02\
+    \x03\x01\x12\x03\n\x04\x12\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\n\x15\
+    \x17\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x1a\n\x0c\n\x05\x05\0\x02\
+    \x04\x01\x12\x03\x0b\x04\x14\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\
+    \x17\x19\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\x18\n\x0c\n\x05\x05\0\
+    \x02\x05\x01\x12\x03\x0c\x04\x12\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\
+    \x0c\x15\x17\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x16\n\x0c\n\x05\x05\
+    \0\x02\x06\x01\x12\x03\r\x04\x10\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\
+    \x13\x15\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x20\n\x0c\n\x05\x05\0\
+    \x02\x07\x01\x12\x03\x0e\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\
+    \x0e\x1c\x1fb\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 0
rust-lib/flowy-editor/src/protobuf/proto/errors.proto

@@ -12,4 +12,5 @@ enum EditorErrorCode {
     DocViewIdInvalid = 11;
     DocDescTooLong = 12;
     DocFileError = 13;
+    EditorUserNotLoginYet = 100;
 }

+ 14 - 21
rust-lib/flowy-editor/src/services/file_manager/manager.rs

@@ -1,33 +1,21 @@
-use crate::services::file_manager::*;
+use crate::{module::EditorUser, services::file_manager::*};
 use std::{
     collections::HashMap,
     io,
     path::{Path, PathBuf},
-    sync::{PoisonError, RwLock, RwLockReadGuard},
+    sync::{Arc, PoisonError, RwLock, RwLockReadGuard},
 };
 
-pub(crate) struct FileManagerConfig {
-    doc_dir: String,
-}
-
-impl FileManagerConfig {
-    pub fn new(root: &str) -> Self {
-        let doc_dir = format!("{}/doc", root);
-        Self { doc_dir }
-    }
-}
-
 pub struct FileManager {
-    config: FileManagerConfig,
+    pub user: Arc<dyn EditorUser>,
     open_files: HashMap<PathBuf, FileId>,
     file_info: HashMap<FileId, FileInfo>,
 }
 
 impl FileManager {
-    pub(crate) fn new(config: FileManagerConfig) -> Self {
-        // let _ = create_dir_if_not_exist(&config.doc_dir)?;
+    pub(crate) fn new(user: Arc<dyn EditorUser>) -> Self {
         Self {
-            config,
+            user,
             open_files: HashMap::new(),
             file_info: HashMap::new(),
         }
@@ -70,12 +58,17 @@ impl FileManager {
         }
     }
 
-    pub(crate) fn create_file(&mut self, id: &str, text: &str) -> PathBuf {
-        let path = PathBuf::from(format!("{}/{}", self.config.doc_dir, id));
+    pub(crate) fn create_file(
+        &mut self,
+        id: &str,
+        dir: &str,
+        text: &str,
+    ) -> Result<PathBuf, FileError> {
+        let path = PathBuf::from(format!("{}/{}", dir, id));
         let file_id: FileId = id.to_owned().into();
         log::info!("Create doc at: {:?}", path);
-        self.save_new(&path, text, &file_id);
-        path
+        let _ = self.save_new(&path, text, &file_id)?;
+        Ok(path)
     }
 
     pub(crate) fn get_info(&self, id: &FileId) -> Option<&FileInfo> { self.file_info.get(id) }

+ 23 - 2
rust-lib/flowy-sdk/src/deps_resolve/editor_deps_impl.rs

@@ -1,10 +1,10 @@
 use flowy_database::DBConnection;
 use flowy_editor::{
     errors::{EditorError, EditorErrorCode, ErrorBuilder},
-    module::EditorDatabase,
+    module::{EditorDatabase, EditorUser},
 };
 use flowy_user::prelude::UserSession;
-use std::sync::Arc;
+use std::{path::Path, sync::Arc};
 
 pub struct EditorDatabaseImpl {
     pub(crate) user_session: Arc<UserSession>,
@@ -19,3 +19,24 @@ impl EditorDatabase for EditorDatabaseImpl {
         })
     }
 }
+
+pub struct EditorUserImpl {
+    pub(crate) user_session: Arc<UserSession>,
+}
+
+impl EditorUser for EditorUserImpl {
+    fn user_doc_dir(&self) -> Result<String, EditorError> {
+        let dir = self.user_session.get_user_dir().map_err(|e| {
+            ErrorBuilder::new(EditorErrorCode::EditorUserNotLoginYet)
+                .error(e)
+                .build()
+        })?;
+
+        let doc_dir = format!("{}/doc", dir);
+        if !Path::new(&doc_dir).exists() {
+            // TODO: Make sure to unwrap? 😁
+            std::fs::create_dir_all(&doc_dir).unwrap();
+        }
+        Ok(doc_dir)
+    }
+}

+ 10 - 3
rust-lib/flowy-sdk/src/module.rs

@@ -3,7 +3,12 @@ use flowy_dispatch::prelude::Module;
 use flowy_editor::prelude::*;
 use flowy_user::prelude::*;
 
-use crate::deps_resolve::{EditorDatabaseImpl, WorkspaceDatabaseImpl, WorkspaceUserImpl};
+use crate::deps_resolve::{
+    EditorDatabaseImpl,
+    EditorUserImpl,
+    WorkspaceDatabaseImpl,
+    WorkspaceUserImpl,
+};
 use std::sync::Arc;
 
 pub struct ModuleConfig {
@@ -28,11 +33,13 @@ pub fn build_modules(config: ModuleConfig, _server: ArcFlowyServer) -> Vec<Modul
     let editor_db = Arc::new(EditorDatabaseImpl {
         user_session: user_session.clone(),
     });
-    let editor_config = EditorConfig::new(&config.root);
+    let editor_user = Arc::new(EditorUserImpl {
+        user_session: user_session.clone(),
+    });
 
     vec![
         flowy_user::module::create(user_session),
         flowy_workspace::module::create(workspace_user_impl, workspace_db),
-        flowy_editor::module::create(editor_db, editor_config),
+        flowy_editor::module::create(editor_db, editor_user),
     ]
 }

+ 5 - 0
rust-lib/flowy-user/src/services/user_session/user_session.rs

@@ -146,6 +146,11 @@ impl UserSession {
         }
     }
 
+    pub fn get_user_dir(&self) -> Result<String, UserError> {
+        let user_id = self.get_user_id()?;
+        Ok(format!("{}/{}", self.config.root_dir, user_id))
+    }
+
     pub fn get_user_id(&self) -> Result<String, UserError> {
         let mut user_id = {
             let read_guard = self.user_id.read().map_err(|e| {