[rust]: initialize the workspace when user status changed

This commit is contained in:
appflowy 2021-11-09 13:29:31 +08:00
parent d8fad4a2f3
commit 60bc41dda5
16 changed files with 211 additions and 172 deletions

View File

@ -27,11 +27,7 @@ class UserRepo {
}
Future<Either<Unit, UserError>> initUser() async {
return Future(() async {
final result = await UserEventInitUser().send();
await WorkspaceEventInitWorkspace().send();
return result;
});
return UserEventInitUser().send();
}
Future<Either<List<Workspace>, WorkspaceError>> getWorkspaces() {

View File

@ -395,20 +395,6 @@ class WorkspaceEventApplyDocDelta {
}
}
class WorkspaceEventInitWorkspace {
WorkspaceEventInitWorkspace();
Future<Either<Unit, WorkspaceError>> send() {
final request = FFIRequest.create()
..event = WorkspaceEvent.InitWorkspace.toString();
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
(bytes) => left(unit),
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
));
}
}
class UserEventInitUser {
UserEventInitUser();

View File

@ -16,7 +16,6 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
static const WorkspaceEvent DeleteWorkspace = WorkspaceEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteWorkspace');
static const WorkspaceEvent OpenWorkspace = WorkspaceEvent._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OpenWorkspace');
static const WorkspaceEvent ReadWorkspaceApps = WorkspaceEvent._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadWorkspaceApps');
static const WorkspaceEvent CreateDefaultWorkspace = WorkspaceEvent._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspace');
static const WorkspaceEvent CreateApp = WorkspaceEvent._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateApp');
static const WorkspaceEvent DeleteApp = WorkspaceEvent._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteApp');
static const WorkspaceEvent ReadApp = WorkspaceEvent._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadApp');
@ -35,7 +34,6 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
static const WorkspaceEvent RestoreAll = WorkspaceEvent._(303, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RestoreAll');
static const WorkspaceEvent DeleteAll = WorkspaceEvent._(304, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteAll');
static const WorkspaceEvent ApplyDocDelta = WorkspaceEvent._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplyDocDelta');
static const WorkspaceEvent InitWorkspace = WorkspaceEvent._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InitWorkspace');
static const $core.List<WorkspaceEvent> values = <WorkspaceEvent> [
CreateWorkspace,
@ -44,7 +42,6 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
DeleteWorkspace,
OpenWorkspace,
ReadWorkspaceApps,
CreateDefaultWorkspace,
CreateApp,
DeleteApp,
ReadApp,
@ -63,7 +60,6 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
RestoreAll,
DeleteAll,
ApplyDocDelta,
InitWorkspace,
];
static final $core.Map<$core.int, WorkspaceEvent> _byValue = $pb.ProtobufEnum.initByValue(values);

View File

@ -18,7 +18,6 @@ const WorkspaceEvent$json = const {
const {'1': 'DeleteWorkspace', '2': 3},
const {'1': 'OpenWorkspace', '2': 4},
const {'1': 'ReadWorkspaceApps', '2': 5},
const {'1': 'CreateDefaultWorkspace', '2': 6},
const {'1': 'CreateApp', '2': 101},
const {'1': 'DeleteApp', '2': 102},
const {'1': 'ReadApp', '2': 103},
@ -37,9 +36,8 @@ const WorkspaceEvent$json = const {
const {'1': 'RestoreAll', '2': 303},
const {'1': 'DeleteAll', '2': 304},
const {'1': 'ApplyDocDelta', '2': 400},
const {'1': 'InitWorkspace', '2': 1000},
],
};
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRIaChZDcmVhdGVEZWZhdWx0V29ya3NwYWNlEAYSDQoJQ3JlYXRlQXBwEGUSDQoJRGVsZXRlQXBwEGYSCwoHUmVhZEFwcBBnEg0KCVVwZGF0ZUFwcBBoEg8KCkNyZWF0ZVZpZXcQyQESDQoIUmVhZFZpZXcQygESDwoKVXBkYXRlVmlldxDLARIPCgpEZWxldGVWaWV3EMwBEhIKDUR1cGxpY2F0ZVZpZXcQzQESDQoIQ29weUxpbmsQzgESDQoIT3BlblZpZXcQzwESDgoJQ2xvc2VWaWV3ENABEg4KCVJlYWRUcmFzaBCsAhIRCgxQdXRiYWNrVHJhc2gQrQISEAoLRGVsZXRlVHJhc2gQrgISDwoKUmVzdG9yZUFsbBCvAhIOCglEZWxldGVBbGwQsAISEgoNQXBwbHlEb2NEZWx0YRCQAxISCg1Jbml0V29ya3NwYWNlEOgH');
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARINCghPcGVuVmlldxDPARIOCglDbG9zZVZpZXcQ0AESDgoJUmVhZFRyYXNoEKwCEhEKDFB1dGJhY2tUcmFzaBCtAhIQCgtEZWxldGVUcmFzaBCuAhIPCgpSZXN0b3JlQWxsEK8CEg4KCURlbGV0ZUFsbBCwAhISCg1BcHBseURvY0RlbHRhEJAD');

View File

@ -1,5 +1,5 @@
use anyhow::Context;
use chrono::Utc;
use sqlx::{PgPool, Postgres};
use flowy_net::{

View File

@ -4,21 +4,35 @@ use diesel::{Connection, SqliteConnection};
use flowy_derive::ProtoBuf;
use flowy_sqlite::{DBConnection, Database, PoolConfig};
use lazy_static::lazy_static;
use std::{path::Path, sync::RwLock};
use std::{
collections::HashMap,
path::Path,
sync::{PoisonError, RwLock, RwLockWriteGuard},
};
const DB_NAME: &str = "kv.db";
lazy_static! {
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV { database: None });
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
}
pub struct KV {
database: Option<Database>,
cache: HashMap<String, KeyValue>,
}
impl KV {
fn set(item: KeyValue) -> Result<(), String> {
fn new() -> Self {
KV {
database: None,
cache: HashMap::new(),
}
}
fn set(value: KeyValue) -> Result<(), String> {
update_cache(value.clone());
let _ = diesel::replace_into(kv_table::table)
.values(&item)
.values(&value)
.execute(&*(get_connection()?))
.map_err(|e| format!("KV set error: {:?}", e))?;
@ -26,16 +40,30 @@ impl KV {
}
fn get(key: &str) -> Result<KeyValue, String> {
if let Some(value) = read_cache(key) {
return Ok(value);
}
let conn = get_connection()?;
let item = dsl::kv_table
let value = dsl::kv_table
.filter(kv_table::key.eq(key))
.first::<KeyValue>(&*conn)
.map_err(|e| format!("KV get error: {:?}", e))?;
Ok(item)
update_cache(value.clone());
Ok(value)
}
#[allow(dead_code)]
pub fn remove(key: &str) -> Result<(), String> {
match KV_HOLDER.write() {
Ok(mut guard) => {
guard.cache.remove(key);
},
Err(e) => log::error!("Require write lock failed: {:?}", e),
};
let conn = get_connection()?;
let sql = dsl::kv_table.filter(kv_table::key.eq(key));
let _ = diesel::delete(sql)
@ -63,6 +91,25 @@ impl KV {
}
}
fn read_cache(key: &str) -> Option<KeyValue> {
match KV_HOLDER.read() {
Ok(guard) => guard.cache.get(key).cloned(),
Err(e) => {
log::error!("Require read lock failed: {:?}", e);
None
},
}
}
fn update_cache(value: KeyValue) {
match KV_HOLDER.write() {
Ok(mut guard) => {
guard.cache.insert(value.key.clone(), value);
},
Err(e) => log::error!("Require write lock failed: {:?}", e),
};
}
macro_rules! impl_get_func {
(
$func_name:ident,

View File

@ -6,11 +6,8 @@ use crate::deps_resolve::WorkspaceDepsResolver;
use flowy_dispatch::prelude::*;
use flowy_document::prelude::FlowyDocument;
use flowy_net::config::ServerConfig;
use flowy_user::{
entities::UserStatus,
services::user::{UserSession, UserSessionBuilder},
};
use flowy_workspace::prelude::WorkspaceController;
use flowy_user::services::user::{UserSession, UserSessionBuilder, UserStatus};
use flowy_workspace::{errors::WorkspaceError, prelude::WorkspaceController};
use module::mk_modules;
pub use module::*;
use std::sync::{
@ -53,7 +50,8 @@ fn crate_log_filter(level: Option<String>) -> String {
filters.push(format!("flowy_dart_notify={}", level));
filters.push(format!("flowy_ot={}", level));
filters.push(format!("flowy_ws={}", level));
filters.push(format!("info"));
filters.push(format!("flowy_ws={}", level));
filters.push(format!("flowy_infra={}", level));
filters.join(",")
}
@ -81,9 +79,7 @@ impl FlowySDK {
let workspace = mk_workspace(user_session.clone(), flowy_document.clone(), &config.server_config);
let modules = mk_modules(workspace.clone(), user_session.clone());
let dispatch = Arc::new(EventDispatch::construct(|| modules));
let subscribe = user_session.status_subscribe();
listen_on_user_status_changed(&dispatch, subscribe, workspace.clone());
_init(&dispatch, user_session.clone(), workspace.clone());
Self {
config,
@ -97,30 +93,47 @@ impl FlowySDK {
pub fn dispatch(&self) -> Arc<EventDispatch> { self.dispatch.clone() }
}
fn listen_on_user_status_changed(
dispatch: &EventDispatch,
fn _init(dispatch: &EventDispatch, user_session: Arc<UserSession>, workspace_controller: Arc<WorkspaceController>) {
let subscribe = user_session.status_subscribe();
dispatch.spawn(async move {
user_session.init();
_listen_user_status(subscribe, workspace_controller).await;
});
}
async fn _listen_user_status(
mut subscribe: broadcast::Receiver<UserStatus>,
workspace_controller: Arc<WorkspaceController>,
) {
dispatch.spawn(async move {
//
loop {
match subscribe.recv().await {
Ok(status) => match status {
UserStatus::Login { .. } => {
workspace_controller.user_did_login();
},
UserStatus::Expired { .. } => {
workspace_controller.user_session_expired();
},
UserStatus::SignUp { .. } => {
let _ = workspace_controller.user_did_sign_up().await;
},
},
Err(_) => {},
}
loop {
match subscribe.recv().await {
Ok(status) => {
let result = || async {
match status {
UserStatus::Login { .. } => {
let _ = workspace_controller.user_did_login()?;
},
UserStatus::Logout { .. } => {
workspace_controller.user_did_logout();
},
UserStatus::Expired { .. } => {
workspace_controller.user_session_expired();
},
UserStatus::SignUp { .. } => {
let _ = workspace_controller.user_did_sign_up().await?;
},
}
Ok::<(), WorkspaceError>(())
};
match result().await {
Ok(_) => {},
Err(e) => log::error!("{}", e),
}
},
Err(_) => {},
}
});
}
}
fn init_kv(root: &str) {

View File

@ -6,13 +6,6 @@ use crate::{
parser::{UserEmail, UserId, UserName, UserPassword},
};
#[derive(Clone)]
pub enum UserStatus {
Login { token: String },
Expired { token: String },
SignUp { profile: UserProfile },
}
#[derive(Default, ProtoBuf)]
pub struct UserToken {
#[pb(index = 1)]

View File

@ -1,6 +1,5 @@
use crate::services::user::{UserSession, UserSessionConfig};
use flowy_net::config::ServerConfig;
use std::sync::Arc;
pub struct UserSessionBuilder {
config: Option<UserSessionConfig>,

View File

@ -19,13 +19,20 @@ use flowy_database::{
use flowy_infra::kv::KV;
use flowy_net::config::ServerConfig;
use flowy_sqlite::ConnectionPool;
use flowy_user_infra::entities::UserStatus;
use flowy_ws::{WsController, WsMessageHandler, WsState};
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::broadcast;
#[derive(Clone)]
pub enum UserStatus {
Login { token: String },
Logout { token: String },
Expired { token: String },
SignUp { profile: UserProfile },
}
pub struct UserSessionConfig {
root_dir: String,
server_config: ServerConfig,
@ -67,6 +74,16 @@ impl UserSession {
user_session
}
pub fn init(&self) {
log::debug!("😁😁😁 user did login");
match self.get_session() {
Ok(session) => {
let _ = self.status_notifier.send(UserStatus::Login { token: session.token });
},
Err(_) => {},
}
}
pub fn status_subscribe(&self) -> broadcast::Receiver<UserStatus> { self.status_notifier.subscribe() }
pub fn db_connection(&self) -> Result<DBConnection, UserError> {
@ -126,7 +143,7 @@ impl UserSession {
diesel::delete(dsl::user_table.filter(dsl::id.eq(&session.user_id))).execute(&*(self.db_connection()?))?;
let _ = self.database.close_user_db(&session.user_id)?;
let _ = self.set_session(None)?;
let _ = self.status_notifier.send(UserStatus::Expired {
let _ = self.status_notifier.send(UserStatus::Logout {
token: session.token.clone(),
});
let _ = self.sign_out_on_server(&session.token).await?;

View File

@ -75,7 +75,4 @@ pub enum WorkspaceEvent {
#[event(input = "DocDelta", output = "DocDelta")]
ApplyDocDelta = 400,
#[event()]
InitWorkspace = 1000,
}

View File

@ -1,20 +1,8 @@
use crate::{
errors::WorkspaceError,
services::{AppController, ViewController, WorkspaceController},
};
use chrono::Utc;
use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
use flowy_workspace_infra::{
entities::{app::RepeatedApp, workspace::*},
user_default,
};
use std::{convert::TryInto, sync::Arc};
use crate::{errors::WorkspaceError, services::WorkspaceController};
#[tracing::instrument(skip(controller), err)]
pub(crate) async fn init_workspace_handler(controller: Unit<Arc<WorkspaceController>>) -> Result<(), WorkspaceError> {
let _ = controller.init()?;
Ok(())
}
use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
use flowy_workspace_infra::entities::{app::RepeatedApp, workspace::*};
use std::{convert::TryInto, sync::Arc};
#[tracing::instrument(skip(data, controller), err)]
pub(crate) async fn create_workspace_handler(

View File

@ -70,8 +70,7 @@ pub fn create(workspace: Arc<WorkspaceController>) -> Module {
.data(workspace.clone())
.data(workspace.app_controller.clone())
.data(workspace.view_controller.clone())
.data(workspace.trash_can.clone())
.event(WorkspaceEvent::InitWorkspace, init_workspace_handler);
.data(workspace.trash_can.clone());
module = module
.event(WorkspaceEvent::CreateWorkspace, create_workspace_handler)

View File

@ -31,7 +31,6 @@ pub enum WorkspaceEvent {
DeleteWorkspace = 3,
OpenWorkspace = 4,
ReadWorkspaceApps = 5,
CreateDefaultWorkspace = 6,
CreateApp = 101,
DeleteApp = 102,
ReadApp = 103,
@ -50,7 +49,6 @@ pub enum WorkspaceEvent {
RestoreAll = 303,
DeleteAll = 304,
ApplyDocDelta = 400,
InitWorkspace = 1000,
}
impl ::protobuf::ProtobufEnum for WorkspaceEvent {
@ -66,7 +64,6 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
3 => ::std::option::Option::Some(WorkspaceEvent::DeleteWorkspace),
4 => ::std::option::Option::Some(WorkspaceEvent::OpenWorkspace),
5 => ::std::option::Option::Some(WorkspaceEvent::ReadWorkspaceApps),
6 => ::std::option::Option::Some(WorkspaceEvent::CreateDefaultWorkspace),
101 => ::std::option::Option::Some(WorkspaceEvent::CreateApp),
102 => ::std::option::Option::Some(WorkspaceEvent::DeleteApp),
103 => ::std::option::Option::Some(WorkspaceEvent::ReadApp),
@ -85,7 +82,6 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
303 => ::std::option::Option::Some(WorkspaceEvent::RestoreAll),
304 => ::std::option::Option::Some(WorkspaceEvent::DeleteAll),
400 => ::std::option::Option::Some(WorkspaceEvent::ApplyDocDelta),
1000 => ::std::option::Option::Some(WorkspaceEvent::InitWorkspace),
_ => ::std::option::Option::None
}
}
@ -98,7 +94,6 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
WorkspaceEvent::DeleteWorkspace,
WorkspaceEvent::OpenWorkspace,
WorkspaceEvent::ReadWorkspaceApps,
WorkspaceEvent::CreateDefaultWorkspace,
WorkspaceEvent::CreateApp,
WorkspaceEvent::DeleteApp,
WorkspaceEvent::ReadApp,
@ -117,7 +112,6 @@ impl ::protobuf::ProtobufEnum for WorkspaceEvent {
WorkspaceEvent::RestoreAll,
WorkspaceEvent::DeleteAll,
WorkspaceEvent::ApplyDocDelta,
WorkspaceEvent::InitWorkspace,
];
values
}
@ -146,74 +140,69 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceEvent {
}
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0bevent.proto*\xe6\x03\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorksp\
\n\x0bevent.proto*\xb6\x03\n\x0eWorkspaceEvent\x12\x13\n\x0fCreateWorksp\
ace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorkspa\
ces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspac\
e\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\x1a\n\x16CreateDefa\
ultWorkspace\x10\x06\x12\r\n\tCreateApp\x10e\x12\r\n\tDeleteApp\x10f\x12\
\x0b\n\x07ReadApp\x10g\x12\r\n\tUpdateApp\x10h\x12\x0f\n\nCreateView\x10\
\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\x12\x0f\n\nUpdateView\x10\xcb\
\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\x12\n\rDuplicateView\x10\xcd\
\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\r\n\x08OpenView\x10\xcf\x01\x12\
\x0e\n\tCloseView\x10\xd0\x01\x12\x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\
\x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0bDeleteTrash\x10\xae\x02\x12\
\x0f\n\nRestoreAll\x10\xaf\x02\x12\x0e\n\tDeleteAll\x10\xb0\x02\x12\x12\
\n\rApplyDocDelta\x10\x90\x03\x12\x12\n\rInitWorkspace\x10\xe8\x07J\xd4\
\x08\n\x06\x12\x04\0\0\x1d\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
\x05\0\x12\x04\x02\0\x1d\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\
\x12\x03\x03\x04\x13\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\
\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x19\n\x0c\n\x05\x05\0\x02\x01\
\x01\x12\x03\x04\x04\x14\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\x17\
\x18\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x17\n\x0c\n\x05\x05\0\x02\
\x02\x01\x12\x03\x05\x04\x12\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\
\x15\x16\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x18\n\x0c\n\x05\x05\0\
\x02\x03\x01\x12\x03\x06\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\
\x06\x16\x17\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x16\n\x0c\n\x05\
\x05\0\x02\x04\x01\x12\x03\x07\x04\x11\n\x0c\n\x05\x05\0\x02\x04\x02\x12\
\x03\x07\x14\x15\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04\x1a\n\x0c\n\
\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\x15\n\x0c\n\x05\x05\0\x02\x05\x02\
\x12\x03\x08\x18\x19\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x1f\n\x0c\n\
\x05\x05\0\x02\x06\x01\x12\x03\t\x04\x1a\n\x0c\n\x05\x05\0\x02\x06\x02\
\x12\x03\t\x1d\x1e\n\x0b\n\x04\x05\0\x02\x07\x12\x03\n\x04\x14\n\x0c\n\
\x05\x05\0\x02\x07\x01\x12\x03\n\x04\r\n\x0c\n\x05\x05\0\x02\x07\x02\x12\
\x03\n\x10\x13\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0b\x04\x14\n\x0c\n\x05\
\x05\0\x02\x08\x01\x12\x03\x0b\x04\r\n\x0c\n\x05\x05\0\x02\x08\x02\x12\
\x03\x0b\x10\x13\n\x0b\n\x04\x05\0\x02\t\x12\x03\x0c\x04\x12\n\x0c\n\x05\
\x05\0\x02\t\x01\x12\x03\x0c\x04\x0b\n\x0c\n\x05\x05\0\x02\t\x02\x12\x03\
\x0c\x0e\x11\n\x0b\n\x04\x05\0\x02\n\x12\x03\r\x04\x14\n\x0c\n\x05\x05\0\
\x02\n\x01\x12\x03\r\x04\r\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x10\x13\
\n\x0b\n\x04\x05\0\x02\x0b\x12\x03\x0e\x04\x15\n\x0c\n\x05\x05\0\x02\x0b\
\x01\x12\x03\x0e\x04\x0e\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x0e\x11\
\x14\n\x0b\n\x04\x05\0\x02\x0c\x12\x03\x0f\x04\x13\n\x0c\n\x05\x05\0\x02\
\x0c\x01\x12\x03\x0f\x04\x0c\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x0f\
\x0f\x12\n\x0b\n\x04\x05\0\x02\r\x12\x03\x10\x04\x15\n\x0c\n\x05\x05\0\
\x02\r\x01\x12\x03\x10\x04\x0e\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x10\
\x11\x14\n\x0b\n\x04\x05\0\x02\x0e\x12\x03\x11\x04\x15\n\x0c\n\x05\x05\0\
\x02\x0e\x01\x12\x03\x11\x04\x0e\n\x0c\n\x05\x05\0\x02\x0e\x02\x12\x03\
\x11\x11\x14\n\x0b\n\x04\x05\0\x02\x0f\x12\x03\x12\x04\x18\n\x0c\n\x05\
\x05\0\x02\x0f\x01\x12\x03\x12\x04\x11\n\x0c\n\x05\x05\0\x02\x0f\x02\x12\
\x03\x12\x14\x17\n\x0b\n\x04\x05\0\x02\x10\x12\x03\x13\x04\x13\n\x0c\n\
\x05\x05\0\x02\x10\x01\x12\x03\x13\x04\x0c\n\x0c\n\x05\x05\0\x02\x10\x02\
\x12\x03\x13\x0f\x12\n\x0b\n\x04\x05\0\x02\x11\x12\x03\x14\x04\x13\n\x0c\
\n\x05\x05\0\x02\x11\x01\x12\x03\x14\x04\x0c\n\x0c\n\x05\x05\0\x02\x11\
\x02\x12\x03\x14\x0f\x12\n\x0b\n\x04\x05\0\x02\x12\x12\x03\x15\x04\x14\n\
\x0c\n\x05\x05\0\x02\x12\x01\x12\x03\x15\x04\r\n\x0c\n\x05\x05\0\x02\x12\
\x02\x12\x03\x15\x10\x13\n\x0b\n\x04\x05\0\x02\x13\x12\x03\x16\x04\x14\n\
\x0c\n\x05\x05\0\x02\x13\x01\x12\x03\x16\x04\r\n\x0c\n\x05\x05\0\x02\x13\
\x02\x12\x03\x16\x10\x13\n\x0b\n\x04\x05\0\x02\x14\x12\x03\x17\x04\x17\n\
\x0c\n\x05\x05\0\x02\x14\x01\x12\x03\x17\x04\x10\n\x0c\n\x05\x05\0\x02\
\x14\x02\x12\x03\x17\x13\x16\n\x0b\n\x04\x05\0\x02\x15\x12\x03\x18\x04\
\x16\n\x0c\n\x05\x05\0\x02\x15\x01\x12\x03\x18\x04\x0f\n\x0c\n\x05\x05\0\
\x02\x15\x02\x12\x03\x18\x12\x15\n\x0b\n\x04\x05\0\x02\x16\x12\x03\x19\
\x04\x15\n\x0c\n\x05\x05\0\x02\x16\x01\x12\x03\x19\x04\x0e\n\x0c\n\x05\
\x05\0\x02\x16\x02\x12\x03\x19\x11\x14\n\x0b\n\x04\x05\0\x02\x17\x12\x03\
\x1a\x04\x14\n\x0c\n\x05\x05\0\x02\x17\x01\x12\x03\x1a\x04\r\n\x0c\n\x05\
\x05\0\x02\x17\x02\x12\x03\x1a\x10\x13\n\x0b\n\x04\x05\0\x02\x18\x12\x03\
\x1b\x04\x18\n\x0c\n\x05\x05\0\x02\x18\x01\x12\x03\x1b\x04\x11\n\x0c\n\
\x05\x05\0\x02\x18\x02\x12\x03\x1b\x14\x17\n\x0b\n\x04\x05\0\x02\x19\x12\
\x03\x1c\x04\x19\n\x0c\n\x05\x05\0\x02\x19\x01\x12\x03\x1c\x04\x11\n\x0c\
\n\x05\x05\0\x02\x19\x02\x12\x03\x1c\x14\x18b\x06proto3\
e\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\r\n\tCreateApp\x10e\
\x12\r\n\tDeleteApp\x10f\x12\x0b\n\x07ReadApp\x10g\x12\r\n\tUpdateApp\
\x10h\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\
\x12\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\
\x12\n\rDuplicateView\x10\xcd\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\r\
\n\x08OpenView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\x0e\n\tR\
eadTrash\x10\xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0b\
DeleteTrash\x10\xae\x02\x12\x0f\n\nRestoreAll\x10\xaf\x02\x12\x0e\n\tDel\
eteAll\x10\xb0\x02\x12\x12\n\rApplyDocDelta\x10\x90\x03J\x82\x08\n\x06\
\x12\x04\0\0\x1b\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\
\x04\x02\0\x1b\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x13\n\x0b\n\x04\
\x05\0\x02\0\x12\x03\x03\x04\x18\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x03\
\x04\x13\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x16\x17\n\x0b\n\x04\x05\
\0\x02\x01\x12\x03\x04\x04\x19\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x04\
\x04\x14\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\x17\x18\n\x0b\n\x04\
\x05\0\x02\x02\x12\x03\x05\x04\x17\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\
\x05\x04\x12\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\x15\x16\n\x0b\n\
\x04\x05\0\x02\x03\x12\x03\x06\x04\x18\n\x0c\n\x05\x05\0\x02\x03\x01\x12\
\x03\x06\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x16\x17\n\x0b\
\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x16\n\x0c\n\x05\x05\0\x02\x04\x01\
\x12\x03\x07\x04\x11\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x07\x14\x15\n\
\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04\x1a\n\x0c\n\x05\x05\0\x02\x05\
\x01\x12\x03\x08\x04\x15\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x08\x18\
\x19\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x14\n\x0c\n\x05\x05\0\x02\
\x06\x01\x12\x03\t\x04\r\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\t\x10\x13\
\n\x0b\n\x04\x05\0\x02\x07\x12\x03\n\x04\x14\n\x0c\n\x05\x05\0\x02\x07\
\x01\x12\x03\n\x04\r\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\n\x10\x13\n\
\x0b\n\x04\x05\0\x02\x08\x12\x03\x0b\x04\x12\n\x0c\n\x05\x05\0\x02\x08\
\x01\x12\x03\x0b\x04\x0b\n\x0c\n\x05\x05\0\x02\x08\x02\x12\x03\x0b\x0e\
\x11\n\x0b\n\x04\x05\0\x02\t\x12\x03\x0c\x04\x14\n\x0c\n\x05\x05\0\x02\t\
\x01\x12\x03\x0c\x04\r\n\x0c\n\x05\x05\0\x02\t\x02\x12\x03\x0c\x10\x13\n\
\x0b\n\x04\x05\0\x02\n\x12\x03\r\x04\x15\n\x0c\n\x05\x05\0\x02\n\x01\x12\
\x03\r\x04\x0e\n\x0c\n\x05\x05\0\x02\n\x02\x12\x03\r\x11\x14\n\x0b\n\x04\
\x05\0\x02\x0b\x12\x03\x0e\x04\x13\n\x0c\n\x05\x05\0\x02\x0b\x01\x12\x03\
\x0e\x04\x0c\n\x0c\n\x05\x05\0\x02\x0b\x02\x12\x03\x0e\x0f\x12\n\x0b\n\
\x04\x05\0\x02\x0c\x12\x03\x0f\x04\x15\n\x0c\n\x05\x05\0\x02\x0c\x01\x12\
\x03\x0f\x04\x0e\n\x0c\n\x05\x05\0\x02\x0c\x02\x12\x03\x0f\x11\x14\n\x0b\
\n\x04\x05\0\x02\r\x12\x03\x10\x04\x15\n\x0c\n\x05\x05\0\x02\r\x01\x12\
\x03\x10\x04\x0e\n\x0c\n\x05\x05\0\x02\r\x02\x12\x03\x10\x11\x14\n\x0b\n\
\x04\x05\0\x02\x0e\x12\x03\x11\x04\x18\n\x0c\n\x05\x05\0\x02\x0e\x01\x12\
\x03\x11\x04\x11\n\x0c\n\x05\x05\0\x02\x0e\x02\x12\x03\x11\x14\x17\n\x0b\
\n\x04\x05\0\x02\x0f\x12\x03\x12\x04\x13\n\x0c\n\x05\x05\0\x02\x0f\x01\
\x12\x03\x12\x04\x0c\n\x0c\n\x05\x05\0\x02\x0f\x02\x12\x03\x12\x0f\x12\n\
\x0b\n\x04\x05\0\x02\x10\x12\x03\x13\x04\x13\n\x0c\n\x05\x05\0\x02\x10\
\x01\x12\x03\x13\x04\x0c\n\x0c\n\x05\x05\0\x02\x10\x02\x12\x03\x13\x0f\
\x12\n\x0b\n\x04\x05\0\x02\x11\x12\x03\x14\x04\x14\n\x0c\n\x05\x05\0\x02\
\x11\x01\x12\x03\x14\x04\r\n\x0c\n\x05\x05\0\x02\x11\x02\x12\x03\x14\x10\
\x13\n\x0b\n\x04\x05\0\x02\x12\x12\x03\x15\x04\x14\n\x0c\n\x05\x05\0\x02\
\x12\x01\x12\x03\x15\x04\r\n\x0c\n\x05\x05\0\x02\x12\x02\x12\x03\x15\x10\
\x13\n\x0b\n\x04\x05\0\x02\x13\x12\x03\x16\x04\x17\n\x0c\n\x05\x05\0\x02\
\x13\x01\x12\x03\x16\x04\x10\n\x0c\n\x05\x05\0\x02\x13\x02\x12\x03\x16\
\x13\x16\n\x0b\n\x04\x05\0\x02\x14\x12\x03\x17\x04\x16\n\x0c\n\x05\x05\0\
\x02\x14\x01\x12\x03\x17\x04\x0f\n\x0c\n\x05\x05\0\x02\x14\x02\x12\x03\
\x17\x12\x15\n\x0b\n\x04\x05\0\x02\x15\x12\x03\x18\x04\x15\n\x0c\n\x05\
\x05\0\x02\x15\x01\x12\x03\x18\x04\x0e\n\x0c\n\x05\x05\0\x02\x15\x02\x12\
\x03\x18\x11\x14\n\x0b\n\x04\x05\0\x02\x16\x12\x03\x19\x04\x14\n\x0c\n\
\x05\x05\0\x02\x16\x01\x12\x03\x19\x04\r\n\x0c\n\x05\x05\0\x02\x16\x02\
\x12\x03\x19\x10\x13\n\x0b\n\x04\x05\0\x02\x17\x12\x03\x1a\x04\x18\n\x0c\
\n\x05\x05\0\x02\x17\x01\x12\x03\x1a\x04\x11\n\x0c\n\x05\x05\0\x02\x17\
\x02\x12\x03\x1a\x14\x17b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -7,7 +7,6 @@ enum WorkspaceEvent {
DeleteWorkspace = 3;
OpenWorkspace = 4;
ReadWorkspaceApps = 5;
CreateDefaultWorkspace = 6;
CreateApp = 101;
DeleteApp = 102;
ReadApp = 103;
@ -26,5 +25,4 @@ enum WorkspaceEvent {
RestoreAll = 303;
DeleteAll = 304;
ApplyDocDelta = 400;
InitWorkspace = 1000;
}

View File

@ -12,7 +12,12 @@ use flowy_workspace_infra::{
entities::{app::RepeatedApp, workspace::*},
user_default,
};
use std::sync::Arc;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
static INIT_WORKSPACE: AtomicBool = AtomicBool::new(false);
pub struct WorkspaceController {
pub user: Arc<dyn WorkspaceUser>,
@ -45,7 +50,13 @@ impl WorkspaceController {
}
}
pub fn init(&self) -> Result<(), WorkspaceError> {
fn init(&self) -> Result<(), WorkspaceError> {
if INIT_WORKSPACE.load(Ordering::SeqCst) {
return Ok(());
}
log::debug!("workspace initialize");
INIT_WORKSPACE.store(true, Ordering::SeqCst);
let _ = self.server.init();
let _ = self.trash_can.init()?;
let _ = self.view_controller.init()?;
@ -54,9 +65,19 @@ impl WorkspaceController {
Ok(())
}
pub fn user_did_login(&self) {}
pub fn user_did_login(&self) -> WorkspaceResult<()> {
// TODO: (nathan) do something here
let _ = self.init()?;
Ok(())
}
pub fn user_session_expired(&self) {}
pub fn user_did_logout(&self) {
// TODO: (nathan) do something here
}
pub fn user_session_expired(&self) {
// TODO: (nathan) do something here
}
pub async fn user_did_sign_up(&self) -> WorkspaceResult<()> {
log::debug!("Create user default workspace");
@ -78,9 +99,11 @@ impl WorkspaceController {
let repeated_workspace = RepeatedWorkspace {
items: vec![cloned_workspace],
};
send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace)
.payload(repeated_workspace)
.send();
let _ = self.init()?;
Ok(())
}
@ -347,7 +370,7 @@ impl WorkspaceController {
const CURRENT_WORKSPACE_ID: &str = "current_workspace_id";
fn set_current_workspace(workspace: &str) { KV::set_str(CURRENT_WORKSPACE_ID, workspace.to_owned()); }
fn set_current_workspace(workspace_id: &str) { KV::set_str(CURRENT_WORKSPACE_ID, workspace_id.to_owned()); }
fn get_current_workspace() -> Result<String, WorkspaceError> {
match KV::get_str(CURRENT_WORKSPACE_ID) {