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'); });