chore: listen backend notification from Tauri (#1743)

This commit is contained in:
Nathan.fooo
2023-01-27 17:17:51 +08:00
committed by GitHub
parent 243a781b6c
commit 7a750e5255
27 changed files with 237 additions and 58 deletions

View File

@ -106,6 +106,16 @@
"preLaunchTask": "AF: Tauri UI Dev", "preLaunchTask": "AF: Tauri UI Dev",
"cwd": "${workspaceRoot}/appflowy_tauri/" "cwd": "${workspaceRoot}/appflowy_tauri/"
}, },
// {
// "type": "lldb",
// "request": "launch",
// "name": "AF-tauri: Production Debug",
// "cargo": {
// "args": ["build", "--release", "--manifest-path=./appflowy_tauri/src-tauri/Cargo.toml"]
// },
// "preLaunchTask": "AF: Tauri UI Build",
// "cwd": "${workspaceRoot}/appflowy_tauri/"
// },
{ {
"name": "AF: Debug Rust", "name": "AF: Debug Rust",
"request": "attach", "request": "attach",

View File

@ -9,6 +9,16 @@
"editor.tabCompletion": "onlySnippets", "editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false, "editor.wordBasedSuggestions": false,
}, },
"[javascript]": {
"editor.formatOnSave": true,
"editor.rulers": [80],
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.formatOnSave": true,
"editor.rulers": [80],
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"svgviewer.enableautopreview": true, "svgviewer.enableautopreview": true,
"svgviewer.previewcolumn": "Active", "svgviewer.previewcolumn": "Active",
"svgviewer.showzoominout": true, "svgviewer.showzoominout": true,

View File

@ -190,7 +190,16 @@
"label": "AF: Tauri UI Dev", "label": "AF: Tauri UI Dev",
"type": "shell", "type": "shell",
"isBackground": true, "isBackground": true,
"command": "yarn dev", "command": "npm run dev",
"problemMatcher": ["$tsc"],
"options": {
"cwd": "${workspaceFolder}/appflowy_tauri"
}
},
{
"label": "AF: Tauri UI Build",
"type": "shell",
"command": "npm run build",
"problemMatcher": ["$tsc"], "problemMatcher": ["$tsc"],
"options": { "options": {
"cwd": "${workspaceFolder}/appflowy_tauri" "cwd": "${workspaceFolder}/appflowy_tauri"

View File

@ -29,9 +29,10 @@ fn main() {
}); });
}) })
.setup(|app| { .setup(|app| {
let window = app.get_window("main").unwrap(); if cfg!(debug_assertions) {
#[cfg(debug_assertions)] let window = app.get_window("main").unwrap();
window.open_devtools(); window.open_devtools();
}
Ok(()) Ok(())
}) })
.run(tauri::generate_context!()) .run(tauri::generate_context!())

View File

@ -5,7 +5,6 @@ use tauri::{AppHandle, Event, Manager, Wry};
#[allow(dead_code)] #[allow(dead_code)]
pub const AF_EVENT: &str = "af-event"; pub const AF_EVENT: &str = "af-event";
#[allow(dead_code)]
pub const AF_NOTIFICATION: &str = "af-notification"; pub const AF_NOTIFICATION: &str = "af-notification";
#[tracing::instrument(level = "trace")] #[tracing::instrument(level = "trace")]

View File

