diff --git a/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-helper.spec.ts b/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-helper.spec.ts index 1592bf85e2..52e96aeefc 100644 --- a/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-helper.spec.ts +++ b/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-helper.spec.ts @@ -7,7 +7,7 @@ import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; import { Schema, Workspace } from '@blocksuite/store'; import { renderHook } from '@testing-library/react'; import { initEmptyPage } from '@toeverything/infra/blocksuite'; -import { beforeEach, describe, expect, test } from 'vitest'; +import { beforeEach, describe, expect, test, vi } from 'vitest'; import { useBlockSuitePageMeta } from '../use-block-suite-page-meta'; import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper'; @@ -17,18 +17,26 @@ let blockSuiteWorkspace: Workspace; const schema = new Schema(); schema.register(AffineSchemas).register(__unstableSchemas); +// todo: this module has some side-effects that will break the tests +vi.mock('@affine/workspace-impl', () => ({ + default: {}, +})); + beforeEach(async () => { blockSuiteWorkspace = new Workspace({ id: 'test', schema, }); + + blockSuiteWorkspace.doc.emit('sync', []); + await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page0' })); await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' })); await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' })); }); describe('useBlockSuiteWorkspaceHelper', () => { - test('should create page', () => { + test('should create page', async () => { expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); const helperHook = renderHook(() => useBlockSuiteWorkspaceHelper(blockSuiteWorkspace) @@ -36,6 +44,7 @@ describe('useBlockSuiteWorkspaceHelper', () => { const pageMetaHook = renderHook(() => useBlockSuitePageMeta(blockSuiteWorkspace) ); + await new Promise(resolve => setTimeout(resolve)); expect(pageMetaHook.result.current.length).toBe(3); expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); const page = helperHook.result.current.createPage('page4'); diff --git a/packages/frontend/core/src/hooks/use-block-suite-page-meta.ts b/packages/frontend/core/src/hooks/use-block-suite-page-meta.ts index 3ea236a54d..3053238469 100644 --- a/packages/frontend/core/src/hooks/use-block-suite-page-meta.ts +++ b/packages/frontend/core/src/hooks/use-block-suite-page-meta.ts @@ -5,9 +5,11 @@ import type { Atom } from 'jotai'; import { atom, useAtomValue } from 'jotai'; import { useMemo } from 'react'; +import { useJournalHelper } from './use-journal'; + const weakMap = new WeakMap>(); -export function useBlockSuitePageMeta( +export function useAllBlockSuitePageMeta( blockSuiteWorkspace: Workspace ): PageMeta[] { if (!weakMap.has(blockSuiteWorkspace)) { @@ -26,6 +28,18 @@ export function useBlockSuitePageMeta( return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom); } +export function useBlockSuitePageMeta(blocksuiteWorkspace: Workspace) { + const pageMetas = useAllBlockSuitePageMeta(blocksuiteWorkspace); + const { isPageJournal } = useJournalHelper(blocksuiteWorkspace); + return useMemo( + () => + pageMetas.filter( + pageMeta => !isPageJournal(pageMeta.id) || !!pageMeta.updatedDate + ), + [isPageJournal, pageMetas] + ); +} + export function usePageMetaHelper(blockSuiteWorkspace: Workspace) { return useMemo( () => ({ diff --git a/packages/frontend/core/src/pages/workspace/detail-page/editor-sidebar/extensions/journal.tsx b/packages/frontend/core/src/pages/workspace/detail-page/editor-sidebar/extensions/journal.tsx index b6df10577c..53487552db 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/editor-sidebar/extensions/journal.tsx +++ b/packages/frontend/core/src/pages/workspace/detail-page/editor-sidebar/extensions/journal.tsx @@ -6,6 +6,7 @@ import { } from '@affine/component'; import { MoveToTrash } from '@affine/core/components/page-list'; import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper'; +import { useBlockSuitePageMeta } from '@affine/core/hooks/use-block-suite-page-meta'; import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title'; import { useJournalHelper, @@ -13,6 +14,7 @@ import { useJournalRouteHelper, } from '@affine/core/hooks/use-journal'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; +import type { BlockSuiteWorkspace } from '@affine/core/shared'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { EdgelessIcon, @@ -20,7 +22,7 @@ import { PageIcon, TodayIcon, } from '@blocksuite/icons'; -import type { Page } from '@blocksuite/store'; +import type { Page, PageMeta } from '@blocksuite/store'; import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; import dayjs from 'dayjs'; @@ -41,21 +43,28 @@ const CountDisplay = ({ return {count > max ? `${max}+` : count}; }; interface PageItemProps extends HTMLAttributes { - page: Page; + pageMeta: PageMeta; + workspace: BlockSuiteWorkspace; right?: ReactNode; } -const PageItem = ({ page, right, className, ...attrs }: PageItemProps) => { - const { isJournal } = useJournalInfoHelper(page.workspace, page.id); - const title = useBlockSuiteWorkspacePageTitle(page.workspace, page.id); +const PageItem = ({ + pageMeta, + workspace, + right, + className, + ...attrs +}: PageItemProps) => { + const { isJournal } = useJournalInfoHelper(workspace, pageMeta.id); + const title = useBlockSuiteWorkspacePageTitle(workspace, pageMeta.id); const Icon = isJournal ? TodayIcon - : page.meta.mode === 'edgeless' + : pageMeta.mode === 'edgeless' ? EdgelessIcon : PageIcon; return (
@@ -114,15 +123,12 @@ const EditorJournalPanel = (props: EditorExtensionProps) => { }; const sortPagesByDate = ( - pages: Page[], + pages: PageMeta[], field: 'updatedDate' | 'createDate', order: 'asc' | 'desc' = 'desc' ) => { return [...pages].sort((a, b) => { - return ( - (order === 'asc' ? 1 : -1) * - dayjs(b.meta[field]).diff(dayjs(a.meta[field])) - ); + return (order === 'asc' ? 1 : -1) * dayjs(b[field]).diff(dayjs(a[field])); }); }; @@ -141,21 +147,21 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => { const nodeRef = useRef(null); const t = useAFFiNEI18N(); const [activeItem, setActiveItem] = useState('createdToday'); + const pageMetas = useBlockSuitePageMeta(workspace); const navigateHelper = useNavigateHelper(); const getTodaysPages = useCallback( (field: 'createDate' | 'updatedDate') => { - const pages: Page[] = []; - Array.from(workspace.pages.values()).forEach(page => { - if (page.meta.trash) return; - if (page.meta[field] && dayjs(page.meta[field]).isSame(date, 'day')) { - pages.push(page); - } - }); - return sortPagesByDate(pages, field); + return sortPagesByDate( + pageMetas.filter(pageMeta => { + if (pageMeta.trash) return false; + return pageMeta[field] && dayjs(pageMeta[field]).isSame(date, 'day'); + }), + field + ); }, - [date, workspace.pages] + [date, pageMetas] ); const createdToday = useMemo( @@ -224,14 +230,15 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
- {renderList.map((page, index) => ( + {renderList.map((pageMeta, index) => ( - navigateHelper.openPage(workspace.id, page.id) + navigateHelper.openPage(workspace.id, pageMeta.id) } tabIndex={name === activeItem ? 0 : -1} key={index} - page={page} + pageMeta={pageMeta} + workspace={workspace} /> ))}
@@ -282,7 +289,8 @@ const ConflictList = ({