diff --git a/packages/app/src/components/header/header.tsx b/packages/app/src/components/header/header.tsx index 9f8a92618f..7aeee29cde 100644 --- a/packages/app/src/components/header/header.tsx +++ b/packages/app/src/components/header/header.tsx @@ -28,15 +28,11 @@ import { useRouter } from 'next/router'; import { useConfirm } from '@/providers/confirm-provider'; import { SyncIcon } from './sync-icon'; 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, - toggleFavoritePage, - toggleDeletePage, - } = useAppState(); + const { getPageMeta, editor, currentPage } = useAppState(); + const { toggleFavoritePage, toggleDeletePage } = usePageHelper(); const { mode, setMode } = useEditor(); const { confirm } = useConfirm(); @@ -192,7 +188,8 @@ const HeaderRight = () => { export const Header = ({ children }: PropsWithChildren<{}>) => { const [showWarning, setShowWarning] = useState(shouldShowWarning()); - + const currentPageMeta = useCurrentPageMeta(); + console.log('currentPageMeta', currentPageMeta); return ( { - const { toggleFavoritePage } = useAppState(); + const { toggleFavoritePage } = usePageHelper(); return ( { const { id, favorite } = pageMeta; const goToPage = useGoToPage(); - const { toggleFavoritePage, toggleDeletePage } = useAppState(); + const { toggleFavoritePage, toggleDeletePage } = usePageHelper(); const { confirm } = useConfirm(); const OperationMenu = ( diff --git a/packages/app/src/components/quick-search/results.tsx b/packages/app/src/components/quick-search/results.tsx index 20be5ef916..2116ae3f56 100644 --- a/packages/app/src/components/quick-search/results.tsx +++ b/packages/app/src/components/quick-search/results.tsx @@ -11,6 +11,7 @@ import { usePageList } from '@/providers/app-state-provider/usePageList'; import { useLoadWorkspace } from '@/providers/app-state-provider/hooks'; import NextImage from 'next/image'; import noResultImage from './jungle-searching.png'; +import { usePageHelper } from '@/hooks/use-page-helper'; export const Results = (props: { query: string; loading: boolean; @@ -26,7 +27,8 @@ export const Results = (props: { const pageList = usePageList(workspace); const goToPage = useGoToPage(); const router = useRouter(); - const { search, currentWorkspaceId } = useAppState(); + const { currentWorkspaceId } = useAppState(); + const { search } = usePageHelper(); const List = config(currentWorkspaceId); const [results, setResults] = useState(new Map()); useEffect(() => { diff --git a/packages/app/src/hooks/use-change-page-meta.ts b/packages/app/src/hooks/use-change-page-meta.ts new file mode 100644 index 0000000000..55f266838c --- /dev/null +++ b/packages/app/src/hooks/use-change-page-meta.ts @@ -0,0 +1,23 @@ +import { useCallback } from 'react'; +import { useAppState } from '@/providers/app-state-provider'; +import { PageMeta } from '@blocksuite/store'; + +export type ChangePageMeta = ( + pageId: string, + pageMeta: Partial +) => void; + +export const useChangePageMeta = () => { + const { currentWorkspace } = useAppState(); + + return useCallback( + (pageId, pageMeta) => { + currentWorkspace?.setPageMeta(pageId, { + ...pageMeta, + }); + }, + [currentWorkspace] + ); +}; + +export default ChangePageMeta; diff --git a/packages/app/src/hooks/use-current-page-meta.ts b/packages/app/src/hooks/use-current-page-meta.ts new file mode 100644 index 0000000000..0117074e7c --- /dev/null +++ b/packages/app/src/hooks/use-current-page-meta.ts @@ -0,0 +1,37 @@ +import { useCallback, useEffect, useState } from 'react'; +import { useAppState } from '@/providers/app-state-provider'; +import { PageMeta } from '@blocksuite/store'; + +export const useCurrentPageMeta = () => { + const { currentPage, currentWorkspace } = useAppState(); + + const pageMetaHandler = useCallback(() => { + if (!currentPage || !currentWorkspace) { + return null; + } + return ( + currentWorkspace?.meta.pageMetas.find(p => p.id === currentPage.pageId) ?? + null + ); + }, [currentPage, currentWorkspace]); + + const [currentPageMeta, setCurrentPageMeta] = useState( + pageMetaHandler + ); + + useEffect(() => { + setCurrentPageMeta(pageMetaHandler); + + const dispose = currentWorkspace?.meta.pagesUpdated.on(res => { + setCurrentPageMeta(pageMetaHandler); + }).dispose; + + return () => { + dispose?.(); + }; + }, [currentPage, currentWorkspace, pageMetaHandler]); + + return currentPageMeta; +}; + +export default useCurrentPageMeta; diff --git a/packages/app/src/hooks/use-editor-mode.ts b/packages/app/src/hooks/use-editor-mode.ts new file mode 100644 index 0000000000..b93e6e2c4b --- /dev/null +++ b/packages/app/src/hooks/use-editor-mode.ts @@ -0,0 +1,7 @@ +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-page-helper.ts b/packages/app/src/hooks/use-page-helper.ts new file mode 100644 index 0000000000..910e24f996 --- /dev/null +++ b/packages/app/src/hooks/use-page-helper.ts @@ -0,0 +1,52 @@ +import { Page } from '@blocksuite/store'; +import { QueryContent } from '@blocksuite/store/dist/workspace/search'; +import { PageMeta } from '@/providers/editor-provider'; +import { useAppState } from '@/providers/app-state-provider'; + +export type EditorHandlers = { + // createPage: (params?: { pageId?: string; title?: 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: QueryContent) => Map; + // changeEditorMode: (pageId: string) => void; +}; + +export const usePageHelper = (): EditorHandlers => { + const { currentWorkspace } = 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, + }); + } + }, + toggleDeletePage: (pageId: string) => { + const pageMeta = currentWorkspace?.meta.pageMetas.find( + p => p.id === pageId + ); + if (pageMeta) { + currentWorkspace!.setPageMeta(pageId, { + trash: !pageMeta.trash, + trashDate: +new Date(), + }); + } + }, + search: (query: QueryContent) => { + return currentWorkspace!.search(query); + }, + }; +}; diff --git a/packages/app/src/hooks/use-page-meta-list.ts b/packages/app/src/hooks/use-page-meta-list.ts new file mode 100644 index 0000000000..35bd93ac39 --- /dev/null +++ b/packages/app/src/hooks/use-page-meta-list.ts @@ -0,0 +1,25 @@ +import { useEffect, useState } from 'react'; +import { PageMeta } from '@/providers/app-state-provider/usePageList'; +import { useAppState } from '@/providers/app-state-provider'; + +export const usePageMetaList = () => { + const { currentWorkspace } = useAppState(); + const [pageList, setPageList] = useState([]); + + useEffect(() => { + if (!currentWorkspace) { + return; + } + setPageList(currentWorkspace.meta.pageMetas as PageMeta[]); + const dispose = currentWorkspace.meta.pagesUpdated.on(res => { + setPageList(currentWorkspace.meta.pageMetas as PageMeta[]); + }).dispose; + return () => { + dispose(); + }; + }, [currentWorkspace]); + + return pageList; +}; + +export default usePageMetaList; diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 2b014e9cc5..78a6be0b45 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -43,9 +43,6 @@ export interface AppStateContext extends AppStateValue { ((pageId?: string) => Promise) | undefined >; getPageMeta: (pageId: string) => PageMeta | null; - toggleFavoritePage: (pageId: string) => void; - toggleDeletePage: (pageId: string) => void; - search: (query: QueryContent) => Map; } export const AppState = createContext({ @@ -66,9 +63,6 @@ export const AppState = createContext({ loadPage: undefined, createPage: undefined, getPageMeta: () => null, - toggleFavoritePage: () => {}, - toggleDeletePage: () => {}, - search: () => new Map(), }); export const useAppState = () => { diff --git a/packages/app/src/providers/app-state-provider/index.ts b/packages/app/src/providers/app-state-provider/index.ts new file mode 100644 index 0000000000..c38e8e8215 --- /dev/null +++ b/packages/app/src/providers/app-state-provider/index.ts @@ -0,0 +1 @@ +export * from './context'; diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index 8551770da0..69c366233a 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -9,11 +9,9 @@ import { import { AppState } from './context'; import type { AppStateValue, - AppStateContext, CreateEditorHandler, LoadWorkspaceHandler, } from './context'; -import { QueryContent } from '@blocksuite/store/dist/workspace/search'; import type { Page, Workspace } from '@blocksuite/store'; import { EditorContainer } from '@blocksuite/editor'; @@ -25,12 +23,9 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { const [state, setState] = useState({ user: null, workspacesMeta: [], - currentWorkspaceId: '', currentWorkspace: null, - currentPage: null, - editor: null, }); @@ -45,6 +40,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { const [createEditorHandler, _setCreateEditorHandler] = useState(); + const setCreateEditorHandler = useCallback( (handler: CreateEditorHandler) => { _setCreateEditorHandler(() => handler); @@ -151,36 +147,6 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { null ); }, - toggleFavoritePage: (pageId: string) => { - const { currentWorkspace } = state; - if (!currentWorkspace) { - return; - } - const pageMeta = currentWorkspace.meta.pageMetas.find( - p => p.id === pageId - ); - if (pageMeta) { - currentWorkspace.setPageMeta(pageId, { - favorite: !pageMeta.favorite, - }); - } - }, - toggleDeletePage: (pageId: string) => { - const { currentWorkspace } = state; - const pageMeta = currentWorkspace?.meta.pageMetas.find( - p => p.id === pageId - ); - if (pageMeta) { - currentWorkspace!.setPageMeta(pageId, { - trash: !pageMeta.trash, - trashDate: +new Date(), - }); - } - }, - search: (query: QueryContent) => { - const { currentWorkspace } = state; - return currentWorkspace!.search(query); - }, }), [state, setState, loadPage, loadWorkspace] );