diff --git a/packages/app/src/components/editor-mode-switch/index.tsx b/packages/app/src/components/editor-mode-switch/index.tsx index e2c1838d8b..d5f61085c3 100644 --- a/packages/app/src/components/editor-mode-switch/index.tsx +++ b/packages/app/src/components/editor-mode-switch/index.tsx @@ -14,6 +14,7 @@ import type { import { useTheme } from '@/providers/themeProvider'; import { EdgelessIcon, PaperIcon } from './icons'; import { useEditor } from '@/providers/editor-provider'; +import { useAppState } from '@/providers/app-state-provider/context'; const PaperItem = ({ active }: { active?: boolean }) => { const { @@ -66,8 +67,9 @@ export const EditorModeSwitch = ({ style = {}, }: AnimateRadioProps) => { const { mode: themeMode } = useTheme(); - const { mode, setMode, getPageMeta } = useEditor(); - const pageMeta = getPageMeta(); + const { getPageMeta, currentPage } = useAppState(); + const { mode, setMode } = useEditor(); + const pageMeta = currentPage?.pageId ? getPageMeta(currentPage.pageId) : null; const modifyRadioItemStatus = (): RadioItemStatus => { return { diff --git a/packages/app/src/components/editor.tsx b/packages/app/src/components/editor.tsx deleted file mode 100644 index d33c7007d3..0000000000 --- a/packages/app/src/components/editor.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import { useEditor } from '@/providers/editor-provider'; - -export const Editor = () => { - const editorContainer = useRef(null); - const { editor, onHistoryUpdated } = useEditor(); - const ref = useRef(); - useEffect(() => { - if (editor && ref.current?.page.id !== editor?.page.id) { - ref.current?.remove(); - ref.current = editor; - - editorContainer.current?.appendChild(editor); - } - }, [editor]); - - return ( -
- ); -}; - -export default Editor; diff --git a/packages/app/src/components/header/editor-header.tsx b/packages/app/src/components/header/editor-header.tsx index 98e6ca2e52..744ca447cd 100644 --- a/packages/app/src/components/header/editor-header.tsx +++ b/packages/app/src/components/header/editor-header.tsx @@ -7,6 +7,7 @@ import { } from './styles'; import { Content } from '@/ui/layout'; import { useEditor } from '@/providers/editor-provider'; +import { useAppState } from '@/providers/app-state-provider/context'; import EditorModeSwitch from '@/components/editor-mode-switch'; import QuickSearchButton from './quick-search-button'; import Header from './header'; @@ -14,8 +15,9 @@ import Header from './header'; export const EditorHeader = () => { const [title, setTitle] = useState(''); const [isHover, setIsHover] = useState(false); + const { getPageMeta, currentPage, editor } = useAppState(); - const { editor, onPropsUpdated, getPageMeta } = useEditor(); + const { onPropsUpdated } = useEditor(); useEffect(() => { onPropsUpdated(editor => { @@ -30,7 +32,7 @@ export const EditorHeader = () => { }, 300); }, [editor]); - const pageMeta = getPageMeta(); + const pageMeta = currentPage?.pageId ? getPageMeta(currentPage.pageId) : null; return (
diff --git a/packages/app/src/components/header/header.tsx b/packages/app/src/components/header/header.tsx index 1efc6ac042..81b5fca67d 100644 --- a/packages/app/src/components/header/header.tsx +++ b/packages/app/src/components/header/header.tsx @@ -18,6 +18,7 @@ import { TrashIcon, } from '@blocksuite/icons'; import { useEditor } from '@/providers/editor-provider'; +import { useAppState } from '@/providers/app-state-provider/context'; import ThemeModeSwitch from '@/components/theme-mode-switch'; import { IconButton, Button } from '@/ui/button'; import CloseIcon from '@mui/icons-material/Close'; @@ -29,18 +30,13 @@ import { SyncIcon } from './sync-icon'; import { toast } from '@/components/toast'; const PopoverContent = () => { - const { - editor, - mode, - setMode, - getPageMeta, - page, - toggleFavoritePage, - toggleDeletePage, - } = useEditor(); + const { getPageMeta, editor, currentPage } = useAppState(); + const { mode, setMode, toggleFavoritePage, toggleDeletePage } = useEditor(); const { confirm } = useConfirm(); - const { id, favorite, title } = getPageMeta(page?.id) ?? { + const { id, favorite, title } = (currentPage?.id + ? getPageMeta(currentPage.id) + : null) ?? { id: '', favorite: false, title: '', diff --git a/packages/app/src/components/page-list/operation-cell.tsx b/packages/app/src/components/page-list/operation-cell.tsx index 94ce303512..e49f8aa619 100644 --- a/packages/app/src/components/page-list/operation-cell.tsx +++ b/packages/app/src/components/page-list/operation-cell.tsx @@ -1,5 +1,8 @@ +import { useRouter } from 'next/router'; import { PageMeta, useEditor } from '@/providers/editor-provider'; import { useConfirm } from '@/providers/confirm-provider'; +import { useAppState } from '@/providers/app-state-provider/context'; +import { useGoToPage } from '@/providers/app-state-provider/hooks'; import { Menu, MenuItem } from '@/ui/menu'; import { Wrapper } from '@/ui/layout'; import { IconButton } from '@/ui/button'; @@ -16,7 +19,8 @@ import { toast } from '@/components/toast'; export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { const { id, favorite } = pageMeta; - const { openPage, toggleFavoritePage, toggleDeletePage } = useEditor(); + const goToPage = useGoToPage(); + const { toggleFavoritePage, toggleDeletePage } = useEditor(); const { confirm } = useConfirm(); const OperationMenu = ( @@ -31,7 +35,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { { - openPage(id); + goToPage(id); }} icon={} > @@ -68,8 +72,9 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { const { id } = pageMeta; - const { permanentlyDeletePage, toggleDeletePage, openPage, getPageMeta } = - useEditor(); + const goToPage = useGoToPage(); + const { getPageMeta } = useAppState(); + const { permanentlyDeletePage, toggleDeletePage } = useEditor(); const { confirm } = useConfirm(); return ( @@ -80,7 +85,7 @@ export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { onClick={() => { toggleDeletePage(id); toast(`${getPageMeta(id)?.title || 'Untitled'} restored`); - openPage(id); + goToPage(id); }} > diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index be3c82b278..f35a4aaefe 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -25,6 +25,7 @@ import Link from 'next/link'; import { Tooltip } from '@/ui/tooltip'; import { useEditor } from '@/providers/editor-provider'; import { useModal } from '@/providers/global-modal-provider'; +import { useGoToPage } from '@/providers/app-state-provider/hooks'; import { IconButton } from '@/ui/button'; import { WorkspaceSelector } from './WorkspaceSelector'; @@ -63,7 +64,8 @@ const FavoriteList = ({ showList }: { showList: boolean }) => { export const WorkSpaceSliderBar = () => { const { triggerQuickSearchModal, triggerImportModal } = useModal(); const [showSubFavorite, setShowSubFavorite] = useState(true); - const { createPage, getPageMeta, openPage } = useEditor(); + const { createPage } = useEditor(); + const goToPage = useGoToPage(); const router = useRouter(); const [showTip, setShowTip] = useState(false); @@ -127,7 +129,7 @@ export const WorkSpaceSliderBar = () => { { const page = await createPage(); - openPage(page.id); + goToPage(page.pageId); }} > New Page diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 647b390fca..d178de8d68 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -3,7 +3,6 @@ import dynamic from 'next/dynamic'; import '../../public/globals.css'; import '../../public/variable.css'; import './temporary.css'; -import { EditorProvider } from '@/providers/editor-provider'; import { ModalProvider } from '@/providers/global-modal-provider'; import { AppStateProvider } from '@/providers/app-state-provider/provider'; import { Logger } from '@toeverything/pathfinder-logger'; @@ -46,7 +45,6 @@ function MyApp({ Component, pageProps }: AppProps) { , , , , diff --git a/packages/app/src/pages/index.tsx b/packages/app/src/pages/index.tsx index fcc7770e04..ae21815c9c 100644 --- a/packages/app/src/pages/index.tsx +++ b/packages/app/src/pages/index.tsx @@ -1,27 +1,7 @@ import type { NextPage } from 'next'; -import { styled } from '@/styles'; -import { EditorHeader } from '@/components/header'; -import EdgelessToolbar from '@/components/edgeless-toolbar'; -import MobileModal from '@/components/mobile-modal'; -import Editor from '@/components/editor'; - -const StyledEditorContainer = styled('div')(({ theme }) => { - return { - height: 'calc(100vh - 60px)', - }; -}); const Home: NextPage = () => { - return ( - <> - - - - - - - - ); + return
Home Page
; }; export default Home; diff --git a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx index 3d0eab2fb0..9250215513 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -21,7 +21,7 @@ const Home: NextPage = () => { const editorContainer = useRef(null); const workspace = useLoadWorkspace(); const page = useLoadPage(); - const { createEditor } = useAppState(); + const { createEditor, setEditor } = useAppState(); useEffect(() => { const ret = () => { @@ -38,6 +38,7 @@ const Home: NextPage = () => { const editor = createEditor(page); if (editor) { editorContainer.current?.appendChild(editor); + setEditor(editor); if (page.isEmpty) { const title = 'Welcome to the AFFiNE Alpha'; const pageId = page.addBlock({ diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index cf972024f5..57ff892fcf 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -4,6 +4,7 @@ import type { Workspace } from '@pathfinder/data-services'; import type { Workspace as StoreWorkspace, Page as StorePage, + PageMeta, } from '@blocksuite/store'; import type { EditorContainer } from '@blocksuite/editor'; @@ -15,16 +16,20 @@ export interface AppStateValue { currentWorkspace: StoreWorkspace | null; currentPage: StorePage | null; + + editor: EditorContainer | null; } export interface AppStateContext extends AppStateValue { setState: (state: AppStateValue) => void; createEditor: (page: StorePage) => EditorContainer | null; + setEditor: (editor: EditorContainer) => void; loadWorkspace?: ( workspaceId: string ) => Promise | null; loadPage: (pageId: string) => Promise | null; createPage: (pageId?: string) => Promise | null; + getPageMeta: (pageId: string) => PageMeta | null; } export const AppState = createContext({ @@ -36,11 +41,15 @@ export const AppState = createContext({ currentPage: null, + editor: null, + setState: () => {}, createEditor: () => null, + setEditor: () => {}, loadWorkspace: undefined, loadPage: () => null, createPage: () => null, + getPageMeta: () => null, }); export const useAppState = () => { diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index 9927e98279..d5dcc262d0 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -4,6 +4,9 @@ import { createWebsocketDocProvider, IndexedDBDocProvider, } from '@blocksuite/store'; +import '@blocksuite/blocks'; +import '@blocksuite/blocks/style'; + import type { Page } from '@blocksuite/store'; import { BlockSchema, createEditor } from '@blocksuite/editor'; import type { AppStateContext } from './context'; diff --git a/packages/app/src/providers/app-state-provider/hooks.ts b/packages/app/src/providers/app-state-provider/hooks.ts index b7f81ccf1f..3ea5ac37c2 100644 --- a/packages/app/src/providers/app-state-provider/hooks.ts +++ b/packages/app/src/providers/app-state-provider/hooks.ts @@ -28,3 +28,12 @@ export const useLoadPage = () => { return currentPage?.pageId === pageId ? currentPage : null; }; + +export const useGoToPage = () => { + const router = useRouter(); + const { currentWorkspaceId } = useAppState(); + + return (pageId: string) => { + router.push(`/workspace/${currentWorkspaceId}/${pageId}`); + }; +}; diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index ba21a309fc..fb1593c49a 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -22,6 +22,8 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { currentWorkspace: null, currentPage: null, + + editor: null, }); const [loadWorkspaceHandler, _setLoadWorkspaceHandler] = @@ -79,6 +81,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { return editor; }, + setEditor: (editor: AppStateValue['editor']) => { + setState(state => ({ ...state, editor })); + }, loadWorkspace: async (workspaceId: string) => { const workspace = (await loadWorkspaceHandler?.(workspaceId)) || null; setState(state => ({ @@ -109,6 +114,16 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { resolve(addedPageId); }); }), + getPageMeta: (pageId: string) => { + const { currentWorkspace } = state; + if (!currentWorkspace) { + return null; + } + return ( + currentWorkspace.meta.pageMetas.find(page => page.id === pageId) || + null + ); + }, }), [state, setState, loadWorkspaceHandler, createEditorHandler] );