diff --git a/packages/common/infra/src/workspace/engine/sync/engine.ts b/packages/common/infra/src/workspace/engine/sync/engine.ts
index 108b6a646..375682889 100644
--- a/packages/common/infra/src/workspace/engine/sync/engine.ts
+++ b/packages/common/infra/src/workspace/engine/sync/engine.ts
@@ -1,8 +1,10 @@
import { DebugLogger } from '@affine/debug';
import { Slot } from '@blocksuite/global/utils';
+import { Observable } from 'rxjs';
import type { Doc } from 'yjs';
import { createIdentifier } from '../../../di';
+import { LiveData } from '../../../livedata';
import { SharedPriorityTarget } from '../../../utils/async-queue';
import { MANUALLY_STOP, throwIfAborted } from '../../../utils/throw-if-aborted';
import { SyncEngineStep, SyncPeerStep } from './consts';
@@ -65,6 +67,21 @@ export class SyncEngine {
this._status = s;
this.onStatusChange.emit(s);
}
+ isRootDocLoaded = LiveData.from(
+ new Observable(observer => {
+ observer.next(
+ this.status.local
+ ? this.status.local.step > SyncPeerStep.LoadingRootDoc
+ : false
+ );
+ this.onStatusChange.on(status => {
+ observer.next(
+ status.local ? status.local.step > SyncPeerStep.LoadingRootDoc : false
+ );
+ });
+ }),
+ false
+ );
priorityTarget = new SharedPriorityTarget();
diff --git a/packages/frontend/core/src/pages/workspace/index.tsx b/packages/frontend/core/src/pages/workspace/index.tsx
index 6848d122c..0de813651 100644
--- a/packages/frontend/core/src/pages/workspace/index.tsx
+++ b/packages/frontend/core/src/pages/workspace/index.tsx
@@ -10,13 +10,7 @@ import {
useServiceOptional,
} from '@toeverything/infra/di';
import { useLiveData } from '@toeverything/infra/livedata';
-import {
- type ReactElement,
- Suspense,
- useEffect,
- useMemo,
- useState,
-} from 'react';
+import { type ReactElement, Suspense, useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { AffineErrorBoundary } from '../../components/affine/affine-error-boundary';
@@ -80,34 +74,15 @@ export const Component = (): ReactElement => {
const currentWorkspace = useServiceOptional(Workspace);
- const [workspaceIsLoading, setWorkspaceIsLoading] = useState(true);
-
- // hotfix: avoid doing operation, before workspace is loaded
- useEffect(() => {
- if (!workspace) {
- setWorkspaceIsLoading(true);
- return;
- }
- const metaYMap = workspace.blockSuiteWorkspace.doc.getMap('meta');
-
- const handleYMapChanged = () => {
- setWorkspaceIsLoading(metaYMap.size === 0);
- };
-
- handleYMapChanged();
-
- metaYMap.observe(handleYMapChanged);
- return () => {
- metaYMap.unobserve(handleYMapChanged);
- };
- }, [workspace]);
+ // avoid doing operation, before workspace is loaded
+ const isRootDocLoaded = useLiveData(workspace?.engine.sync.isRootDocLoaded);
// if listLoading is false, we can show 404 page, otherwise we should show loading page.
if (listLoading === false && meta === undefined) {
return ;
}
- if (!currentWorkspace || workspaceIsLoading) {
+ if (!currentWorkspace || !isRootDocLoaded) {
return ;
}