diff --git a/apps/web/src/bootstrap/index.ts b/apps/web/src/bootstrap/index.ts
index d11bf29810..aa609a326f 100644
--- a/apps/web/src/bootstrap/index.ts
+++ b/apps/web/src/bootstrap/index.ts
@@ -6,7 +6,11 @@ import type {
} from '@affine/env/workspace';
import { WorkspaceFlavour, WorkspaceVersion } from '@affine/env/workspace';
import type { RootWorkspaceMetadata } from '@affine/workspace/atom';
-import { workspaceAdaptersAtom } from '@affine/workspace/atom';
+import {
+ type RootWorkspaceMetadataV2,
+ rootWorkspacesMetadataAtom,
+ workspaceAdaptersAtom,
+} from '@affine/workspace/atom';
import {
migrateLocalBlobStorage,
upgradeV1ToV2,
@@ -77,6 +81,36 @@ if (!environment.isServer) {
}
return;
};
+
+ const createFirst = (): RootWorkspaceMetadataV2[] => {
+ const Plugins = Object.values(WorkspaceAdapters).sort(
+ (a, b) => a.loadPriority - b.loadPriority
+ );
+
+ return Plugins.flatMap(Plugin => {
+ return Plugin.Events['app:init']?.().map(
+ id =>
+ ({
+ id,
+ flavour: Plugin.flavour,
+ // new workspace should all support sub-doc feature
+ version: WorkspaceVersion.SubDoc,
+ }) satisfies RootWorkspaceMetadataV2
+ );
+ }).filter((ids): ids is RootWorkspaceMetadataV2 => !!ids);
+ };
+
+ rootStore
+ .get(rootWorkspacesMetadataAtom)
+ .then(meta => {
+ if (meta.length === 0 && localStorage.getItem('is-first-open') === null) {
+ const result = createFirst();
+ console.info('create first workspace', result);
+ localStorage.setItem('is-first-open', 'false');
+ rootStore.set(rootWorkspacesMetadataAtom, result).catch(console.error);
+ }
+ })
+ .catch(console.error);
}
if (runtimeConfig.enablePlugin && !environment.isServer) {
diff --git a/apps/web/src/pages/index.tsx b/apps/web/src/pages/index.tsx
index d2898abc11..2a695aa8be 100644
--- a/apps/web/src/pages/index.tsx
+++ b/apps/web/src/pages/index.tsx
@@ -1,15 +1,14 @@
import { WorkspaceFallback } from '@affine/component/workspace';
import { DebugLogger } from '@affine/debug';
-import { WorkspaceSubPath, WorkspaceVersion } from '@affine/env/workspace';
-import type { RootWorkspaceMetadataV2 } from '@affine/workspace/atom';
+import { WorkspaceSubPath } from '@affine/env/workspace';
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
+import { NoSsr } from '@mui/material';
import { getWorkspace } from '@toeverything/plugin-infra/__internal__/workspace';
-import { useAtom } from 'jotai';
+import { useAtomValue } from 'jotai';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import { Suspense, useEffect } from 'react';
-import { WorkspaceAdapters } from '../adapters/workspace';
import { RouteLogic, useRouterHelper } from '../hooks/use-router-helper';
import { useWorkspace } from '../hooks/use-workspace';
import { useAppHelper } from '../hooks/use-workspaces';
@@ -29,46 +28,9 @@ const WorkspaceLoader = (props: AllWorkspaceLoaderProps): null => {
const IndexPageInner = () => {
const router = useRouter();
const { jumpToPage, jumpToSubPath } = useRouterHelper(router);
- const [meta, setMeta] = useAtom(rootWorkspacesMetadataAtom);
+ const meta = useAtomValue(rootWorkspacesMetadataAtom);
const helper = useAppHelper();
- useEffect(() => {
- const abortController = new AbortController();
- const signal = abortController.signal;
- const createFirst = (): RootWorkspaceMetadataV2[] => {
- if (signal.aborted) {
- return [];
- }
-
- const Plugins = Object.values(WorkspaceAdapters).sort(
- (a, b) => a.loadPriority - b.loadPriority
- );
-
- return Plugins.flatMap(Plugin => {
- return Plugin.Events['app:init']?.().map(
- id =>
- ({
- id,
- flavour: Plugin.flavour,
- // new workspace should all support sub-doc feature
- version: WorkspaceVersion.SubDoc,
- }) satisfies RootWorkspaceMetadataV2
- );
- }).filter((ids): ids is RootWorkspaceMetadataV2 => !!ids);
- };
-
- if (meta.length === 0 && localStorage.getItem('is-first-open') === null) {
- meta.push(...createFirst());
- console.info('create first workspace', meta);
- localStorage.setItem('is-first-open', 'false');
- setMeta(meta).catch(console.error);
- }
-
- return () => {
- abortController.abort();
- };
- }, [meta, setMeta]);
-
useEffect(() => {
if (!router.isReady) {
return;
@@ -136,9 +98,11 @@ const IndexPageInner = () => {
const IndexPage: NextPage = () => {
return (
- }>
-
-
+
+ }>
+
+
+
);
};
diff --git a/packages/workspace/src/atom.ts b/packages/workspace/src/atom.ts
index 22b7283177..1cca2d72a5 100644
--- a/packages/workspace/src/atom.ts
+++ b/packages/workspace/src/atom.ts
@@ -187,7 +187,6 @@ export const rootWorkspacesMetadataAtom = atom<
const metadataMap = new Map(metadata.map(x => [x.id, x]));
metadata = Array.from(metadataMap.values());
-
// write back to localStorage
rootWorkspaceMetadataArraySchema.parse(metadata);
localStorage.setItem(METADATA_STORAGE_KEY, JSON.stringify(metadata));
diff --git a/tests/affine-legacy/0.7.0-canary.18/e2e/basic.spec.ts b/tests/affine-legacy/0.7.0-canary.18/e2e/basic.spec.ts
index ddf1941765..1a4896f40e 100644
--- a/tests/affine-legacy/0.7.0-canary.18/e2e/basic.spec.ts
+++ b/tests/affine-legacy/0.7.0-canary.18/e2e/basic.spec.ts
@@ -1,6 +1,6 @@
import { resolve } from 'node:path';
-import { test } from '@playwright/test';
+import { expect, test } from '@playwright/test';
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
@@ -59,6 +59,9 @@ test('init page', async ({ page, context }) => {
await page.waitForSelector('v-line', {
timeout: 10000,
});
+ await page.getByTestId('new-page-button').click();
+ const locator = page.locator('v-line').nth(0);
+ await locator.fill('hello');
const currentWorkspaceId: string = await page.evaluate(
() => (globalThis as any).currentWorkspace.id
@@ -81,7 +84,10 @@ test('init page', async ({ page, context }) => {
await switchToNext();
await page.waitForTimeout(1000);
await page.goto('http://localhost:8081/');
+ await page.waitForTimeout(1000);
+ await page.goto('http://localhost:8081/');
await page.waitForSelector('v-line', {
timeout: 10000,
});
+ expect(await page.locator('v-line').nth(0).textContent()).toBe('hello');
});