mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: create read me when user sign up
This commit is contained in:
parent
b4237b1986
commit
1896c79379
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
|
||||
abstract class IDoc {
|
||||
|
@ -4,7 +4,7 @@ import 'dart:typed_data';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:app_flowy/workspace/domain/i_doc.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
|
||||
class IDocImpl extends IDoc {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_query.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
|
||||
|
@ -15,7 +15,8 @@ import 'package:flowy_sdk/ffi.dart' as ffi;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document-infra/protobuf.dart';
|
||||
|
||||
// ignore: unused_import
|
||||
import 'package:flowy_sdk/protobuf/flowy-infra/protobuf.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
|
||||
use crate::service::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
|
||||
use chrono::Utc;
|
||||
use flowy_document_infra::document_default::doc_initial_string;
|
||||
use flowy_document_infra::user_default::doc_initial_string;
|
||||
use flowy_net::errors::ServerError;
|
||||
use flowy_workspace_infra::protobuf::Workspace;
|
||||
use std::convert::TryInto;
|
||||
|
@ -73,10 +73,9 @@ impl ScriptContext {
|
||||
|
||||
async fn open_doc(&mut self) {
|
||||
let flowy_document = self.flowy_test.sdk.flowy_document.clone();
|
||||
let pool = self.client_user_session.db_pool().unwrap();
|
||||
let doc_id = self.doc_id.clone();
|
||||
|
||||
let edit_context = flowy_document.open(DocIdentifier { doc_id }, pool).await.unwrap();
|
||||
let edit_context = flowy_document.open(DocIdentifier { doc_id }).await.unwrap();
|
||||
self.client_edit_context = Some(edit_context);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub mod document_default;
|
||||
pub mod entities;
|
||||
pub mod protobuf;
|
||||
pub mod user_default;
|
||||
pub mod util;
|
||||
|
@ -1,23 +1,25 @@
|
||||
use flowy_ot::core::{Delta, DeltaBuilder};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn doc_initial_delta() -> Delta { DeltaBuilder::new().insert("\n").build() }
|
||||
#[allow(dead_code)]
|
||||
|
||||
#[inline]
|
||||
pub fn doc_initial_string() -> String { doc_initial_delta().to_json() }
|
||||
#[allow(dead_code)]
|
||||
|
||||
#[inline]
|
||||
pub fn doc_initial_bytes() -> Vec<u8> { doc_initial_string().into_bytes() }
|
||||
pub fn initial_read_me() -> Delta {
|
||||
let json = include_str!("READ_ME.json");
|
||||
let delta = Delta::from_json(json).unwrap();
|
||||
delta
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::user_default::initial_read_me;
|
||||
use flowy_ot::core::Delta;
|
||||
|
||||
#[test]
|
||||
fn load_read_me() {
|
||||
let json = include_str!("READ_ME.json");
|
||||
let delta = Delta::from_json(json).unwrap();
|
||||
assert_eq!(delta.to_json(), json);
|
||||
println!("{}", initial_read_me().to_json());
|
||||
}
|
||||
}
|
@ -15,10 +15,12 @@ pub trait DocumentUser: Send + Sync {
|
||||
fn user_dir(&self) -> Result<String, DocError>;
|
||||
fn user_id(&self) -> Result<String, DocError>;
|
||||
fn token(&self) -> Result<String, DocError>;
|
||||
fn db_pool(&self) -> Result<Arc<ConnectionPool>, DocError>;
|
||||
}
|
||||
|
||||
pub struct FlowyDocument {
|
||||
doc_ctrl: Arc<DocController>,
|
||||
user: Arc<dyn DocumentUser>,
|
||||
}
|
||||
|
||||
impl FlowyDocument {
|
||||
@ -28,8 +30,8 @@ impl FlowyDocument {
|
||||
server_config: &ServerConfig,
|
||||
) -> FlowyDocument {
|
||||
let server = construct_doc_server(server_config);
|
||||
let controller = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone()));
|
||||
Self { doc_ctrl: controller }
|
||||
let doc_ctrl = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone()));
|
||||
Self { doc_ctrl, user }
|
||||
}
|
||||
|
||||
pub fn init(&self) -> Result<(), DocError> {
|
||||
@ -42,8 +44,8 @@ impl FlowyDocument {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn open(&self, params: DocIdentifier, pool: Arc<ConnectionPool>) -> Result<Arc<ClientEditDoc>, DocError> {
|
||||
let edit_context = self.doc_ctrl.open(params, pool).await?;
|
||||
pub async fn open(&self, params: DocIdentifier) -> Result<Arc<ClientEditDoc>, DocError> {
|
||||
let edit_context = self.doc_ctrl.open(params, self.user.db_pool()?).await?;
|
||||
Ok(edit_context)
|
||||
}
|
||||
|
||||
@ -65,7 +67,10 @@ impl FlowyDocument {
|
||||
pub async fn apply_doc_delta(&self, params: DocDelta) -> Result<DocDelta, DocError> {
|
||||
// workaround: compare the rust's delta with flutter's delta. Will be removed
|
||||
// very soon
|
||||
let doc = self.doc_ctrl.apply_local_delta(params.clone()).await?;
|
||||
let doc = self
|
||||
.doc_ctrl
|
||||
.apply_local_delta(params.clone(), self.user.db_pool()?)
|
||||
.await?;
|
||||
Ok(doc)
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ impl DocCache {
|
||||
self.inner.insert(doc_id, doc);
|
||||
}
|
||||
|
||||
pub(crate) fn is_opened(&self, doc_id: &str) -> bool { self.inner.get(doc_id).is_some() }
|
||||
pub(crate) fn contains(&self, doc_id: &str) -> bool { self.inner.get(doc_id).is_some() }
|
||||
|
||||
pub(crate) fn get(&self, doc_id: &str) -> Result<Arc<ClientEditDoc>, DocError> {
|
||||
if !self.is_opened(&doc_id) {
|
||||
if !self.contains(&doc_id) {
|
||||
return Err(doc_not_found());
|
||||
}
|
||||
let opened_doc = self.inner.get(doc_id).unwrap();
|
||||
|
@ -47,7 +47,7 @@ impl DocController {
|
||||
params: DocIdentifier,
|
||||
pool: Arc<ConnectionPool>,
|
||||
) -> Result<Arc<ClientEditDoc>, DocError> {
|
||||
if self.cache.is_opened(¶ms.doc_id) == false {
|
||||
if self.cache.contains(¶ms.doc_id) == false {
|
||||
let edit_ctx = self.make_edit_context(¶ms.doc_id, pool.clone()).await?;
|
||||
return Ok(edit_ctx);
|
||||
}
|
||||
@ -74,8 +74,17 @@ impl DocController {
|
||||
// as None e.g.
|
||||
// json : {"retain":7,"attributes":{"bold":null}}
|
||||
// deserialize delta: [ {retain: 7, attributes: {Bold: AttributeValue(None)}} ]
|
||||
#[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.doc_id), err)]
|
||||
pub(crate) async fn apply_local_delta(&self, delta: DocDelta) -> Result<DocDelta, DocError> {
|
||||
#[tracing::instrument(level = "debug", skip(self, delta, db_pool), fields(doc_id = %delta.doc_id), err)]
|
||||
pub(crate) async fn apply_local_delta(
|
||||
&self,
|
||||
delta: DocDelta,
|
||||
db_pool: Arc<ConnectionPool>,
|
||||
) -> Result<DocDelta, DocError> {
|
||||
if !self.cache.contains(&delta.doc_id) {
|
||||
let doc_identifier: DocIdentifier = delta.doc_id.clone().into();
|
||||
let _ = self.open(doc_identifier, db_pool).await?;
|
||||
}
|
||||
|
||||
let edit_doc_ctx = self.cache.get(&delta.doc_id)?;
|
||||
let _ = edit_doc_ctx.composing_local_delta(Bytes::from(delta.data)).await?;
|
||||
Ok(edit_doc_ctx.delta().await?)
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
errors::DocError,
|
||||
services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD},
|
||||
};
|
||||
use flowy_document_infra::document_default::doc_initial_delta;
|
||||
use flowy_document_infra::user_default::doc_initial_delta;
|
||||
use flowy_ot::core::*;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{errors::DocError, services::server::DocumentServerAPI};
|
||||
use flowy_document_infra::{
|
||||
document_default::doc_initial_string,
|
||||
entities::doc::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams},
|
||||
user_default::doc_initial_string,
|
||||
};
|
||||
use flowy_infra::future::ResultFuture;
|
||||
|
||||
|
@ -8,6 +8,7 @@ use flowy_document::{
|
||||
use flowy_user::{errors::ErrorCode, services::user::UserSession};
|
||||
use flowy_ws::{WsMessage, WsMessageHandler, WsModule};
|
||||
|
||||
use flowy_database::ConnectionPool;
|
||||
use flowy_document::services::ws::{DocumentWebSocket, WsDocumentManager};
|
||||
use flowy_user::errors::UserError;
|
||||
use std::{path::Path, sync::Arc};
|
||||
@ -63,6 +64,8 @@ impl DocumentUser for DocumentUserImpl {
|
||||
fn user_id(&self) -> Result<String, DocError> { self.user.user_id().map_err(map_user_error) }
|
||||
|
||||
fn token(&self) -> Result<String, DocError> { self.user.token().map_err(map_user_error) }
|
||||
|
||||
fn db_pool(&self) -> Result<Arc<ConnectionPool>, DocError> { self.user.db_pool().map_err(map_user_error) }
|
||||
}
|
||||
|
||||
struct WsSenderImpl {
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_document_infra::document_default::doc_initial_string;
|
||||
use flowy_document_infra::user_default::doc_initial_string;
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(PartialEq, Debug, ProtoBuf_Enum, Clone)]
|
||||
|
@ -108,7 +108,7 @@ impl ViewController {
|
||||
#[tracing::instrument(level = "debug", skip(self, params), fields(doc_id = %params.doc_id), err)]
|
||||
pub(crate) async fn open_view(&self, params: DocIdentifier) -> Result<DocDelta, WorkspaceError> {
|
||||
let doc_id = params.doc_id.clone();
|
||||
let edit_context = self.document.open(params, self.database.db_pool()?).await?;
|
||||
let edit_context = self.document.open(params).await?;
|
||||
|
||||
KV::set_str(LATEST_VIEW_ID, doc_id);
|
||||
Ok(edit_context.delta().await.map_err(internal_error)?)
|
||||
|
@ -7,6 +7,7 @@ use crate::{
|
||||
};
|
||||
use chrono::Utc;
|
||||
use flowy_database::SqliteConnection;
|
||||
use flowy_document_infra::{entities::doc::DocDelta, user_default::initial_read_me};
|
||||
use flowy_infra::kv::KV;
|
||||
use flowy_workspace_infra::{
|
||||
entities::{app::RepeatedApp, view::View, workspace::*},
|
||||
@ -101,6 +102,13 @@ impl WorkspaceController {
|
||||
let _ = self.app_controller.create_app(app).await?;
|
||||
for (index, view) in views.into_iter().enumerate() {
|
||||
if index == 0 {
|
||||
let delta = initial_read_me();
|
||||
let doc_delta = DocDelta {
|
||||
doc_id: view.id.clone(),
|
||||
data: delta.to_json(),
|
||||
};
|
||||
let _ = self.view_controller.apply_doc_delta(doc_delta).await?;
|
||||
|
||||
self.view_controller.set_latest_view(&view);
|
||||
}
|
||||
let _ = self.view_controller.create_view(view).await?;
|
||||
|
Loading…
Reference in New Issue
Block a user