[flutter]: create read me when user sign up

This commit is contained in:
appflowy 2021-11-13 11:53:50 +08:00
parent b4237b1986
commit 1896c79379
17 changed files with 56 additions and 29 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
pub mod document_default;
pub mod entities;
pub mod protobuf;
pub mod user_default;
pub mod util;

View File

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

View File

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

View File

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

View File

@ -47,7 +47,7 @@ impl DocController {
params: DocIdentifier,
pool: Arc<ConnectionPool>,
) -> Result<Arc<ClientEditDoc>, DocError> {
if self.cache.is_opened(&params.doc_id) == false {
if self.cache.contains(&params.doc_id) == false {
let edit_ctx = self.make_edit_context(&params.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?)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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