save doc file in user's doc dir

This commit is contained in:
appflowy 2021-07-23 17:30:33 +08:00
parent af1c35de45
commit 7e5c2cc62c
12 changed files with 104 additions and 66 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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',

View File

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

View File

@ -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?;

View File

@ -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()

View File

@ -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;

View File

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

View File

@ -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) }

View File

@ -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)
}
}

View File

@ -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),
]
}

View File

@ -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| {