@ -4,25 +4,33 @@ import {
SignInPayloadPB, SignInPayloadPB,
} from "../services/backend/events/flowy-user/index"; } from "../services/backend/events/flowy-user/index";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { UserNotificationListener } from "./components/user/application/notifications";
function App() { function App() {
async function greet() { async function sendSignInEvent() {
let make_payload = () => let make_payload = () =>
SignInPayloadPB.fromObject({ SignInPayloadPB.fromObject({
email: nanoid(4) + "@gmail.com", email: nanoid(4) + "@gmail.com",
password: "A!@123abc", password: "A!@123abc",
name: "abc", name: "abc",
}); });
let listener = await new UserNotificationListener("", (userProfile) => {
console.log(userProfile);
listener.stop();
});
listener.start();
await UserEventSignIn(make_payload()); await UserEventSignIn(make_payload());
} }
return ( return (
<div className="container"> <div className="container">
<h1>Welcome to AppFlowy!</h1> <h1>Welcome to AppFlowy!</h1>
<button type="button" onClick={() => sendSignInEvent()}>
<button type="button" onClick={() => greet()}> Test Sign In Event
Sign in
</button> </button>
</div> </div>
); );

View File

@ -0,0 +1 @@
export * from "./user_listener";

View File

@ -0,0 +1,27 @@
import { Result } from "ts-results/result";
import { UserNotification, FlowyError } from "../../../../../services/backend";
import { NotificationParser, OnNotificationError } from "../../../../../services/backend/notifications/parser";
declare type UserNotificationCallback = (ty: UserNotification, payload: Uint8Array) => void;
export class UserNotificationParser extends NotificationParser<UserNotification> {
constructor(callback: UserNotificationCallback, id?: String, onError?: OnNotificationError) {
super(
callback,
(ty) => {
let notification = UserNotification[ty];
if (isUserNotification(notification)) {
return UserNotification[notification];
} else {
return UserNotification.Unknown;
}
},
id,
onError
);
}
}
const isUserNotification = (notification: string): notification is keyof typeof UserNotification => {
return Object.values(UserNotification).indexOf(notification) !== -1;
};

View File

@ -0,0 +1,34 @@
import { FlowyError, UserNotification, UserProfilePB } from "../../../../../services/backend";
import { AFNotificationListener, OnNotificationError } from "../../../../../services/backend/notifications";
import { UserNotificationParser } from "./parser";
declare type OnUserProfileUpdate = (userProfile: UserProfilePB) => void;
export class UserNotificationListener extends AFNotificationListener<UserNotification> {
onProfileUpdate?: OnUserProfileUpdate;
constructor(userId?: String, onProfileUpdate?: OnUserProfileUpdate, onError?: OnNotificationError) {
let parser = new UserNotificationParser(
(notification, payload) => {
switch (notification) {
case UserNotification.UserAuthChanged:
break;
case UserNotification.UserProfileUpdated:
break;
case UserNotification.UserUnauthorized:
break;
case UserNotification.UserSignIn:
let userProfile = UserProfilePB.deserializeBinary(payload);
this.onProfileUpdate?.(userProfile);
break;
default:
break;
}
},
userId,
onError
);
super(parser);
this.onProfileUpdate = onProfileUpdate;
}
}

View File

@ -0,0 +1,2 @@
export * from "./listener";
export * from "./parser";

View File

@ -0,0 +1,29 @@
import { listen, UnlistenFn } from "@tauri-apps/api/event";
import { FlowyError } from "../classes/flowy-error";
import { SubscribeObject } from "../classes/flowy-notification";
import { NotificationParser } from "./parser";
declare type OnError = (error: FlowyError) => void;
export abstract class AFNotificationListener<T> {
parser?: NotificationParser<T> | null;
private _listener?: UnlistenFn;
protected constructor(parser?: NotificationParser<T>) {
this.parser = parser;
}
async start() {
this._listener = await listen("af-notification", (notification) => {
let object = SubscribeObject.fromObject(notification.payload as {});
this.parser?.parse(object);
});
}
async stop() {
if (this._listener != null) {
this._listener();
}
this.parser = null;
}
}

View File

@ -0,0 +1,42 @@
import { Ok, Err, Result } from "ts-results/result";
import { FlowyError } from "../classes/flowy-error";
import { SubscribeObject } from "../classes/flowy-notification";
export declare type OnNotificationPayload<T> = (ty: T, payload: Uint8Array) => void;
export declare type OnNotificationError = (error: FlowyError) => void;
export declare type NotificationTyParser<T> = (num: number) => T | null;
export declare type ErrParser<E> = (data: Uint8Array) => E;
export abstract class NotificationParser<T> {
id?: String;
onPayload: OnNotificationPayload<T>;
onError?: OnNotificationError;
tyParser: NotificationTyParser<T>;
constructor(onPayload: OnNotificationPayload<T>, tyParser: NotificationTyParser<T>, id?: String, onError?: OnNotificationError) {
this.id = id;
this.onPayload = onPayload;
this.onError = onError;
this.tyParser = tyParser;
}
parse(subject: SubscribeObject) {
if (typeof this.id !== "undefined" && this.id.length == 0) {
if (subject.id != this.id) {
return;
}
}
let ty = this.tyParser(subject.ty);
if (ty == null) {
return;
}
if (subject.has_error) {
let error = FlowyError.deserializeBinary(subject.error);
this.onError?.(error);
} else {
this.onPayload(ty, subject.payload);
}
}
}

View File

@ -5,7 +5,7 @@ use crate::{
entities::workspace::RepeatedWorkspacePB, entities::workspace::RepeatedWorkspacePB,
errors::FlowyResult, errors::FlowyResult,
event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
notification::{send_dart_notification, FolderNotification}, notification::{send_notification, FolderNotification},
services::{ services::{
folder_editor::FolderEditor, persistence::FolderPersistence, set_current_workspace, AppController, folder_editor::FolderEditor, persistence::FolderPersistence, set_current_workspace, AppController,
TrashController, ViewController, WorkspaceController, TrashController, ViewController, WorkspaceController,
@ -249,7 +249,7 @@ impl DefaultFolderBuilder {
let repeated_workspace = RepeatedWorkspacePB { let repeated_workspace = RepeatedWorkspacePB {
items: vec![workspace_rev.into()], items: vec![workspace_rev.into()],
}; };
send_dart_notification(token, FolderNotification::UserCreateWorkspace) send_notification(token, FolderNotification::UserCreateWorkspace)
.payload(repeated_workspace) .payload(repeated_workspace)
.send(); .send();
Ok(()) Ok(())

View File

@ -33,11 +33,11 @@ impl std::convert::From<FolderNotification> for i32 {
} }
#[tracing::instrument(level = "trace")] #[tracing::instrument(level = "trace")]
pub(crate) fn send_dart_notification(id: &str, ty: FolderNotification) -> NotificationBuilder { pub(crate) fn send_notification(id: &str, ty: FolderNotification) -> NotificationBuilder {
NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY) NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY)
} }
#[tracing::instrument(level = "trace")] #[tracing::instrument(level = "trace")]
pub(crate) fn send_anonymous_dart_notification(ty: FolderNotification) -> NotificationBuilder { pub(crate) fn send_anonymous_notification(ty: FolderNotification) -> NotificationBuilder {
NotificationBuilder::new("", ty, OBSERVABLE_CATEGORY) NotificationBuilder::new("", ty, OBSERVABLE_CATEGORY)
} }

View File

@ -91,7 +91,7 @@ impl AppController {
}) })
.await? .await?
.into(); .into();
send_dart_notification(&app_id, FolderNotification::AppUpdated) send_notification(&app_id, FolderNotification::AppUpdated)
.payload(app) .payload(app)
.send(); .send();
self.update_app_on_server(params)?; self.update_app_on_server(params)?;
@ -163,7 +163,7 @@ impl AppController {
{ {
Ok(_) => { Ok(_) => {
let app: AppPB = app_rev.into(); let app: AppPB = app_rev.into();
send_dart_notification(&app.id, FolderNotification::AppUpdated) send_notification(&app.id, FolderNotification::AppUpdated)
.payload(app) .payload(app)
.send(); .send();
} }
@ -248,7 +248,7 @@ fn notify_apps_changed<'a>(
.map(|app_rev| app_rev.into()) .map(|app_rev| app_rev.into())
.collect(); .collect();
let repeated_app = RepeatedAppPB { items }; let repeated_app = RepeatedAppPB { items };
send_dart_notification(workspace_id, FolderNotification::WorkspaceAppsChanged) send_notification(workspace_id, FolderNotification::WorkspaceAppsChanged)
.payload(repeated_app) .payload(repeated_app)
.send(); .send();
Ok(()) Ok(())

View File

@ -2,7 +2,7 @@ use crate::{
entities::trash::{RepeatedTrashIdPB, RepeatedTrashPB, TrashIdPB, TrashPB, TrashType}, entities::trash::{RepeatedTrashIdPB, RepeatedTrashPB, TrashIdPB, TrashPB, TrashType},
errors::{FlowyError, FlowyResult}, errors::{FlowyError, FlowyResult},
event_map::{FolderCouldServiceV1, WorkspaceUser}, event_map::{FolderCouldServiceV1, WorkspaceUser},
notification::{send_anonymous_dart_notification, FolderNotification}, notification::{send_anonymous_notification, FolderNotification},
services::persistence::{FolderPersistence, FolderPersistenceTransaction}, services::persistence::{FolderPersistence, FolderPersistenceTransaction},
}; };
@ -283,7 +283,7 @@ impl TrashController {
fn notify_trash_changed<T: Into<RepeatedTrashPB>>(repeated_trash: T) { fn notify_trash_changed<T: Into<RepeatedTrashPB>>(repeated_trash: T) {
let repeated_trash = repeated_trash.into(); let repeated_trash = repeated_trash.into();
tracing::Span::current().record("n_trash", repeated_trash.len()); tracing::Span::current().record("n_trash", repeated_trash.len());
send_anonymous_dart_notification(FolderNotification::TrashUpdated) send_anonymous_notification(FolderNotification::TrashUpdated)
.payload(repeated_trash) .payload(repeated_trash)
.send(); .send();
} }

View File

@ -8,7 +8,7 @@ use crate::{
}, },
errors::{FlowyError, FlowyResult}, errors::{FlowyError, FlowyResult},
event_map::{FolderCouldServiceV1, WorkspaceUser}, event_map::{FolderCouldServiceV1, WorkspaceUser},
notification::{send_dart_notification, FolderNotification}, notification::{send_notification, FolderNotification},
services::{ services::{
persistence::{FolderPersistence, FolderPersistenceTransaction, ViewChangeset}, persistence::{FolderPersistence, FolderPersistenceTransaction, ViewChangeset},
TrashController, TrashEvent, TrashController, TrashEvent,
@ -225,7 +225,7 @@ impl ViewController {
}) })
.await?; .await?;
send_dart_notification(&view_id, FolderNotification::ViewMoveToTrash) send_notification(&view_id, FolderNotification::ViewMoveToTrash)
.payload(deleted_view) .payload(deleted_view)
.send(); .send();
@ -291,7 +291,7 @@ impl ViewController {
transaction.update_view(changeset)?; transaction.update_view(changeset)?;
let view_rev = transaction.read_view(&view_id)?; let view_rev = transaction.read_view(&view_id)?;
let view: ViewPB = view_rev.clone().into(); let view: ViewPB = view_rev.clone().into();
send_dart_notification(&view_id, FolderNotification::ViewUpdated) send_notification(&view_id, FolderNotification::ViewUpdated)
.payload(view) .payload(view)
.send(); .send();
notify_views_changed(&view_rev.app_id, self.trash_controller.clone(), &transaction)?; notify_views_changed(&view_rev.app_id, self.trash_controller.clone(), &transaction)?;
@ -356,7 +356,7 @@ impl ViewController {
{ {
Ok(_) => { Ok(_) => {
let view: ViewPB = view_rev.into(); let view: ViewPB = view_rev.into();
send_dart_notification(&view.id, FolderNotification::ViewUpdated) send_notification(&view.id, FolderNotification::ViewUpdated)
.payload(view) .payload(view)
.send(); .send();
} }
@ -518,7 +518,7 @@ fn read_local_views_with_transaction<'a>(
} }
fn notify_dart(view: ViewPB, notification: FolderNotification) { fn notify_dart(view: ViewPB, notification: FolderNotification) {
send_dart_notification(&view.id, notification).payload(view).send(); send_notification(&view.id, notification).payload(view).send();
} }
#[tracing::instrument( #[tracing::instrument(
@ -537,7 +537,7 @@ fn notify_views_changed<'a>(
app_rev.belongings.retain(|view| !trash_ids.contains(&view.id)); app_rev.belongings.retain(|view| !trash_ids.contains(&view.id));
let app: AppPB = app_rev.into(); let app: AppPB = app_rev.into();
send_dart_notification(belong_to_id, FolderNotification::AppUpdated) send_notification(belong_to_id, FolderNotification::AppUpdated)
.payload(app) .payload(app)
.send(); .send();

View File

@ -53,7 +53,7 @@ impl WorkspaceController {
.map(|workspace_rev| workspace_rev.into()) .map(|workspace_rev| workspace_rev.into())
.collect(); .collect();
let repeated_workspace = RepeatedWorkspacePB { items: workspaces }; let repeated_workspace = RepeatedWorkspacePB { items: workspaces };
send_dart_notification(&token, FolderNotification::UserCreateWorkspace) send_notification(&token, FolderNotification::UserCreateWorkspace)
.payload(repeated_workspace) .payload(repeated_workspace)
.send(); .send();
set_current_workspace(&user_id, &workspace.id); set_current_workspace(&user_id, &workspace.id);
@ -73,7 +73,7 @@ impl WorkspaceController {
}) })
.await?; .await?;
send_dart_notification(&workspace_id, FolderNotification::WorkspaceUpdated) send_notification(&workspace_id, FolderNotification::WorkspaceUpdated)
.payload(workspace) .payload(workspace)
.send(); .send();
self.update_workspace_on_server(params)?; self.update_workspace_on_server(params)?;
@ -92,7 +92,7 @@ impl WorkspaceController {
self.read_local_workspaces(None, &user_id, &transaction) self.read_local_workspaces(None, &user_id, &transaction)
}) })
.await?; .await?;
send_dart_notification(&token, FolderNotification::UserDeleteWorkspace) send_notification(&token, FolderNotification::UserDeleteWorkspace)
.payload(repeated_workspace) .payload(repeated_workspace)
.send(); .send();
self.delete_workspace_on_server(workspace_id)?; self.delete_workspace_on_server(workspace_id)?;
@ -236,7 +236,7 @@ pub async fn notify_workspace_setting_did_change(
}) })
.await?; .await?;
send_dart_notification(&token, FolderNotification::WorkspaceSetting) send_notification(&token, FolderNotification::WorkspaceSetting)
.payload(workspace_setting) .payload(workspace_setting)
.send(); .send();
Ok(()) Ok(())

