mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-07 04:20:11 +08:00
chore: move client folders (#948)
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
use bytes::Bytes;
|
||||
use futures::{
|
||||
stream::{self},
|
||||
StreamExt,
|
||||
};
|
||||
|
||||
use ipc_types::blob::{GetBlob, PutBlob};
|
||||
use jwst::BlobStorage;
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn put_blob<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: PutBlob,
|
||||
) -> Result<String, String> {
|
||||
let blob_storage = &state.0.lock().await.blob_storage;
|
||||
if let Ok(path) = blob_storage
|
||||
.put_blob(
|
||||
// TODO: ask octobase to accept blob directly or wrap/await tauri command to create a real stream, so we don't need to construct stream manually
|
||||
parameters.workspace_id,
|
||||
stream::iter::<Vec<Bytes>>(vec![Bytes::from(parameters.blob)]),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(path)
|
||||
} else {
|
||||
Err("Failed to create".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_blob<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: GetBlob,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
let GetBlob { workspace_id, id } = parameters;
|
||||
// TODO: check user permission? Or just assume there will only be one user
|
||||
let blob_storage = &state.0.lock().await.blob_storage;
|
||||
if let Ok(mut file_stream) = blob_storage.get_blob(workspace_id.clone(), id.clone()).await {
|
||||
// Read all of the chunks into a vector.
|
||||
let mut stream_contents = Vec::new();
|
||||
let mut error_message = "".to_string();
|
||||
while let Some(chunk) = file_stream.next().await {
|
||||
match chunk {
|
||||
Ok(chunk_bytes) => stream_contents.extend_from_slice(&chunk_bytes),
|
||||
Err(err) => {
|
||||
error_message = format!(
|
||||
"Failed to read blob file {}/{} from stream, error: {}",
|
||||
workspace_id.clone().unwrap_or_default().to_string(),
|
||||
id,
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if error_message.len() > 0 {
|
||||
return Err(error_message);
|
||||
}
|
||||
Ok(stream_contents)
|
||||
} else {
|
||||
Err(format!(
|
||||
"Failed to read blob file {}/{} ",
|
||||
workspace_id.unwrap_or_default().to_string(),
|
||||
id
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use ipc_types::document::{
|
||||
CreateDocumentParameter, GetDocumentParameter, GetDocumentResponse, YDocumentUpdate,
|
||||
};
|
||||
use jwst::DocStorage;
|
||||
use jwst::Workspace as OctoBaseWorkspace;
|
||||
use lib0::any::Any;
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
#[tauri::command]
|
||||
/// get yDoc created by create_workspace, using same id
|
||||
pub async fn create_doc<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: CreateDocumentParameter,
|
||||
) -> Result<(), String> {
|
||||
let workspace_doc = OctoBaseWorkspace::new(parameters.workspace_id.clone());
|
||||
|
||||
workspace_doc.with_trx(|mut workspace_doc_transaction| {
|
||||
workspace_doc_transaction.set_metadata(
|
||||
"name",
|
||||
Any::String(parameters.workspace_name.clone().into_boxed_str()),
|
||||
);
|
||||
});
|
||||
if let Err(error_message) = &state
|
||||
.0
|
||||
.lock()
|
||||
.await
|
||||
.doc_db
|
||||
.write_doc(parameters.workspace_id.clone(), workspace_doc.doc())
|
||||
.await
|
||||
{
|
||||
Err(format!(
|
||||
"Failed to write_doc during create_workspace with error {}",
|
||||
error_message.to_string()
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
/// get yDoc created by create_workspace, using same id
|
||||
pub async fn get_doc<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: GetDocumentParameter,
|
||||
) -> Result<GetDocumentResponse, String> {
|
||||
// TODO: check user permission
|
||||
let state = &state.0.lock().await;
|
||||
let doc_db = &state.doc_db;
|
||||
|
||||
if let Ok(all_updates_of_workspace) = doc_db.all(¶meters.id).await {
|
||||
let all_updates = all_updates_of_workspace
|
||||
.iter()
|
||||
.map(|model| model.blob.clone())
|
||||
.collect::<Vec<Vec<u8>>>();
|
||||
Ok(GetDocumentResponse {
|
||||
updates: all_updates,
|
||||
})
|
||||
} else {
|
||||
Err(format!(
|
||||
"Failed to get yDoc from workspace {}",
|
||||
parameters.id
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn update_y_document<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: YDocumentUpdate,
|
||||
) -> Result<bool, String> {
|
||||
let state = &state.0.lock().await;
|
||||
let doc_db = &state.doc_db;
|
||||
|
||||
doc_db
|
||||
.replace_with(¶meters.id.clone(), parameters.update)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
use cloud_database::{CreateUser, User};
|
||||
use ipc_types::{document::CreateDocumentParameter, user::GetUserParameters};
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::document::create_doc;
|
||||
|
||||
#[tauri::command]
|
||||
/// create new user and a private workspace
|
||||
pub async fn create_user<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: CreateUser,
|
||||
) -> Result<User, String> {
|
||||
let new_user_result = &state
|
||||
.0
|
||||
.lock()
|
||||
.await
|
||||
.metadata_db
|
||||
.create_user(parameters.clone())
|
||||
.await;
|
||||
match new_user_result {
|
||||
Ok(new_user_option) => match new_user_option {
|
||||
Some((new_user, new_workspace)) => {
|
||||
// a new private workspace is created, we have to create a yDoc for it
|
||||
create_doc(
|
||||
state,
|
||||
CreateDocumentParameter {
|
||||
workspace_id: new_workspace.id.clone(),
|
||||
workspace_name: parameters.name.clone(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
Ok(new_user.clone())
|
||||
}
|
||||
None => Err("User creation failed".to_string()),
|
||||
},
|
||||
Err(error_message) => Err(error_message.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
/// get the only one user in local sqlite
|
||||
pub async fn get_user<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: GetUserParameters,
|
||||
) -> Result<User, String> {
|
||||
let db = &state.0.lock().await.metadata_db;
|
||||
match db.get_user_by_email(¶meters.email).await.ok().unwrap() {
|
||||
Some(user) => Ok(user),
|
||||
None => Err("User not found".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
use ipc_types::{
|
||||
document::CreateDocumentParameter,
|
||||
workspace::{
|
||||
CreateWorkspace, CreateWorkspaceResult, GetWorkspace, GetWorkspaceResult, GetWorkspaces,
|
||||
GetWorkspacesResult, UpdateWorkspace,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::document::create_doc;
|
||||
|
||||
#[tauri::command]
|
||||
/// create yDoc for a workspace
|
||||
pub async fn get_workspaces<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: GetWorkspaces,
|
||||
) -> Result<GetWorkspacesResult, String> {
|
||||
match &state
|
||||
.0
|
||||
.lock()
|
||||
.await
|
||||
.metadata_db
|
||||
.get_user_workspaces(parameters.user_id.to_string())
|
||||
.await
|
||||
{
|
||||
Ok(user_workspaces) => Ok(GetWorkspacesResult {
|
||||
workspaces: user_workspaces.clone(),
|
||||
}),
|
||||
Err(error_message) => Err(error_message.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
/// create yDoc for a workspace
|
||||
pub async fn get_workspace<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: GetWorkspace,
|
||||
) -> Result<GetWorkspaceResult, String> {
|
||||
match &state
|
||||
.0
|
||||
.lock()
|
||||
.await
|
||||
.metadata_db
|
||||
.get_workspace_by_id(parameters.id)
|
||||
.await
|
||||
{
|
||||
Ok(user_workspace_option) => match user_workspace_option {
|
||||
Some(user_workspace) => Ok(GetWorkspaceResult {
|
||||
workspace: user_workspace.clone(),
|
||||
}),
|
||||
None => Err("Get workspace has no result".to_string()),
|
||||
},
|
||||
Err(error_message) => Err(error_message.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
/// create yDoc for a workspace
|
||||
pub async fn create_workspace<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: CreateWorkspace,
|
||||
) -> Result<CreateWorkspaceResult, String> {
|
||||
let new_workspace_result = &state
|
||||
.0
|
||||
.lock()
|
||||
.await
|
||||
.metadata_db
|
||||
.create_normal_workspace(parameters.user_id.to_string())
|
||||
.await;
|
||||
match new_workspace_result {
|
||||
Ok(new_workspace) => {
|
||||
create_doc(
|
||||
state,
|
||||
CreateDocumentParameter {
|
||||
workspace_id: new_workspace.id.clone(),
|
||||
workspace_name: parameters.name.clone(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
Ok(CreateWorkspaceResult {
|
||||
id: new_workspace.id.clone(),
|
||||
name: parameters.name,
|
||||
})
|
||||
}
|
||||
Err(error_message) => Err(format!(
|
||||
"Failed to create_workspace with error {}",
|
||||
error_message.to_string()
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn update_workspace<'s>(
|
||||
state: tauri::State<'s, AppState>,
|
||||
parameters: UpdateWorkspace,
|
||||
) -> Result<bool, String> {
|
||||
// TODO: check user permission
|
||||
// No thing to update now. The avatar is update in YDoc using websocket or yrs.update
|
||||
Ok(true)
|
||||
}
|
||||
Reference in New Issue
Block a user