From 64cf297399b53ea0bd1a319f3d216b530d4b9045 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Thu, 13 Jul 2023 20:14:30 +0800 Subject: [PATCH] refactor(web): move current atoms into plugin infra (#3220) --- apps/web/src/bootstrap/index.ts | 50 ++++++++++++++++++- .../affine/affine-error-eoundary.tsx | 14 +++--- .../header-right-items/editor-option-menu.tsx | 6 +-- .../header-right-items/trash-button-group.tsx | 5 +- .../web/src/hooks/current/use-current-mode.ts | 4 +- .../src/hooks/current/use-current-page-id.ts | 12 ----- .../hooks/current/use-current-workspace.ts | 12 ++--- .../hooks/root/use-on-transform-workspace.ts | 4 +- apps/web/src/layouts/workspace-layout.tsx | 13 ++--- .../workspace/[workspaceId]/[pageId].tsx | 6 +-- apps/web/src/providers/modal-provider.tsx | 14 +++--- packages/plugin-infra/src/manager.ts | 2 + packages/workspace/src/atom.ts | 47 ----------------- 13 files changed, 91 insertions(+), 98 deletions(-) delete mode 100644 apps/web/src/hooks/current/use-current-page-id.ts diff --git a/apps/web/src/bootstrap/index.ts b/apps/web/src/bootstrap/index.ts index ee4084e91f..7c398961de 100644 --- a/apps/web/src/bootstrap/index.ts +++ b/apps/web/src/bootstrap/index.ts @@ -13,7 +13,12 @@ import { } from '@affine/workspace/migration'; import { createIndexedDBDownloadProvider } from '@affine/workspace/providers'; import { assertExists } from '@blocksuite/global/utils'; -import { rootStore } from '@toeverything/plugin-infra/manager'; +import { + currentPageIdAtom, + currentWorkspaceIdAtom, + rootStore, +} from '@toeverything/plugin-infra/manager'; +import Router from 'next/router'; import { WorkspaceAdapters } from '../adapters/workspace'; @@ -31,6 +36,49 @@ if (process.env.NODE_ENV === 'development') { console.log('Runtime Preset', runtimeConfig); } +if (!environment.isServer) { + currentWorkspaceIdAtom.onMount = set => { + if (environment.isBrowser) { + const callback = (url: string) => { + const value = url.split('/')[2]; + if (value === 'all' || value === 'trash' || value === 'shared') { + set(null); + } else if (value) { + set(value); + localStorage.setItem('last_workspace_id', value); + } else { + set(null); + } + }; + callback(window.location.pathname); + Router.events.on('routeChangeStart', callback); + return () => { + Router.events.off('routeChangeStart', callback); + }; + } + return; + }; + + currentPageIdAtom.onMount = set => { + if (environment.isBrowser) { + const callback = (url: string) => { + const value = url.split('/')[3]; + if (value) { + set(value); + } else { + set(null); + } + }; + callback(window.location.pathname); + Router.events.on('routeChangeStart', callback); + return () => { + Router.events.off('routeChangeStart', callback); + }; + } + return; + }; +} + if (runtimeConfig.enablePlugin && !environment.isServer) { import('@affine/copilot'); } diff --git a/apps/web/src/components/affine/affine-error-eoundary.tsx b/apps/web/src/components/affine/affine-error-eoundary.tsx index 68dc7b4033..1ea5743aa8 100644 --- a/apps/web/src/components/affine/affine-error-eoundary.tsx +++ b/apps/web/src/components/affine/affine-error-eoundary.tsx @@ -4,12 +4,12 @@ import type { WorkspaceNotFoundError, } from '@affine/env/constant'; import { PageNotFoundError } from '@affine/env/constant'; +import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom'; import { - rootCurrentPageIdAtom, - rootCurrentWorkspaceIdAtom, - rootWorkspacesMetadataAtom, -} from '@affine/workspace/atom'; -import { rootStore } from '@toeverything/plugin-infra/manager'; + currentPageIdAtom, + currentWorkspaceIdAtom, + rootStore, +} from '@toeverything/plugin-infra/manager'; import { useAtomValue } from 'jotai/react'; import { Provider } from 'jotai/react'; import type { NextRouter } from 'next/router'; @@ -35,8 +35,8 @@ interface AffineErrorBoundaryState { export const DumpInfo = (props: Pick) => { const router = props.router; const metadata = useAtomValue(rootWorkspacesMetadataAtom); - const currentWorkspaceId = useAtomValue(rootCurrentWorkspaceIdAtom); - const currentPageId = useAtomValue(rootCurrentPageIdAtom); + const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom); + const currentPageId = useAtomValue(currentPageIdAtom); const path = router.asPath; const query = router.query; return ( diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx index 5472dc6469..8fd863bda8 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/editor-option-menu.tsx @@ -14,13 +14,13 @@ import { useBlockSuitePageMeta, usePageMetaHelper, } from '@toeverything/hooks/use-block-suite-page-meta'; -import { useAtom } from 'jotai'; +import { currentPageIdAtom } from '@toeverything/plugin-infra/manager'; +import { useAtom, useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { pageSettingFamily } from '../../../../atoms'; import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper'; -import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id'; import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace'; import { toast } from '../../../../utils'; import { MenuThemeModeSwitch } from '../header-right-items/theme-mode-switch'; @@ -56,7 +56,7 @@ const PageMenu = () => { const t = useAFFiNEI18N(); // fixme(himself65): remove these hooks ASAP const [workspace] = useCurrentWorkspace(); - const [pageId] = useCurrentPageId(); + const pageId = useAtomValue(currentPageIdAtom); assertExists(workspace); assertExists(pageId); const blockSuiteWorkspace = workspace.blockSuiteWorkspace; diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx index fd55415657..74884cc271 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/trash-button-group.tsx @@ -2,17 +2,18 @@ import { Button, Confirm } from '@affine/component'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; +import { currentPageIdAtom } from '@toeverything/plugin-infra/manager'; +import { useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper'; -import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id'; import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace'; export const TrashButtonGroup = () => { // fixme(himself65): remove these hooks ASAP const [workspace] = useCurrentWorkspace(); - const [pageId] = useCurrentPageId(); + const pageId = useAtomValue(currentPageIdAtom); assertExists(workspace); assertExists(pageId); const blockSuiteWorkspace = workspace.blockSuiteWorkspace; diff --git a/apps/web/src/hooks/current/use-current-mode.ts b/apps/web/src/hooks/current/use-current-mode.ts index 2cc31a8fbb..d7bd2cced8 100644 --- a/apps/web/src/hooks/current/use-current-mode.ts +++ b/apps/web/src/hooks/current/use-current-mode.ts @@ -1,10 +1,10 @@ -import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; +import { currentPageIdAtom } from '@toeverything/plugin-infra/manager'; import { atom, useAtomValue } from 'jotai'; import { pageSettingFamily } from '../../atoms'; const currentModeAtom = atom<'page' | 'edgeless'>(get => { - const pageId = get(rootCurrentPageIdAtom); + const pageId = get(currentPageIdAtom); // fixme(himself65): pageId should not be null if (!pageId) { return 'page'; diff --git a/apps/web/src/hooks/current/use-current-page-id.ts b/apps/web/src/hooks/current/use-current-page-id.ts deleted file mode 100644 index afa167aa59..0000000000 --- a/apps/web/src/hooks/current/use-current-page-id.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; -import { useAtom } from 'jotai'; - -/** - * @deprecated Use `rootCurrentPageIdAtom` directly instead. - */ -export function useCurrentPageId(): [ - string | null, - (newId: string | null) => void, -] { - return useAtom(rootCurrentPageIdAtom); -} diff --git a/apps/web/src/hooks/current/use-current-workspace.ts b/apps/web/src/hooks/current/use-current-workspace.ts index 9c040e3500..a5915644c8 100644 --- a/apps/web/src/hooks/current/use-current-workspace.ts +++ b/apps/web/src/hooks/current/use-current-workspace.ts @@ -1,8 +1,8 @@ -import { - rootCurrentPageIdAtom, - rootCurrentWorkspaceIdAtom, -} from '@affine/workspace/atom'; import { assertExists } from '@blocksuite/global/utils'; +import { + currentPageIdAtom, + currentWorkspaceIdAtom, +} from '@toeverything/plugin-infra/manager'; import { useAtom, useSetAtom } from 'jotai'; import { useCallback, useEffect } from 'react'; @@ -24,7 +24,7 @@ export function useCurrentWorkspace(): [ AllWorkspace, (id: string | null) => void, ] { - const [id, setId] = useAtom(rootCurrentWorkspaceIdAtom); + const [id, setId] = useAtom(currentWorkspaceIdAtom); assertExists(id); const currentWorkspace = useWorkspace(id); useEffect(() => { @@ -35,7 +35,7 @@ export function useCurrentWorkspace(): [ }) ); }, [currentWorkspace]); - const setPageId = useSetAtom(rootCurrentPageIdAtom); + const setPageId = useSetAtom(currentPageIdAtom); return [ currentWorkspace, useCallback( diff --git a/apps/web/src/hooks/root/use-on-transform-workspace.ts b/apps/web/src/hooks/root/use-on-transform-workspace.ts index 95cf9e04de..f9766dd152 100644 --- a/apps/web/src/hooks/root/use-on-transform-workspace.ts +++ b/apps/web/src/hooks/root/use-on-transform-workspace.ts @@ -1,6 +1,6 @@ import type { WorkspaceRegistry } from '@affine/env/workspace'; import type { WorkspaceFlavour } from '@affine/env/workspace'; -import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom'; +import { currentPageIdAtom } from '@toeverything/plugin-infra/manager'; import { useSetAtom } from 'jotai'; import { useCallback } from 'react'; @@ -8,7 +8,7 @@ import { useTransformWorkspace } from '../use-transform-workspace'; export function useOnTransformWorkspace() { const transformWorkspace = useTransformWorkspace(); - const setWorkspaceId = useSetAtom(rootCurrentWorkspaceIdAtom); + const setWorkspaceId = useSetAtom(currentPageIdAtom); return useCallback( async ( from: From, diff --git a/apps/web/src/layouts/workspace-layout.tsx b/apps/web/src/layouts/workspace-layout.tsx index 52e00dba88..2e0af3443e 100644 --- a/apps/web/src/layouts/workspace-layout.tsx +++ b/apps/web/src/layouts/workspace-layout.tsx @@ -18,8 +18,6 @@ import { import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { rootBlockHubAtom, - rootCurrentPageIdAtom, - rootCurrentWorkspaceIdAtom, rootWorkspacesMetadataAtom, } from '@affine/workspace/atom'; import { assertEquals, assertExists } from '@blocksuite/global/utils'; @@ -36,6 +34,10 @@ import { } from '@dnd-kit/core'; import { usePassiveWorkspaceEffect } from '@toeverything/hooks/use-block-suite-workspace'; import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper'; +import { + currentPageIdAtom, + currentWorkspaceIdAtom, +} from '@toeverything/plugin-infra/manager'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import Head from 'next/head'; import { useRouter } from 'next/router'; @@ -111,7 +113,7 @@ if (globalThis.HALTING_PROBLEM_TIMEOUT === undefined) { export const CurrentWorkspaceContext = ({ children, }: PropsWithChildren): ReactElement => { - const workspaceId = useAtomValue(rootCurrentWorkspaceIdAtom); + const workspaceId = useAtomValue(currentWorkspaceIdAtom); const metadata = useAtomValue(rootWorkspacesMetadataAtom); const exist = metadata.find(m => m.id === workspaceId); const router = useRouter(); @@ -149,7 +151,7 @@ export const CurrentWorkspaceContext = ({ export const WorkspaceLayout: FC = function WorkspacesSuspense({ children }) { useTrackRouterHistoryEffect(); - const currentWorkspaceId = useAtomValue(rootCurrentWorkspaceIdAtom); + const currentWorkspaceId = useAtomValue(currentWorkspaceIdAtom); const jotaiWorkspaces = useAtomValue(rootWorkspacesMetadataAtom); const meta = useMemo( () => jotaiWorkspaces.find(x => x.id === currentWorkspaceId), @@ -181,8 +183,7 @@ export const WorkspaceLayout: FC = export const WorkspaceLayoutInner: FC = ({ children }) => { const [currentWorkspace] = useCurrentWorkspace(); - const setCurrentPageId = useSetAtom(rootCurrentPageIdAtom); - const currentPageId = useAtomValue(rootCurrentPageIdAtom); + const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom); const router = useRouter(); const { jumpToPage } = useRouterHelper(router); diff --git a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx index 369e69b91d..2cb6185c22 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -4,10 +4,10 @@ import { useCollectionManager, } from '@affine/component/page-list'; import { WorkspaceSubPath } from '@affine/env/workspace'; -import { rootCurrentPageIdAtom } from '@affine/workspace/atom'; import type { EditorContainer } from '@blocksuite/editor'; import { assertExists } from '@blocksuite/global/utils'; import type { Page } from '@blocksuite/store'; +import { currentPageIdAtom } from '@toeverything/plugin-infra/manager'; import { useAtom, useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; import type React from 'react'; @@ -22,7 +22,7 @@ import type { NextPageWithLayout } from '../../../shared'; const WorkspaceDetail: React.FC = () => { const router = useRouter(); const { openPage, jumpToSubPath } = useRouterHelper(router); - const currentPageId = useAtomValue(rootCurrentPageIdAtom); + const currentPageId = useAtomValue(currentPageIdAtom); const [currentWorkspace] = useCurrentWorkspace(); assertExists(currentWorkspace); assertExists(currentPageId); @@ -73,7 +73,7 @@ const WorkspaceDetail: React.FC = () => { const WorkspaceDetailPage: NextPageWithLayout = () => { const router = useRouter(); const [currentWorkspace] = useCurrentWorkspace(); - const [currentPageId, setCurrentPageId] = useAtom(rootCurrentPageIdAtom); + const [currentPageId, setCurrentPageId] = useAtom(currentPageIdAtom); const page = currentPageId ? currentWorkspace.blockSuiteWorkspace.getPage(currentPageId) : null; diff --git a/apps/web/src/providers/modal-provider.tsx b/apps/web/src/providers/modal-provider.tsx index 5c1cf99bc4..495a90bdf7 100644 --- a/apps/web/src/providers/modal-provider.tsx +++ b/apps/web/src/providers/modal-provider.tsx @@ -1,11 +1,11 @@ import { WorkspaceSubPath } from '@affine/env/workspace'; -import { - rootCurrentPageIdAtom, - rootCurrentWorkspaceIdAtom, - rootWorkspacesMetadataAtom, -} from '@affine/workspace/atom'; +import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom'; import { assertExists } from '@blocksuite/global/utils'; import { arrayMove } from '@dnd-kit/sortable'; +import { + currentPageIdAtom, + currentWorkspaceIdAtom, +} from '@toeverything/plugin-infra/manager'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { useRouter } from 'next/router'; import type { FC, ReactElement } from 'react'; @@ -123,9 +123,9 @@ export const AllWorkspaceModals = (): ReactElement => { const workspaces = useAtomValue(rootWorkspacesMetadataAtom); const setWorkspaces = useSetAtom(rootWorkspacesMetadataAtom); const [currentWorkspaceId, setCurrentWorkspaceId] = useAtom( - rootCurrentWorkspaceIdAtom + currentWorkspaceIdAtom ); - const setCurrentPageId = useSetAtom(rootCurrentPageIdAtom); + const setCurrentPageId = useSetAtom(currentPageIdAtom); const [transitioning, transition] = useTransition(); const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); diff --git a/packages/plugin-infra/src/manager.ts b/packages/plugin-infra/src/manager.ts index e83fd25e90..91adb14e85 100644 --- a/packages/plugin-infra/src/manager.ts +++ b/packages/plugin-infra/src/manager.ts @@ -12,6 +12,8 @@ export const rootStore = createStore(); // todo: for now every plugin is enabled by default export const affinePluginsAtom = atom>>({}); +export const currentPageIdAtom = atom(null); +export const currentWorkspaceIdAtom = atom(null); export function definePlugin( definition: Definition, diff --git a/packages/workspace/src/atom.ts b/packages/workspace/src/atom.ts index d32f4f0f3e..5304cfa4c0 100644 --- a/packages/workspace/src/atom.ts +++ b/packages/workspace/src/atom.ts @@ -4,7 +4,6 @@ import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils'; import type { BlockHub } from '@blocksuite/blocks'; import { assertExists } from '@blocksuite/global/utils'; import { atom } from 'jotai'; -import Router from 'next/router'; import { z } from 'zod'; const rootWorkspaceMetadataV1Schema = z.object({ @@ -232,52 +231,6 @@ export const rootWorkspacesMetadataAtom = atom< } ); -// two more atoms to store the current workspace and page -export const rootCurrentWorkspaceIdAtom = atom(null); - -rootCurrentWorkspaceIdAtom.onMount = set => { - if (environment.isBrowser) { - const callback = (url: string) => { - const value = url.split('/')[2]; - if (value === 'all' || value === 'trash' || value === 'shared') { - set(null); - } else if (value) { - set(value); - localStorage.setItem('last_workspace_id', value); - } else { - set(null); - } - }; - callback(window.location.pathname); - Router.events.on('routeChangeStart', callback); - return () => { - Router.events.off('routeChangeStart', callback); - }; - } - return; -}; - -export const rootCurrentPageIdAtom = atom(null); - -rootCurrentPageIdAtom.onMount = set => { - if (environment.isBrowser) { - const callback = (url: string) => { - const value = url.split('/')[3]; - if (value) { - set(value); - } else { - set(null); - } - }; - callback(window.location.pathname); - Router.events.on('routeChangeStart', callback); - return () => { - Router.events.off('routeChangeStart', callback); - }; - } - return; -}; - // blocksuite atoms, // each app should have only one block-hub in the same time export const rootBlockHubAtom = atom | null>(null);