View File

@ -6,7 +6,7 @@ use crate::entities::{
use crate::{ use crate::{
errors::FlowyError, errors::FlowyError,
manager::FolderManager, manager::FolderManager,
notification::{send_dart_notification, FolderNotification}, notification::{send_notification, FolderNotification},
services::{get_current_workspace, read_local_workspace_apps, WorkspaceController}, services::{get_current_workspace, read_local_workspace_apps, WorkspaceController},
}; };
use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult}; use lib_dispatch::prelude::{data_result, AFPluginData, AFPluginState, DataResult};
@ -151,7 +151,7 @@ fn read_workspaces_on_server(
.collect(), .collect(),
}; };
send_dart_notification(&token, FolderNotification::WorkspaceListUpdated) send_notification(&token, FolderNotification::WorkspaceListUpdated)
.payload(repeated_workspace) .payload(repeated_workspace)
.send(); .send();
Result::<(), FlowyError>::Ok(()) Result::<(), FlowyError>::Ok(())

View File

@ -35,6 +35,6 @@ impl std::convert::From<GridDartNotification> for i32 {
} }
#[tracing::instrument(level = "trace")] #[tracing::instrument(level = "trace")]
pub fn send_dart_notification(id: &str, ty: GridDartNotification) -> NotificationBuilder { pub fn send_notification(id: &str, ty: GridDartNotification) -> NotificationBuilder {
NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY) NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY)
} }

