From 17a0a793796ca73632c597dc28fd857652c46e17 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 15 May 2023 10:56:01 +0800 Subject: [PATCH] fix: tests (#2516) --- .../components/tests/DatabaseTestHelper.ts | 4 +-- .../effects/database/cell/cell_controller.ts | 10 ++++-- .../effects/database/cell/cell_observer.ts | 13 ++++---- .../database/field/field_controller.ts | 17 +++++----- .../effects/database/field/field_observer.ts | 22 +++++++------ .../database/group/group_controller.ts | 21 ++++++------ .../effects/database/group/group_observer.ts | 17 +++++----- .../stores/effects/database/row/row_cache.ts | 32 +++++++++++-------- .../database/view/view_row_observer.ts | 23 ++++++------- .../stores/effects/folder/app/app_observer.ts | 15 +++++---- .../effects/folder/view/view_observer.ts | 21 ++++++------ .../folder/workspace/workspace_observer.ts | 17 +++++----- .../src/appflowy_app/utils/change_notifier.ts | 18 +++++++++-- 13 files changed, 129 insertions(+), 101 deletions(-) diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts b/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts index 6930e7c0e1..51080322e6 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts @@ -26,13 +26,13 @@ import { FieldInfo } from '../../stores/effects/database/field/field_controller' import { TypeOptionController } from '../../stores/effects/database/field/type_option/type_option_controller'; import { makeSingleSelectTypeOptionContext } from '../../stores/effects/database/field/type_option/type_option_context'; import { SelectOptionBackendService } from '../../stores/effects/database/cell/select_option_bd_svc'; +import { Log } from '$app/utils/log'; // Create a database view for specific layout type // Do not use it production code. Just for testing export async function createTestDatabaseView(layout: ViewLayoutPB): Promise { const workspaceSetting: WorkspaceSettingPB = await FolderEventReadCurrentWorkspace().then((result) => result.unwrap()); - const app = workspaceSetting.workspace.views[0]; - const appService = new AppBackendService(app.id); + const appService = new AppBackendService(workspaceSetting.workspace.id); return await appService.createView({ name: 'New Grid', layoutType: layout }); } diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_controller.ts index 1cd73aad90..aa0c75e919 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_controller.ts @@ -30,6 +30,7 @@ export class CellController { this.cellDataNotifier = new CellDataNotifier(cellCache.get(this.cacheKey)); this.cellObserver = new CellObserver(cellIdentifier.rowId, cellIdentifier.fieldId); this.fieldNotifier = new DatabaseFieldObserver(cellIdentifier.fieldId); + void this.cellObserver.subscribe({ /// 1.Listen on user edit event and load the new cell data if needed. /// For example: @@ -37,7 +38,11 @@ export class CellController { /// cell display: $12 onCellChanged: async () => { this.cellCache.remove(this.cacheKey); - await this._loadCellData(); + try { + await this._loadCellData(); + } catch (e) { + Log.error(e); + } }, }); @@ -57,7 +62,7 @@ export class CellController { subscribeChanged = (callbacks: Callbacks) => { this.subscribeCallbacks = callbacks; - this.cellDataNotifier.observer.subscribe((cellData) => { + this.cellDataNotifier.observer?.subscribe((cellData) => { if (cellData !== null) { callbacks.onCellChanged(Some(cellData)); } @@ -108,7 +113,6 @@ export class CellController { }; dispose = async () => { - this.cellDataNotifier.unsubscribe(); await this.cellObserver.unsubscribe(); await this.fieldNotifier.unsubscribe(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_observer.ts index 7796112559..dba0290d7a 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/cell_observer.ts @@ -2,21 +2,20 @@ import { Ok, Result } from 'ts-results'; import { ChangeNotifier } from '$app/utils/change_notifier'; import { DatabaseNotificationObserver } from '../notifications/observer'; import { DatabaseNotification, FlowyError } from '@/services/backend'; +import { Subscription } from 'rxjs'; -type UpdateCellNotifiedValue = Result; - -export type CellChangedCallback = (value: UpdateCellNotifiedValue) => void; +export type CellChangedCallback = (value: Result) => void; export class CellObserver { - private notifier?: ChangeNotifier; + private notifier?: ChangeNotifier>; private listener?: DatabaseNotificationObserver; + private subscription?: Subscription; constructor(public readonly rowId: string, public readonly fieldId: string) {} subscribe = async (callbacks: { onCellChanged: CellChangedCallback }) => { this.notifier = new ChangeNotifier(); - this.notifier?.observer.subscribe(callbacks.onCellChanged); - + this.subscription = this.notifier?.observer?.subscribe(callbacks.onCellChanged); this.listener = new DatabaseNotificationObserver({ // The rowId combine with fieldId can identifier the cell. // This format rowId:fieldId is also defined in the backend, @@ -40,7 +39,7 @@ export class CellObserver { }; unsubscribe = async () => { - this.notifier?.unsubscribe(); + this.subscription?.unsubscribe(); await this.listener?.stop(); }; } diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts index c1e126e7d9..1cebae3ee0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts @@ -1,8 +1,8 @@ -import { Log } from '$app/utils/log'; -import { DatabaseBackendService } from '../database_bd_svc'; -import { DatabaseFieldChangesetObserver } from './field_observer'; -import { FieldIdPB, FieldPB, IndexFieldPB } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; +import { Log } from "$app/utils/log"; +import { DatabaseBackendService } from "../database_bd_svc"; +import { DatabaseFieldChangesetObserver } from "./field_observer"; +import { FieldIdPB, FieldPB, IndexFieldPB } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; export class FieldController { private backendService: DatabaseBackendService; @@ -37,7 +37,7 @@ export class FieldController { }; subscribe = (callbacks: { onNumOfFieldsChanged?: (fieldInfos: readonly FieldInfo[]) => void }) => { - this.numOfFieldsNotifier.observer.subscribe((fieldInfos) => { + this.numOfFieldsNotifier.observer?.subscribe((fieldInfos) => { callbacks.onNumOfFieldsChanged?.(fieldInfos); }); }; @@ -53,7 +53,7 @@ export class FieldController { } else { Log.error(result.val); } - }, + } }); }; @@ -122,5 +122,6 @@ class NumOfFieldsNotifier extends ChangeNotifier { } export class FieldInfo { - constructor(public readonly field: FieldPB) {} + constructor(public readonly field: FieldPB) { + } } diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_observer.ts index 471016d5fd..d6a3e307b2 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_observer.ts @@ -1,7 +1,7 @@ -import { Ok, Result } from 'ts-results'; -import { DatabaseNotification, DatabaseFieldChangesetPB, FlowyError, FieldPB } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { DatabaseNotificationObserver } from '../notifications/observer'; +import { Ok, Result } from "ts-results"; +import { DatabaseNotification, DatabaseFieldChangesetPB, FlowyError, FieldPB } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { DatabaseNotificationObserver } from "../notifications/observer"; export type FieldChangesetSubscribeCallback = (value: Result) => void; @@ -9,11 +9,12 @@ export class DatabaseFieldChangesetObserver { private notifier?: ChangeNotifier>; private listener?: DatabaseNotificationObserver; - constructor(public readonly viewId: string) {} + constructor(public readonly viewId: string) { + } subscribe = async (callbacks: { onFieldsChanged: FieldChangesetSubscribeCallback }) => { this.notifier = new ChangeNotifier(); - this.notifier?.observer.subscribe(callbacks.onFieldsChanged); + this.notifier?.observer?.subscribe(callbacks.onFieldsChanged); this.listener = new DatabaseNotificationObserver({ id: this.viewId, @@ -29,7 +30,7 @@ export class DatabaseFieldChangesetObserver { default: break; } - }, + } }); await this.listener.start(); }; @@ -46,11 +47,12 @@ export class DatabaseFieldObserver { private _notifier?: ChangeNotifier>; private _listener?: DatabaseNotificationObserver; - constructor(public readonly fieldId: string) {} + constructor(public readonly fieldId: string) { + } subscribe = async (callbacks: { onFieldChanged: FieldSubscribeCallback }) => { this._notifier = new ChangeNotifier(); - this._notifier?.observer.subscribe(callbacks.onFieldChanged); + this._notifier?.observer?.subscribe(callbacks.onFieldChanged); this._listener = new DatabaseNotificationObserver({ id: this.fieldId, @@ -66,7 +68,7 @@ export class DatabaseFieldObserver { default: break; } - }, + } }); await this._listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_controller.ts index ea500e64fe..1181bb5fd5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_controller.ts @@ -1,9 +1,9 @@ -import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { None, Ok, Option, Result, Some } from 'ts-results'; -import { DatabaseNotificationObserver } from '../notifications/observer'; -import { Log } from '$app/utils/log'; -import { DatabaseBackendService } from '../database_bd_svc'; +import { DatabaseNotification, FlowyError, GroupPB, GroupRowsNotificationPB, RowPB } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { None, Ok, Option, Result, Some } from "ts-results"; +import { DatabaseNotificationObserver } from "../notifications/observer"; +import { Log } from "$app/utils/log"; +import { DatabaseBackendService } from "../database_bd_svc"; export type GroupDataCallbacks = { onRemoveRow: (groupId: string, rowId: string) => void; @@ -83,7 +83,7 @@ export class DatabaseGroupController { } else { Log.error(result.val); } - }, + } }); }; @@ -111,11 +111,12 @@ class GroupDataObserver { private notifier?: ChangeNotifier>; private listener?: DatabaseNotificationObserver; - constructor(public readonly groupId: string) {} + constructor(public readonly groupId: string) { + } subscribe = async (callbacks: { onRowsChanged: GroupRowsSubscribeCallback }) => { this.notifier = new ChangeNotifier(); - this.notifier?.observer.subscribe(callbacks.onRowsChanged); + this.notifier?.observer?.subscribe(callbacks.onRowsChanged); this.listener = new DatabaseNotificationObserver({ id: this.groupId, @@ -131,7 +132,7 @@ class GroupDataObserver { default: break; } - }, + } }); await this.listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_observer.ts index 8a3cb101f4..930a182d62 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/group/group_observer.ts @@ -1,7 +1,7 @@ -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { Ok, Result } from 'ts-results'; -import { DatabaseNotification, FlowyError, GroupChangesetPB, GroupPB } from '@/services/backend'; -import { DatabaseNotificationObserver } from '../notifications/observer'; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { Ok, Result } from "ts-results"; +import { DatabaseNotification, FlowyError, GroupChangesetPB, GroupPB } from "@/services/backend"; +import { DatabaseNotificationObserver } from "../notifications/observer"; export type GroupByFieldCallback = (value: Result) => void; export type GroupChangesetSubscribeCallback = (value: Result) => void; @@ -11,17 +11,18 @@ export class DatabaseGroupObserver { private groupChangesetNotifier?: ChangeNotifier>; private listener?: DatabaseNotificationObserver; - constructor(public readonly viewId: string) {} + constructor(public readonly viewId: string) { + } subscribe = async (callbacks: { onGroupBy: GroupByFieldCallback; onGroupChangeset: GroupChangesetSubscribeCallback; }) => { this.groupByNotifier = new ChangeNotifier(); - this.groupByNotifier?.observer.subscribe(callbacks.onGroupBy); + this.groupByNotifier?.observer?.subscribe(callbacks.onGroupBy); this.groupChangesetNotifier = new ChangeNotifier(); - this.groupChangesetNotifier?.observer.subscribe(callbacks.onGroupChangeset); + this.groupChangesetNotifier?.observer?.subscribe(callbacks.onGroupChangeset); this.listener = new DatabaseNotificationObserver({ id: this.viewId, @@ -44,7 +45,7 @@ export class DatabaseGroupObserver { default: break; } - }, + } }); await this.listener.start(); diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/row_cache.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/row_cache.ts index 38ce5aca28..9df78866ff 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/row_cache.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/row/row_cache.ts @@ -6,15 +6,15 @@ import { OptionalRowPB, RowsChangesetPB, RowsVisibilityChangesetPB, - ReorderSingleRowPB, -} from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { FieldInfo } from '../field/field_controller'; -import { CellCache, CellCacheKey } from '../cell/cell_cache'; -import { CellIdentifier } from '../cell/cell_bd_svc'; -import { DatabaseEventGetRow } from '@/services/backend/events/flowy-database2'; -import { None, Option, Some } from 'ts-results'; -import { Log } from '$app/utils/log'; + ReorderSingleRowPB +} from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { FieldInfo } from "../field/field_controller"; +import { CellCache, CellCacheKey } from "../cell/cell_cache"; +import { CellIdentifier } from "../cell/cell_bd_svc"; +import { DatabaseEventGetRow } from "@/services/backend/events/flowy-database2"; +import { None, Option, Some } from "ts-results"; +import { Log } from "$app/utils/log"; export type CellByFieldId = Map; @@ -56,7 +56,7 @@ export class RowCache { subscribe = (callbacks: { onRowsChanged: (reason: RowChangedReason, cellMap?: Map) => void; }) => { - return this.notifier.observer.subscribe((change) => { + return this.notifier.observer?.subscribe((change) => { if (change.rowId !== undefined) { callbacks.onRowsChanged(change.reason, this._toCellMap(change.rowId, this.getFieldInfos())); } else { @@ -339,7 +339,8 @@ export class RowInfo { public readonly viewId: string, public readonly fieldInfos: readonly FieldInfo[], public readonly row: RowPB - ) {} + ) { + } copyWith = (params: { row?: RowPB; fieldInfos?: readonly FieldInfo[] }) => { return new RowInfo(this.viewId, params.fieldInfos || this.fieldInfos, params.row || this.row); @@ -347,15 +348,18 @@ export class RowInfo { } export class DeletedRow { - constructor(public readonly index: number, public readonly rowInfo: RowInfo) {} + constructor(public readonly index: number, public readonly rowInfo: RowInfo) { + } } export class InsertedRow { - constructor(public readonly index: number, public readonly rowId: string) {} + constructor(public readonly index: number, public readonly rowId: string) { + } } export class RowChanged { - constructor(public readonly reason: RowChangedReason, public readonly rowId?: string) {} + constructor(public readonly reason: RowChangedReason, public readonly rowId?: string) { + } } // eslint-disable-next-line no-shadow diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/view_row_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/view_row_observer.ts index b3da8cd061..961b3821a0 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/view_row_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/view/view_row_observer.ts @@ -1,14 +1,14 @@ -import { Ok, Result } from 'ts-results'; +import { Ok, Result } from "ts-results"; import { DatabaseNotification, FlowyError, ReorderAllRowsPB, ReorderSingleRowPB, RowsChangesetPB, - RowsVisibilityChangesetPB, -} from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { DatabaseNotificationObserver } from '../notifications/observer'; + RowsVisibilityChangesetPB +} from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { DatabaseNotificationObserver } from "../notifications/observer"; export type RowsVisibilityNotifyValue = Result; export type RowsNotifyValue = Result; @@ -23,7 +23,8 @@ export class DatabaseViewRowsObserver { private _listener?: DatabaseNotificationObserver; - constructor(public readonly viewId: string) {} + constructor(public readonly viewId: string) { + } subscribe = async (callbacks: { onRowsVisibilityChanged?: (value: RowsVisibilityNotifyValue) => void; @@ -32,10 +33,10 @@ export class DatabaseViewRowsObserver { onReorderSingleRow?: (value: ReorderSingleRowNotifyValue) => void; }) => { // - this.rowsVisibilityNotifier.observer.subscribe(callbacks.onRowsVisibilityChanged); - this.rowsNotifier.observer.subscribe(callbacks.onNumberOfRowsChanged); - this.reorderRowsNotifier.observer.subscribe(callbacks.onReorderRows); - this.reorderSingleRowNotifier.observer.subscribe(callbacks.onReorderSingleRow); + this.rowsVisibilityNotifier.observer?.subscribe(callbacks.onRowsVisibilityChanged); + this.rowsNotifier.observer?.subscribe(callbacks.onNumberOfRowsChanged); + this.reorderRowsNotifier.observer?.subscribe(callbacks.onReorderRows); + this.reorderSingleRowNotifier.observer?.subscribe(callbacks.onReorderSingleRow); this._listener = new DatabaseNotificationObserver({ id: this.viewId, @@ -72,7 +73,7 @@ export class DatabaseViewRowsObserver { default: break; } - }, + } }); await this._listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/app_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/app_observer.ts index a2c430d92f..47ff37333f 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/app_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/app/app_observer.ts @@ -1,7 +1,7 @@ -import { Ok, Result } from 'ts-results'; -import { FlowyError, FolderNotification, RepeatedViewPB } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { FolderNotificationObserver } from '../notifications/observer'; +import { Ok, Result } from "ts-results"; +import { FlowyError, FolderNotification, RepeatedViewPB } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { FolderNotificationObserver } from "../notifications/observer"; export type AppUpdateNotifyCallback = (value: Result) => void; @@ -9,10 +9,11 @@ export class AppObserver { _appNotifier = new ChangeNotifier>(); _listener?: FolderNotificationObserver; - constructor(public readonly appId: string) {} + constructor(public readonly appId: string) { + } subscribe = async (callbacks: { onAppChanged: AppUpdateNotifyCallback }) => { - this._appNotifier?.observer.subscribe(callbacks.onAppChanged); + this._appNotifier?.observer?.subscribe(callbacks.onAppChanged); this._listener = new FolderNotificationObserver({ viewId: this.appId, parserHandler: (notification, result) => { @@ -27,7 +28,7 @@ export class AppObserver { default: break; } - }, + } }); await this._listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/view/view_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/view/view_observer.ts index a54d3e5175..9a5f687c53 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/view/view_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/view/view_observer.ts @@ -1,7 +1,7 @@ -import { Ok, Result } from 'ts-results'; -import { DeletedViewPB, FolderNotification, ViewPB, FlowyError } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { FolderNotificationObserver } from '../notifications/observer'; +import { Ok, Result } from "ts-results"; +import { DeletedViewPB, FolderNotification, ViewPB, FlowyError } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { FolderNotificationObserver } from "../notifications/observer"; type DeleteViewNotifyValue = Result; type UpdateViewNotifyValue = Result; @@ -15,7 +15,8 @@ export class ViewObserver { private _moveToTashNotifier = new ChangeNotifier(); private _listener?: FolderNotificationObserver; - constructor(public readonly viewId: string) {} + constructor(public readonly viewId: string) { + } subscribe = async (callbacks: { onViewUpdate?: (value: UpdateViewNotifyValue) => void; @@ -24,19 +25,19 @@ export class ViewObserver { onViewMoveToTrash?: (value: MoveToTrashViewNotifyValue) => void; }) => { if (callbacks.onViewDelete !== undefined) { - this._deleteViewNotifier.observer.subscribe(callbacks.onViewDelete); + this._deleteViewNotifier.observer?.subscribe(callbacks.onViewDelete); } if (callbacks.onViewUpdate !== undefined) { - this._updateViewNotifier.observer.subscribe(callbacks.onViewUpdate); + this._updateViewNotifier.observer?.subscribe(callbacks.onViewUpdate); } if (callbacks.onViewRestored !== undefined) { - this._restoreViewNotifier.observer.subscribe(callbacks.onViewRestored); + this._restoreViewNotifier.observer?.subscribe(callbacks.onViewRestored); } if (callbacks.onViewMoveToTrash !== undefined) { - this._moveToTashNotifier.observer.subscribe(callbacks.onViewMoveToTrash); + this._moveToTashNotifier.observer?.subscribe(callbacks.onViewMoveToTrash); } this._listener = new FolderNotificationObserver({ @@ -74,7 +75,7 @@ export class ViewObserver { default: break; } - }, + } }); await this._listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/workspace/workspace_observer.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/workspace/workspace_observer.ts index 7fd72c6622..836ba4ac98 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/workspace/workspace_observer.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/folder/workspace/workspace_observer.ts @@ -1,7 +1,7 @@ -import { Ok, Result } from 'ts-results'; -import { FolderNotification, WorkspacePB, FlowyError, RepeatedViewPB, ViewPB } from '@/services/backend'; -import { ChangeNotifier } from '$app/utils/change_notifier'; -import { FolderNotificationObserver } from '../notifications/observer'; +import { Ok, Result } from "ts-results"; +import { FolderNotification, WorkspacePB, FlowyError, RepeatedViewPB, ViewPB } from "@/services/backend"; +import { ChangeNotifier } from "$app/utils/change_notifier"; +import { FolderNotificationObserver } from "../notifications/observer"; export type AppListNotifyValue = Result; export type AppListNotifyCallback = (value: AppListNotifyValue) => void; @@ -13,14 +13,15 @@ export class WorkspaceObserver { private workspaceNotifier = new ChangeNotifier(); private listener?: FolderNotificationObserver; - constructor(public readonly workspaceId: string) {} + constructor(public readonly workspaceId: string) { + } subscribe = async (callbacks: { onAppListChanged: AppListNotifyCallback; onWorkspaceChanged: WorkspaceNotifyCallback; }) => { - this.appListNotifier?.observer.subscribe(callbacks.onAppListChanged); - this.workspaceNotifier?.observer.subscribe(callbacks.onWorkspaceChanged); + this.appListNotifier?.observer?.subscribe(callbacks.onAppListChanged); + this.workspaceNotifier?.observer?.subscribe(callbacks.onWorkspaceChanged); this.listener = new FolderNotificationObserver({ viewId: this.workspaceId, @@ -43,7 +44,7 @@ export class WorkspaceObserver { default: break; } - }, + } }); await this.listener.start(); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/utils/change_notifier.ts b/frontend/appflowy_tauri/src/appflowy_app/utils/change_notifier.ts index c3e112f80c..df81d11c47 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/utils/change_notifier.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/utils/change_notifier.ts @@ -1,17 +1,29 @@ -import { Subject } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; export class ChangeNotifier { + private isUnsubscribe = false; private subject = new Subject(); notify(value: T) { this.subject.next(value); } - get observer() { + get observer(): Observable | null { + if (this.isUnsubscribe) { + return null; + } return this.subject.asObservable(); } + // Unsubscribe the subject might cause [UnsubscribedError] error if there is + // ongoing Observable execution. + // + // Maybe you should use the [Subscription] that returned when call subscribe on + // [Observable] to unsubscribe. unsubscribe = () => { - this.subject.unsubscribe(); + if (!this.isUnsubscribe) { + this.isUnsubscribe = true; + this.subject.unsubscribe(); + } }; }