diff --git a/packages/app/src/components/edgeless-toolbar/index.tsx b/packages/app/src/components/edgeless-toolbar/index.tsx index 00f821e6ba..54076c974d 100644 --- a/packages/app/src/components/edgeless-toolbar/index.tsx +++ b/packages/app/src/components/edgeless-toolbar/index.tsx @@ -16,7 +16,9 @@ import { } from './icons'; import { Tooltip } from '@/ui/tooltip'; import Slide from '@mui/material/Slide'; -import { useEditor } from '@/providers/editor-provider'; +import useCurrentPageMeta from '@/hooks/use-current-page-meta'; +import { useAppState } from '@/providers/app-state-provider'; +import useHistoryUpdated from '@/hooks/use-history-update'; const toolbarList1 = [ { @@ -95,7 +97,8 @@ const toolbarList2 = [ const UndoRedo = () => { const [canUndo, setCanUndo] = useState(false); const [canRedo, setCanRedo] = useState(false); - const { onHistoryUpdated, page } = useEditor(); + const { currentPage } = useAppState(); + const onHistoryUpdated = useHistoryUpdated(); useEffect(() => { onHistoryUpdated(page => { @@ -110,7 +113,7 @@ const UndoRedo = () => { { - page?.undo(); + currentPage?.undo(); }} > @@ -120,7 +123,7 @@ const UndoRedo = () => { { - page?.redo(); + currentPage?.redo(); }} > @@ -131,7 +134,7 @@ const UndoRedo = () => { }; export const EdgelessToolbar = () => { - const { mode } = useEditor(); + const { mode } = useCurrentPageMeta() || {}; return ( { const { @@ -67,9 +67,8 @@ export const EditorModeSwitch = ({ style = {}, }: AnimateRadioProps) => { const { mode: themeMode } = useTheme(); - const { getPageMeta, currentPage } = useAppState(); - const { mode, setMode } = useEditor(); - const pageMeta = currentPage?.pageId ? getPageMeta(currentPage.pageId) : null; + const { changePageMode } = usePageHelper(); + const { trash, mode = 'page', id = '' } = useCurrentPageMeta() || {}; const modifyRadioItemStatus = (): RadioItemStatus => { return { @@ -103,7 +102,7 @@ export const EditorModeSwitch = ({ data-testid="editor-mode-switcher" shrink={!isHover} style={style} - disabled={!!pageMeta?.trash} + disabled={!!trash} > { - setMode('page'); + changePageMode(id, 'page'); }} onMouseEnter={() => { setRadioItemStatus({ @@ -132,7 +131,7 @@ export const EditorModeSwitch = ({ active={mode === 'edgeless'} status={radioItemStatus.right} onClick={() => { - setMode('edgeless'); + changePageMode(id, 'edgeless'); }} onMouseEnter={() => { setRadioItemStatus({ diff --git a/packages/app/src/components/header/editor-header.tsx b/packages/app/src/components/header/editor-header.tsx index 744ca447cd..14ee04c21f 100644 --- a/packages/app/src/components/header/editor-header.tsx +++ b/packages/app/src/components/header/editor-header.tsx @@ -6,18 +6,19 @@ import { StyledTitleWrapper, } 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'; +import usePropsUpdated from '@/hooks/use-props-updated'; +import useCurrentPageMeta from '@/hooks/use-current-page-meta'; export const EditorHeader = () => { const [title, setTitle] = useState(''); const [isHover, setIsHover] = useState(false); - const { getPageMeta, currentPage, editor } = useAppState(); - - const { onPropsUpdated } = useEditor(); + const { editor } = useAppState(); + const pageMeta = useCurrentPageMeta(); + const onPropsUpdated = usePropsUpdated(); useEffect(() => { onPropsUpdated(editor => { @@ -32,8 +33,6 @@ export const EditorHeader = () => { }, 300); }, [editor]); - const pageMeta = currentPage?.pageId ? getPageMeta(currentPage.pageId) : null; - return (
{title && ( diff --git a/packages/app/src/components/header/header.tsx b/packages/app/src/components/header/header.tsx index 7aeee29cde..bdf6503c3e 100644 --- a/packages/app/src/components/header/header.tsx +++ b/packages/app/src/components/header/header.tsx @@ -17,7 +17,6 @@ import { FavouritedIcon, 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'; @@ -31,18 +30,16 @@ import { toast } from '@/components/toast'; import useCurrentPageMeta from '@/hooks/use-current-page-meta'; import { usePageHelper } from '@/hooks/use-page-helper'; const PopoverContent = () => { - const { getPageMeta, editor, currentPage } = useAppState(); + const { editor } = useAppState(); const { toggleFavoritePage, toggleDeletePage } = usePageHelper(); - const { mode, setMode } = useEditor(); + const { changePageMode } = usePageHelper(); const { confirm } = useConfirm(); - - const { id, favorite, title } = (currentPage?.id - ? getPageMeta(currentPage.id) - : null) ?? { - id: '', - favorite: false, - title: '', - }; + const { + mode = 'page', + id = '', + favorite = false, + title = '', + } = useCurrentPageMeta() || {}; return ( <> @@ -58,7 +55,7 @@ const PopoverContent = () => { : } onClick={() => { - setMode(mode === 'page' ? 'edgeless' : 'page'); + changePageMode(id); }} > Convert to {mode === 'page' ? 'Edgeless' : 'Page'} @@ -128,11 +125,12 @@ const BrowserWarning = ({ }; const HeaderRight = () => { - const { pageList, permanentlyDeletePage } = useEditor(); - const { currentWorkspaceId, toggleDeletePage } = useAppState(); + const { permanentlyDeletePage } = usePageHelper(); + const { currentWorkspaceId } = useAppState(); + const { toggleDeletePage } = usePageHelper(); const { confirm } = useConfirm(); const router = useRouter(); - const currentPageMeta = pageList.find(p => p.id === router.query.pageId); + const currentPageMeta = useCurrentPageMeta(); const isTrash = !!currentPageMeta?.trash; if (isTrash) { @@ -188,8 +186,6 @@ const HeaderRight = () => { export const Header = ({ children }: PropsWithChildren<{}>) => { const [showWarning, setShowWarning] = useState(shouldShowWarning()); - const currentPageMeta = useCurrentPageMeta(); - console.log('currentPageMeta', currentPageMeta); return ( ; export const HelpIsland = ({ showList = ['contact', 'shortcuts'], @@ -22,7 +21,7 @@ export const HelpIsland = ({ }) => { const [showContent, setShowContent] = useState(false); const { mode } = useTheme(); - const { mode: editorMode } = useEditor(); + const { mode: editorMode } = useCurrentPageMeta() || {}; const { triggerShortcutsModal, triggerContactModal } = useModal(); const isEdgelessDark = mode === 'dark' && editorMode === 'edgeless'; diff --git a/packages/app/src/components/page-list/date-cell.tsx b/packages/app/src/components/page-list/date-cell.tsx index e7d90f64e8..4ffc4e95cd 100644 --- a/packages/app/src/components/page-list/date-cell.tsx +++ b/packages/app/src/components/page-list/date-cell.tsx @@ -1,6 +1,6 @@ import localizedFormat from 'dayjs/plugin/localizedFormat'; import dayjs from 'dayjs'; -import { PageMeta } from '@/providers/editor-provider'; +import { PageMeta } from '@/providers/app-state-provider'; import { TableCell } from '@/ui/table'; import React from 'react'; diff --git a/packages/app/src/components/page-list/index.tsx b/packages/app/src/components/page-list/index.tsx index 5573b5be03..4baed96ebd 100644 --- a/packages/app/src/components/page-list/index.tsx +++ b/packages/app/src/components/page-list/index.tsx @@ -1,4 +1,4 @@ -import { PageMeta, useEditor } from '@/providers/editor-provider'; +import { PageMeta } from '@/providers/app-state-provider'; import { FavouritedIcon, FavouritesIcon, diff --git a/packages/app/src/components/page-list/operation-cell.tsx b/packages/app/src/components/page-list/operation-cell.tsx index 9111bc47c1..bfa562e5ae 100644 --- a/packages/app/src/components/page-list/operation-cell.tsx +++ b/packages/app/src/components/page-list/operation-cell.tsx @@ -1,7 +1,5 @@ -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 { useAppState, PageMeta } from '@/providers/app-state-provider'; import { Menu, MenuItem } from '@/ui/menu'; import { Wrapper } from '@/ui/layout'; import { IconButton } from '@/ui/button'; @@ -19,7 +17,7 @@ import { usePageHelper } from '@/hooks/use-page-helper'; export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { const { id, favorite } = pageMeta; - const goToPage = useGoToPage(); + const { openPage } = usePageHelper(); const { toggleFavoritePage, toggleDeletePage } = usePageHelper(); const { confirm } = useConfirm(); @@ -36,7 +34,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { { - goToPage(id); + openPage(id); }} icon={} > @@ -73,9 +71,9 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { const { id } = pageMeta; - const goToPage = useGoToPage(); - const { getPageMeta, toggleDeletePage } = useAppState(); - const { permanentlyDeletePage } = useEditor(); + const { openPage } = usePageHelper(); + const { getPageMeta } = useAppState(); + const { toggleDeletePage, permanentlyDeletePage } = usePageHelper(); const { confirm } = useConfirm(); return ( @@ -86,7 +84,7 @@ export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => { onClick={() => { toggleDeletePage(id); toast(`${getPageMeta(id)?.title || 'Untitled'} restored`); - goToPage(id); + openPage(id); }} > diff --git a/packages/app/src/components/quick-search/footer.tsx b/packages/app/src/components/quick-search/footer.tsx index 4f2b356577..d3f66b143e 100644 --- a/packages/app/src/components/quick-search/footer.tsx +++ b/packages/app/src/components/quick-search/footer.tsx @@ -4,12 +4,12 @@ import { StyledModalFooterContent } from './style'; import { useModal } from '@/providers/global-modal-provider'; import { useAppState } from '@/providers/app-state-provider/context'; import { Command } from 'cmdk'; -import { useGoToPage } from '@/providers/app-state-provider/hooks'; +import { usePageHelper } from '@/hooks/use-page-helper'; export const Footer = (props: { query: string }) => { const { createPage } = useAppState(); const { triggerQuickSearchModal } = useModal(); - const goToPage = useGoToPage(); + const { openPage } = usePageHelper(); const query = props.query; return ( @@ -18,7 +18,7 @@ export const Footer = (props: { query: string }) => { onSelect={async () => { const pageId = await createPage?.current?.(); if (pageId) { - goToPage(pageId); + openPage(pageId); } triggerQuickSearchModal(); diff --git a/packages/app/src/components/quick-search/results.tsx b/packages/app/src/components/quick-search/results.tsx index 4252943207..c9a5a56706 100644 --- a/packages/app/src/components/quick-search/results.tsx +++ b/packages/app/src/components/quick-search/results.tsx @@ -6,7 +6,6 @@ import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { useAppState } from '@/providers/app-state-provider/context'; import { useRouter } from 'next/router'; import { config } from './config'; -import { useGoToPage } from '@/providers/app-state-provider/hooks'; import { usePageList } from '@/providers/app-state-provider/usePageList'; import { useLoadWorkspace } from '@/providers/app-state-provider/hooks'; import { NoResultSVG } from './noResultSVG'; @@ -24,7 +23,7 @@ export const Results = (props: { const { triggerQuickSearchModal } = useModal(); const workspace = useLoadWorkspace(); const pageList = usePageList(workspace); - const goToPage = useGoToPage(); + const { openPage } = usePageHelper(); const router = useRouter(); const { currentWorkspaceId } = useAppState(); const { search } = usePageHelper(); @@ -55,7 +54,7 @@ export const Results = (props: { { - goToPage(result.id); + openPage(result.id); triggerQuickSearchModal(); }} value={result.id} diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index 2fcb4ccde9..fe2492451a 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -23,17 +23,19 @@ import { } from '@blocksuite/icons'; 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 { useAppState } from '@/providers/app-state-provider/context'; import { IconButton } from '@/ui/button'; import { WorkspaceSelector } from './WorkspaceSelector'; import useLocalStorage from '@/hooks/use-local-storage'; import { useTranslation } from '@/libs/i18n'; +import usePageMetaList from '@/hooks/use-page-meta-list'; +import { usePageHelper } from '@/hooks/use-page-helper'; + const FavoriteList = ({ showList }: { showList: boolean }) => { - const { pageList, openPage } = useEditor(); + const { openPage } = usePageHelper(); + const pageList = usePageMetaList(); const router = useRouter(); const favoriteList = pageList.filter(p => p.favorite && !p.trash); @@ -66,7 +68,7 @@ export const WorkSpaceSliderBar = () => { const { triggerQuickSearchModal } = useModal(); const [showSubFavorite, setShowSubFavorite] = useState(true); const { createPage, currentWorkspaceId } = useAppState(); - const goToPage = useGoToPage(); + const { openPage } = usePageHelper(); const router = useRouter(); const [showTip, setShowTip] = useState(false); @@ -142,9 +144,8 @@ export const WorkSpaceSliderBar = () => { { const pageId = await createPage?.current?.(); - console.log('pageID', pageId); if (pageId) { - goToPage(pageId); + openPage(pageId); } }} > diff --git a/packages/app/src/hooks/use-change-page-meta.ts b/packages/app/src/hooks/use-change-page-meta.ts index 55f266838c..1b553f2099 100644 --- a/packages/app/src/hooks/use-change-page-meta.ts +++ b/packages/app/src/hooks/use-change-page-meta.ts @@ -1,6 +1,5 @@ import { useCallback } from 'react'; -import { useAppState } from '@/providers/app-state-provider'; -import { PageMeta } from '@blocksuite/store'; +import { useAppState, PageMeta } from '@/providers/app-state-provider'; export type ChangePageMeta = ( pageId: string, diff --git a/packages/app/src/hooks/use-current-page-meta.ts b/packages/app/src/hooks/use-current-page-meta.ts index 0117074e7c..36ccf4befe 100644 --- a/packages/app/src/hooks/use-current-page-meta.ts +++ b/packages/app/src/hooks/use-current-page-meta.ts @@ -1,17 +1,17 @@ import { useCallback, useEffect, useState } from 'react'; -import { useAppState } from '@/providers/app-state-provider'; -import { PageMeta } from '@blocksuite/store'; +import { useAppState, PageMeta } from '@/providers/app-state-provider'; -export const useCurrentPageMeta = () => { +export const useCurrentPageMeta = (): PageMeta | null => { const { currentPage, currentWorkspace } = useAppState(); - const pageMetaHandler = useCallback(() => { + const pageMetaHandler = useCallback((): PageMeta | null => { if (!currentPage || !currentWorkspace) { return null; } return ( - currentWorkspace?.meta.pageMetas.find(p => p.id === currentPage.pageId) ?? - null + (currentWorkspace?.meta.pageMetas.find( + p => p.id === currentPage.pageId + ) as PageMeta) ?? null ); }, [currentPage, currentWorkspace]); diff --git a/packages/app/src/hooks/use-editor-mode.ts b/packages/app/src/hooks/use-editor-mode.ts deleted file mode 100644 index b93e6e2c4b..0000000000 --- a/packages/app/src/hooks/use-editor-mode.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useState } from 'react'; -import { EditorContainer } from '@blocksuite/editor'; -import { useAppState } from '@/providers/app-state-provider'; - -export const usePageHandler = () => { - return null; -}; diff --git a/packages/app/src/hooks/use-history-update.ts b/packages/app/src/hooks/use-history-update.ts new file mode 100644 index 0000000000..8329988e0c --- /dev/null +++ b/packages/app/src/hooks/use-history-update.ts @@ -0,0 +1,37 @@ +import { Page } from '@blocksuite/store'; +import { useAppState } from '@/providers/app-state-provider'; +import { useEffect, useRef } from 'react'; + +export type EventCallBack = (callback: (props: T) => void) => void; +export type UseHistoryUpdated = (page?: Page) => EventCallBack; + +export const useHistoryUpdate: UseHistoryUpdated = () => { + const { currentPage } = useAppState(); + + const callbackQueue = useRef<((page: Page) => void)[]>([]); + + useEffect(() => { + if (!currentPage) { + return; + } + + setTimeout(() => { + currentPage.signals.historyUpdated.on(() => { + callbackQueue.current.forEach(callback => { + callback(currentPage); + }); + }); + }, 300); + + return () => { + callbackQueue.current = []; + currentPage.signals.historyUpdated.dispose(); + }; + }, [currentPage]); + + return callback => { + callbackQueue.current.push(callback); + }; +}; + +export default useHistoryUpdate; diff --git a/packages/app/src/hooks/use-page-helper.ts b/packages/app/src/hooks/use-page-helper.ts index e138b74780..36ce66e356 100644 --- a/packages/app/src/hooks/use-page-helper.ts +++ b/packages/app/src/hooks/use-page-helper.ts @@ -1,51 +1,88 @@ -import { Page } from '@blocksuite/store'; -import { PageMeta } from '@/providers/editor-provider'; +import { Workspace } from '@blocksuite/store'; +import { QueryContent } from '@blocksuite/store/dist/workspace/search'; import { useAppState } from '@/providers/app-state-provider'; +import { EditorContainer } from '@blocksuite/editor'; +import { useChangePageMeta } from '@/hooks/use-change-page-meta'; +import { useRouter } from 'next/router'; export type EditorHandlers = { // createPage: (params?: { pageId?: string; title?: string }) => Promise; - // openPage: ( - // pageId: string, - // query?: { [key: string]: string } - // ) => Promise; + openPage: ( + pageId: string, + query?: { [key: string]: string } + ) => Promise; // getPageMeta: (pageId?: string) => PageMeta; - toggleDeletePage: (pageId: string) => void; - toggleFavoritePage: (pageId: string) => void; - // permanentlyDeletePage: (pageId: string) => void; - search: (query: string) => Map; + toggleDeletePage: (pageId: string) => Promise; + toggleFavoritePage: (pageId: string) => Promise; + permanentlyDeletePage: (pageId: string) => void; + search: (query: QueryContent) => Map; // changeEditorMode: (pageId: string) => void; + changePageMode: ( + pageId: string, + mode: EditorContainer['mode'] + ) => Promise; }; +const getPageMeta = (workspace: Workspace | null, pageId: string) => { + return workspace?.meta.pageMetas.find(p => p.id === pageId); +}; export const usePageHelper = (): EditorHandlers => { - const { currentWorkspace } = useAppState(); + const router = useRouter(); + const changePageMeta = useChangePageMeta(); + const { currentWorkspace, editor, currentWorkspaceId } = useAppState(); return { - toggleFavoritePage: (pageId: string) => { - if (!currentWorkspace) { - return; - } - const pageMeta = currentWorkspace.meta.pageMetas.find( - p => p.id === pageId - ); - if (pageMeta) { - currentWorkspace.setPageMeta(pageId, { - favorite: !pageMeta.favorite, - }); + toggleFavoritePage: async pageId => { + const pageMeta = getPageMeta(currentWorkspace, pageId); + if (!pageMeta) { + return Promise.reject('No page'); } + const favorite = !pageMeta.favorite; + changePageMeta(pageMeta.id, { + favorite, + }); + return favorite; }, - toggleDeletePage: (pageId: string) => { - const pageMeta = currentWorkspace?.meta.pageMetas.find( - p => p.id === pageId - ); - if (pageMeta) { - currentWorkspace!.setPageMeta(pageId, { - trash: !pageMeta.trash, - trashDate: +new Date(), - }); + toggleDeletePage: async pageId => { + const pageMeta = getPageMeta(currentWorkspace, pageId); + + if (!pageMeta) { + return Promise.reject('No page'); } + const trash = !pageMeta.trash; + + changePageMeta(pageMeta.id, { + trash, + trashDate: +new Date(), + }); + return trash; }, search: (query: string) => { return currentWorkspace!.search(query); }, + changePageMode: async (pageId, mode) => { + const pageMeta = getPageMeta(currentWorkspace, pageId); + if (!pageMeta) { + return Promise.reject('No page'); + } + + editor?.setAttribute('mode', mode as string); + + changePageMeta(pageMeta.id, { + mode, + }); + return mode; + }, + permanentlyDeletePage: pageId => { + // TODO: workspace.meta.removePage or workspace.removePage? + currentWorkspace!.meta.removePage(pageId); + }, + openPage: (pageId, query = {}) => { + pageId = pageId.replace('space:', ''); + return router.push({ + pathname: `/workspace/${currentWorkspaceId}/${pageId}`, + query, + }); + }, }; }; diff --git a/packages/app/src/hooks/use-page-meta-list.ts b/packages/app/src/hooks/use-page-meta-list.ts index 35bd93ac39..3c55ec9d26 100644 --- a/packages/app/src/hooks/use-page-meta-list.ts +++ b/packages/app/src/hooks/use-page-meta-list.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { PageMeta } from '@/providers/app-state-provider/usePageList'; +import { PageMeta } from '@/providers/app-state-provider'; import { useAppState } from '@/providers/app-state-provider'; export const usePageMetaList = () => { diff --git a/packages/app/src/hooks/use-props-updated.ts b/packages/app/src/hooks/use-props-updated.ts new file mode 100644 index 0000000000..d76ada43d2 --- /dev/null +++ b/packages/app/src/hooks/use-props-updated.ts @@ -0,0 +1,38 @@ +import { useEffect, useRef } from 'react'; +import { EditorContainer } from '@blocksuite/editor'; +import { useAppState } from '@/providers/app-state-provider'; +export type EventCallBack = (callback: (props: T) => void) => void; + +export type UsePropsUpdated = ( + editor?: EditorContainer +) => EventCallBack; + +export const usePropsUpdated: UsePropsUpdated = () => { + const { editor } = useAppState(); + + const callbackQueue = useRef<((editor: EditorContainer) => void)[]>([]); + + useEffect(() => { + if (!editor) { + return; + } + setTimeout(() => { + editor.model?.propsUpdated.on(() => { + callbackQueue.current.forEach(callback => { + callback(editor); + }); + }); + }, 300); + + return () => { + callbackQueue.current = []; + editor?.model?.propsUpdated.dispose(); + }; + }, [editor]); + + return callback => { + callbackQueue.current.push(callback); + }; +}; + +export default usePropsUpdated; diff --git a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx index c8b59769e7..3a26f736ef 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -9,7 +9,7 @@ import { useLoadPage, } from '@/providers/app-state-provider/hooks'; import { useAppState } from '@/providers/app-state-provider/context'; -import exampleMarkdown from '@/providers/editor-provider/example-markdown'; +import exampleMarkdown from '@/static/example-markdown'; const StyledEditorContainer = styled('div')(({ theme }) => { return { diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 3dd06f0433..115ef7fb84 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -1,13 +1,12 @@ -import { createContext, MutableRefObject, RefObject, useContext } from 'react'; +import { createContext, MutableRefObject, useContext } from 'react'; import type { Workspace } from '@pathfinder/data-services'; import { AccessTokenMessage } from '@pathfinder/data-services'; import type { Page as StorePage, - PageMeta, Workspace as StoreWorkspace, } from '@blocksuite/store'; import type { EditorContainer } from '@blocksuite/editor'; - +import { PageMeta } from './interface'; export type LoadWorkspaceHandler = ( workspaceId: string ) => Promise | null; diff --git a/packages/app/src/providers/app-state-provider/hooks.ts b/packages/app/src/providers/app-state-provider/hooks.ts index 6df6738636..c57dd89ab9 100644 --- a/packages/app/src/providers/app-state-provider/hooks.ts +++ b/packages/app/src/providers/app-state-provider/hooks.ts @@ -28,12 +28,3 @@ 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/index.ts b/packages/app/src/providers/app-state-provider/index.ts index c38e8e8215..88c38fd7cf 100644 --- a/packages/app/src/providers/app-state-provider/index.ts +++ b/packages/app/src/providers/app-state-provider/index.ts @@ -1 +1,2 @@ export * from './context'; +export * from './interface'; diff --git a/packages/app/src/providers/app-state-provider/interface.ts b/packages/app/src/providers/app-state-provider/interface.ts new file mode 100644 index 0000000000..078eebbf1a --- /dev/null +++ b/packages/app/src/providers/app-state-provider/interface.ts @@ -0,0 +1,19 @@ +import { EditorContainer } from '@blocksuite/editor'; +import { PageMeta as OriginalPageMeta } from '@blocksuite/store/dist/workspace/workspace'; + +// export type PageMeta = { +// favorite: boolean; +// trash: boolean; +// trashDate: number | void; +// updatedDate: number | void; +// mode: EditorContainer['mode']; +// } & OriginalPageMeta; + +export interface PageMeta extends OriginalPageMeta { + favorite: boolean; + trash: boolean; + trashDate: number; + updatedDate: number; + // @ts-ignore + mode: 'edgeless' | 'page'; +} diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index 69c366233a..50ff911f74 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -14,7 +14,7 @@ import type { } from './context'; import type { Page, Workspace } from '@blocksuite/store'; import { EditorContainer } from '@blocksuite/editor'; - +import { PageMeta } from './interface'; const DynamicBlocksuite = dynamic(() => import('./dynamic-blocksuite'), { ssr: false, }); @@ -143,8 +143,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { return null; } return ( - currentWorkspace.meta.pageMetas.find(page => page.id === pageId) || - null + (currentWorkspace.meta.pageMetas.find( + page => page.id === pageId + ) as PageMeta) || null ); }, }), diff --git a/packages/app/src/providers/app-state-provider/usePageList.ts b/packages/app/src/providers/app-state-provider/usePageList.ts index 6d2515200f..e39f5f1b18 100644 --- a/packages/app/src/providers/app-state-provider/usePageList.ts +++ b/packages/app/src/providers/app-state-provider/usePageList.ts @@ -1,15 +1,6 @@ import { useState, useEffect } from 'react'; import type { Workspace } from '@blocksuite/store'; -import type { PageMeta as OriginalPageMeta } from '@blocksuite/store'; -import type { EditorContainer } from '@blocksuite/editor'; - -export type PageMeta = { - favorite: boolean; - trash: boolean; - trashDate: number | void; - updatedDate: number | void; - mode: EditorContainer['mode']; -} & OriginalPageMeta; +import { PageMeta } from './interface'; export const usePageList = (workspace: Workspace | null) => { const [pageList, setPageList] = useState([]); diff --git a/packages/app/src/providers/editor-provider/index.ts b/packages/app/src/providers/editor-provider/index.ts index 7fd40844ee..d0826b40a6 100644 --- a/packages/app/src/providers/editor-provider/index.ts +++ b/packages/app/src/providers/editor-provider/index.ts @@ -1,4 +1,4 @@ -export * from './editor-provider'; -export * from './example-markdown'; -export * from './utils'; -export * from './interface'; +// export * from './editor-provider'; +// export * from './example-markdown'; +// export * from './utils'; +// export * from './interface'; diff --git a/packages/app/src/providers/themeProvider.tsx b/packages/app/src/providers/themeProvider.tsx index f821da5d0a..15185e8f79 100644 --- a/packages/app/src/providers/themeProvider.tsx +++ b/packages/app/src/providers/themeProvider.tsx @@ -21,7 +21,7 @@ import { globalThemeVariables, } from '@/styles/theme'; import { SystemThemeHelper, localStorageThemeHelper } from '@/styles/utils'; -import { useEditor } from '@/providers/editor-provider'; +import useCurrentPageMeta from '@/hooks/use-current-page-meta'; export const ThemeContext = createContext({ mode: 'light', @@ -38,7 +38,7 @@ export const ThemeProvider = ({ }: PropsWithChildren) => { const [theme, setTheme] = useState(defaultTheme); const [mode, setMode] = useState('auto'); - const { mode: editorMode } = useEditor(); + const { mode: editorMode = 'page' } = useCurrentPageMeta() || {}; const themeStyle = theme === 'light' ? getLightTheme(editorMode) : getDarkTheme(editorMode); const changeMode = (themeMode: ThemeMode) => { diff --git a/packages/app/src/static/example-markdown.ts b/packages/app/src/static/example-markdown.ts new file mode 100644 index 0000000000..30210ed2c3 --- /dev/null +++ b/packages/app/src/static/example-markdown.ts @@ -0,0 +1,62 @@ +export const exampleMarkdown = `The AFFiNE Alpha is here! You can also view our [Official Website](https://affine.pro/)! + +**What's different in AFFiNE Alpha?** + +1. A much ~smoother editing~ experience, with much ~greater stability~; +2. More complete ~Markdown~ support and improved ~keyboard shortcuts~; +3. New features such as ~dark mode~; + * **Switch between view styles using the** ☀ **and** 🌙. +4. ~Clean and modern UI/UX~ design. + +**Looking for Markdown syntax or keyboard shortcuts?** + +* Find the (?) in the bottom right, then the ️⌨️, to view a full list of \`Keyboard Shortcuts\` + +**Have an enjoyable editing experience !!!** 😃 + +Have some feedback or just want to get in touch? Use the (?), then 🎧 to get in touch and join our communities. + +**Still in development** + +There are also some things you should consider about this AFFiNE Alpha including some ~limitations~: + +* Single page editing - currently editing multiple docs/pages is not supported; +* Changes are not automatically stored, to save changes you should export your data. Options can be found by going to the top right and finding the \`⋮\` icon; +* Without an import/open feature you are still able to access your data by copying it back in. + +**Keyboard Shortcuts:** + +1. Undo: \`⌘+Z\` or \`Ctrl+Z\` +2. Redo: \`⌘+⇧+Z\` or \`Ctrl+Shift+Z\` +3. Bold: \`⌘+B\` or \`Ctrl+B\` +4. Italic: \`⌘+I\` or \`Ctrl+I\` +5. Underline: \`⌘+U\` or \`Ctrl+U\` +6. Strikethrough: \`⌘+⇧+S\` or \`Ctrl+Shift+S\` +7. Inline code: \`⌘+E\` or \`Ctrl+E\` +8. Link: \`⌘+K\` or \`Ctrl+K\` +9. Body text: \`⌘+⌥+0\` or \`Ctrl+Shift+0\` +10. Heading 1: \`⌘+⌥+1\` or \`Ctrl+Shift+1\` +11. Heading 2: \`⌘+⌥+2\` or \`Ctrl+Shift+2\` +12. Heading 3: \`⌘+⌥+3\` or \`Ctrl+Shift+3\` +13. Heading 4: \`⌘+⌥+4\` or \`Ctrl+Shift+4\` +14. Heading 5: \`⌘+⌥+5\` or \`Ctrl+Shift+5\` +15. Heading 6: \`⌘+⌥+6\` or \`Ctrl+Shift+6\` +16. Increase indent: \`Tab\` +17. Reduce indent: \`⇧+Tab\` or \`Shift+Tab\` + +**Markdown Syntax:** + +1. Bold: \`**text**\` +2. Italic: \`*text*\` +3. Underline: \`~text~\` +4. Strikethrough: \`~~text~~\` +5. Inline code: \`\` \`text\` \`\` +6. Heading 1: \`# text\` +7. Heading 2: \`## text\` +8. Heading 3: \`### text\` +9. Heading 4: \`#### text\` +10. Heading 5: \`##### text\` +11. Heading 6: \`###### text\` +`; + +export default exampleMarkdown;