View File

@ -1,6 +1,6 @@
use crate::entities::{CellChangesetPB, InsertedRowPB, UpdatedRowPB}; use crate::entities::{CellChangesetPB, InsertedRowPB, UpdatedRowPB};
use crate::manager::GridUser; use crate::manager::GridUser;
use crate::notification::{send_dart_notification, GridDartNotification}; use crate::notification::{send_notification, GridDartNotification};
use crate::services::block_editor::{GridBlockRevisionEditor, GridBlockRevisionMergeable}; use crate::services::block_editor::{GridBlockRevisionEditor, GridBlockRevisionMergeable};
use crate::services::persistence::block_index::BlockIndexCache; use crate::services::persistence::block_index::BlockIndexCache;
use crate::services::persistence::rev_sqlite::{ use crate::services::persistence::rev_sqlite::{
@ -262,7 +262,7 @@ impl GridBlockManager {
async fn notify_did_update_cell(&self, changeset: CellChangesetPB) -> FlowyResult<()> { async fn notify_did_update_cell(&self, changeset: CellChangesetPB) -> FlowyResult<()> {
let id = format!("{}:{}", changeset.row_id, changeset.field_id); let id = format!("{}:{}", changeset.row_id, changeset.field_id);
send_dart_notification(&id, GridDartNotification::DidUpdateCell).send(); send_notification(&id, GridDartNotification::DidUpdateCell).send();
Ok(()) Ok(())
} }
} }

View File

@ -1,7 +1,7 @@
use crate::entities::CellPathParams; use crate::entities::CellPathParams;
use crate::entities::*; use crate::entities::*;
use crate::manager::GridUser; use crate::manager::GridUser;
use crate::notification::{send_dart_notification, GridDartNotification}; use crate::notification::{send_notification, GridDartNotification};
use crate::services::block_manager::GridBlockManager; use crate::services::block_manager::GridBlockManager;
use crate::services::cell::{ use crate::services::cell::{
apply_cell_data_changeset, decode_type_cell_data, stringify_cell_data, AnyTypeCache, AtomicCellDataCache, apply_cell_data_changeset, decode_type_cell_data, stringify_cell_data, AnyTypeCache, AtomicCellDataCache,
@ -852,7 +852,7 @@ impl GridRevisionEditor {
let notified_changeset = GridFieldChangesetPB::update(&self.grid_id, vec![updated_field.clone()]); let notified_changeset = GridFieldChangesetPB::update(&self.grid_id, vec![updated_field.clone()]);
self.notify_did_update_grid(notified_changeset).await?; self.notify_did_update_grid(notified_changeset).await?;
send_dart_notification(field_id, GridDartNotification::DidUpdateField) send_notification(field_id, GridDartNotification::DidUpdateField)
.payload(updated_field) .payload(updated_field)
.send(); .send();
} }
@ -861,7 +861,7 @@ impl GridRevisionEditor {
} }
async fn notify_did_update_grid(&self, changeset: GridFieldChangesetPB) -> FlowyResult<()> { async fn notify_did_update_grid(&self, changeset: GridFieldChangesetPB) -> FlowyResult<()> {
send_dart_notification(&self.grid_id, GridDartNotification::DidUpdateGridFields) send_notification(&self.grid_id, GridDartNotification::DidUpdateGridFields)
.payload(changeset) .payload(changeset)
.send(); .send();
Ok(()) Ok(())

View File

@ -1,5 +1,5 @@
use crate::entities::{GridRowsVisibilityChangesetPB, ReorderAllRowsPB, ReorderSingleRowPB}; use crate::entities::{GridRowsVisibilityChangesetPB, ReorderAllRowsPB, ReorderSingleRowPB};
use crate::notification::{send_dart_notification, GridDartNotification}; use crate::notification::{send_notification, GridDartNotification};
use crate::services::filter::FilterResultNotification; use crate::services::filter::FilterResultNotification;
use crate::services::sort::{ReorderAllRowsResult, ReorderSingleRowResult}; use crate::services::sort::{ReorderAllRowsResult, ReorderSingleRowResult};
use async_stream::stream; use async_stream::stream;
@ -37,7 +37,7 @@ impl GridViewChangedReceiverRunner {
invisible_rows: notification.invisible_rows, invisible_rows: notification.invisible_rows,
}; };
send_dart_notification( send_notification(
&changeset.view_id, &changeset.view_id,
GridDartNotification::DidUpdateGridViewRowsVisibility, GridDartNotification::DidUpdateGridViewRowsVisibility,
) )
@ -48,7 +48,7 @@ impl GridViewChangedReceiverRunner {
let row_orders = ReorderAllRowsPB { let row_orders = ReorderAllRowsPB {
row_orders: notification.row_orders, row_orders: notification.row_orders,
}; };
send_dart_notification(&notification.view_id, GridDartNotification::DidReorderRows) send_notification(&notification.view_id, GridDartNotification::DidReorderRows)
.payload(row_orders) .payload(row_orders)
.send() .send()
} }
@ -58,7 +58,7 @@ impl GridViewChangedReceiverRunner {
old_index: notification.old_index as i32, old_index: notification.old_index as i32,
new_index: notification.new_index as i32, new_index: notification.new_index as i32,
}; };
send_dart_notification(&notification.view_id, GridDartNotification::DidReorderSingleRow) send_notification(&notification.view_id, GridDartNotification::DidReorderSingleRow)
.payload(reorder_row) .payload(reorder_row)
.send() .send()
} }

View File

@ -1,5 +1,5 @@
use crate::entities::*; use crate::entities::*;
use crate::notification::{send_dart_notification, GridDartNotification}; use crate::notification::{send_notification, GridDartNotification};
use crate::services::block_manager::GridBlockEvent; use crate::services::block_manager::GridBlockEvent;
use crate::services::cell::{AtomicCellDataCache, TypeCellData}; use crate::services::cell::{AtomicCellDataCache, TypeCellData};
use crate::services::field::{RowSingleCellData, TypeOptionCellDataHandler}; use crate::services::field::{RowSingleCellData, TypeOptionCellDataHandler};
@ -184,7 +184,7 @@ impl GridViewRevisionEditor {
} }
}; };
send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGridViewRows) send_notification(&self.view_id, GridDartNotification::DidUpdateGridViewRows)
.payload(changeset) .payload(changeset)
.send(); .send();
} }
@ -616,7 +616,7 @@ impl GridViewRevisionEditor {
debug_assert!(!changeset.is_empty()); debug_assert!(!changeset.is_empty());
if !changeset.is_empty() { if !changeset.is_empty() {
send_dart_notification(&changeset.view_id, GridDartNotification::DidGroupByNewField) send_notification(&changeset.view_id, GridDartNotification::DidGroupByNewField)
.payload(changeset) .payload(changeset)
.send(); .send();
} }
@ -630,33 +630,33 @@ impl GridViewRevisionEditor {
async fn notify_did_update_setting(&self) { async fn notify_did_update_setting(&self) {
let setting = self.get_view_setting().await; let setting = self.get_view_setting().await;
send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGridSetting) send_notification(&self.view_id, GridDartNotification::DidUpdateGridSetting)
.payload(setting) .payload(setting)
.send(); .send();
} }
pub async fn notify_did_update_group_rows(&self, payload: GroupRowsNotificationPB) { pub async fn notify_did_update_group_rows(&self, payload: GroupRowsNotificationPB) {
send_dart_notification(&payload.group_id, GridDartNotification::DidUpdateGroup) send_notification(&payload.group_id, GridDartNotification::DidUpdateGroup)
.payload(payload) .payload(payload)
.send(); .send();
} }
pub async fn notify_did_update_filter(&self, notification: FilterChangesetNotificationPB) { pub async fn notify_did_update_filter(&self, notification: FilterChangesetNotificationPB) {
send_dart_notification(&notification.view_id, GridDartNotification::DidUpdateFilter) send_notification(&notification.view_id, GridDartNotification::DidUpdateFilter)
.payload(notification) .payload(notification)
.send(); .send();
} }
pub async fn notify_did_update_sort(&self, notification: SortChangesetNotificationPB) { pub async fn notify_did_update_sort(&self, notification: SortChangesetNotificationPB) {
if !notification.is_empty() { if !notification.is_empty() {
send_dart_notification(&notification.view_id, GridDartNotification::DidUpdateSort) send_notification(&notification.view_id, GridDartNotification::DidUpdateSort)
.payload(notification) .payload(notification)
.send(); .send();
} }
} }
async fn notify_did_update_view(&self, changeset: GroupViewChangesetPB) { async fn notify_did_update_view(&self, changeset: GroupViewChangesetPB) {
send_dart_notification(&self.view_id, GridDartNotification::DidUpdateGroupView) send_notification(&self.view_id, GridDartNotification::DidUpdateGroupView)
.payload(changeset) .payload(changeset)
.send(); .send();
} }

View File

@ -9,6 +9,7 @@ pub(crate) enum UserNotification {
UserProfileUpdated = 2, UserProfileUpdated = 2,
UserUnauthorized = 3, UserUnauthorized = 3,
UserWsConnectStateChanged = 4, UserWsConnectStateChanged = 4,
UserSignIn = 5,
} }
impl std::default::Default for UserNotification { impl std::default::Default for UserNotification {
@ -23,6 +24,10 @@ impl std::convert::From<UserNotification> for i32 {
} }
} }
pub(crate) fn dart_notify(id: &str, ty: UserNotification) -> NotificationBuilder { pub(crate) fn send_notification(id: &str, ty: UserNotification) -> NotificationBuilder {
NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY) NotificationBuilder::new(id, ty, OBSERVABLE_CATEGORY)
} }
pub(crate) fn send_sign_in_notification() -> NotificationBuilder {
NotificationBuilder::new("", UserNotification::UserSignIn, OBSERVABLE_CATEGORY)
}

View File

@ -84,7 +84,13 @@ impl UserSession {
#[tracing::instrument(level = "debug", skip(self))] #[tracing::instrument(level = "debug", skip(self))]
pub async fn sign_in(&self, params: SignInParams) -> Result<UserProfilePB, FlowyError> { pub async fn sign_in(&self, params: SignInParams) -> Result<UserProfilePB, FlowyError> {
if self.is_user_login(&params.email) { if self.is_user_login(&params.email) {
self.get_user_profile().await match self.get_user_profile().await {
Ok(profile) => {
send_sign_in_notification().payload(profile.clone()).send();
Ok(profile)
}
Err(err) => Err(err),
}
} else { } else {
let resp = self.cloud_service.sign_in(params).await?; let resp = self.cloud_service.sign_in(params).await?;
let session: Session = resp.clone().into(); let session: Session = resp.clone().into();
@ -92,6 +98,7 @@ impl UserSession {
let user_table = self.save_user(resp.into()).await?; let user_table = self.save_user(resp.into()).await?;
let user_profile: UserProfilePB = user_table.into(); let user_profile: UserProfilePB = user_table.into();
self.notifier.notify_login(&user_profile.token, &user_profile.id); self.notifier.notify_login(&user_profile.token, &user_profile.id);
send_sign_in_notification().payload(user_profile.clone()).send();
Ok(user_profile) Ok(user_profile)
} }
} }
@ -134,7 +141,7 @@ impl UserSession {
diesel_update_table!(user_table, changeset, &*self.db_connection()?); diesel_update_table!(user_table, changeset, &*self.db_connection()?);
let user_profile = self.get_user_profile().await?; let user_profile = self.get_user_profile().await?;
dart_notify(&session.token, UserNotification::UserProfileUpdated) send_notification(&session.token, UserNotification::UserProfileUpdated)
.payload(user_profile) .payload(user_profile)
.send(); .send();
self.update_user_on_server(&session.token, params).await?; self.update_user_on_server(&session.token, params).await?;

View File

@ -1,11 +1,5 @@
[tasks.tauri_build] [tasks.tauri_build]
script = [""" description = "Build the Tauri backend & Run Code Generation"
cd appflowy_tauri/src-tauri
npm run tauri build
"""]
script_runner = "@shell"
[tasks.tauri_pb]
script = [""" script = ["""
cd appflowy_tauri/src-tauri cd appflowy_tauri/src-tauri
cargo build cargo build
@ -20,6 +14,7 @@ script = ["""
script_runner = "@shell" script_runner = "@shell"
[tasks.tauri_clean] [tasks.tauri_clean]
description = "Remove all the building artifacts"
run_task = { name = [ run_task = { name = [
"rust_lib_clean", "rust_lib_clean",
"rm_macro_build_cache", "rm_macro_build_cache",