feat(core): ignore empty journals for page lists (#5744)

This commit is contained in:
Cats Juice
2024-01-30 17:21:20 +08:00
committed by GitHub
parent 48cd8999bd
commit ea17e86032
3 changed files with 59 additions and 28 deletions
@@ -7,7 +7,7 @@ import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import { Schema, Workspace } from '@blocksuite/store'; import { Schema, Workspace } from '@blocksuite/store';
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
import { initEmptyPage } from '@toeverything/infra/blocksuite'; 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 { useBlockSuitePageMeta } from '../use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper'; import { useBlockSuiteWorkspaceHelper } from '../use-block-suite-workspace-helper';
@@ -17,18 +17,26 @@ let blockSuiteWorkspace: Workspace;
const schema = new Schema(); const schema = new Schema();
schema.register(AffineSchemas).register(__unstableSchemas); 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 () => { beforeEach(async () => {
blockSuiteWorkspace = new Workspace({ blockSuiteWorkspace = new Workspace({
id: 'test', id: 'test',
schema, schema,
}); });
blockSuiteWorkspace.doc.emit('sync', []);
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page0' })); await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page0' }));
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' })); await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page1' }));
await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' })); await initEmptyPage(blockSuiteWorkspace.createPage({ id: 'page2' }));
}); });
describe('useBlockSuiteWorkspaceHelper', () => { describe('useBlockSuiteWorkspaceHelper', () => {
test('should create page', () => { test('should create page', async () => {
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
const helperHook = renderHook(() => const helperHook = renderHook(() =>
useBlockSuiteWorkspaceHelper(blockSuiteWorkspace) useBlockSuiteWorkspaceHelper(blockSuiteWorkspace)
@@ -36,6 +44,7 @@ describe('useBlockSuiteWorkspaceHelper', () => {
const pageMetaHook = renderHook(() => const pageMetaHook = renderHook(() =>
useBlockSuitePageMeta(blockSuiteWorkspace) useBlockSuitePageMeta(blockSuiteWorkspace)
); );
await new Promise(resolve => setTimeout(resolve));
expect(pageMetaHook.result.current.length).toBe(3); expect(pageMetaHook.result.current.length).toBe(3);
expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3); expect(blockSuiteWorkspace.meta.pageMetas.length).toBe(3);
const page = helperHook.result.current.createPage('page4'); const page = helperHook.result.current.createPage('page4');
@@ -5,9 +5,11 @@ import type { Atom } from 'jotai';
import { atom, useAtomValue } from 'jotai'; import { atom, useAtomValue } from 'jotai';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useJournalHelper } from './use-journal';
const weakMap = new WeakMap<Workspace, Atom<PageMeta[]>>(); const weakMap = new WeakMap<Workspace, Atom<PageMeta[]>>();
export function useBlockSuitePageMeta( export function useAllBlockSuitePageMeta(
blockSuiteWorkspace: Workspace blockSuiteWorkspace: Workspace
): PageMeta[] { ): PageMeta[] {
if (!weakMap.has(blockSuiteWorkspace)) { if (!weakMap.has(blockSuiteWorkspace)) {
@@ -26,6 +28,18 @@ export function useBlockSuitePageMeta(
return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<PageMeta[]>); return useAtomValue(weakMap.get(blockSuiteWorkspace) as Atom<PageMeta[]>);
} }
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) { export function usePageMetaHelper(blockSuiteWorkspace: Workspace) {
return useMemo( return useMemo(
() => ({ () => ({
@@ -6,6 +6,7 @@ import {
} from '@affine/component'; } from '@affine/component';
import { MoveToTrash } from '@affine/core/components/page-list'; import { MoveToTrash } from '@affine/core/components/page-list';
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper'; 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 { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title';
import { import {
useJournalHelper, useJournalHelper,
@@ -13,6 +14,7 @@ import {
useJournalRouteHelper, useJournalRouteHelper,
} from '@affine/core/hooks/use-journal'; } from '@affine/core/hooks/use-journal';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import type { BlockSuiteWorkspace } from '@affine/core/shared';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
EdgelessIcon, EdgelessIcon,
@@ -20,7 +22,7 @@ import {
PageIcon, PageIcon,
TodayIcon, TodayIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Page, PageMeta } from '@blocksuite/store';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx'; import clsx from 'clsx';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -41,21 +43,28 @@ const CountDisplay = ({
return <span {...attrs}>{count > max ? `${max}+` : count}</span>; return <span {...attrs}>{count > max ? `${max}+` : count}</span>;
}; };
interface PageItemProps extends HTMLAttributes<HTMLDivElement> { interface PageItemProps extends HTMLAttributes<HTMLDivElement> {
page: Page; pageMeta: PageMeta;
workspace: BlockSuiteWorkspace;
right?: ReactNode; right?: ReactNode;
} }
const PageItem = ({ page, right, className, ...attrs }: PageItemProps) => { const PageItem = ({
const { isJournal } = useJournalInfoHelper(page.workspace, page.id); pageMeta,
const title = useBlockSuiteWorkspacePageTitle(page.workspace, page.id); workspace,
right,
className,
...attrs
}: PageItemProps) => {
const { isJournal } = useJournalInfoHelper(workspace, pageMeta.id);
const title = useBlockSuiteWorkspacePageTitle(workspace, pageMeta.id);
const Icon = isJournal const Icon = isJournal
? TodayIcon ? TodayIcon
: page.meta.mode === 'edgeless' : pageMeta.mode === 'edgeless'
? EdgelessIcon ? EdgelessIcon
: PageIcon; : PageIcon;
return ( return (
<div <div
aria-label={page.meta.title} aria-label={pageMeta.title}
className={clsx(className, styles.pageItem)} className={clsx(className, styles.pageItem)}
{...attrs} {...attrs}
> >
@@ -114,15 +123,12 @@ const EditorJournalPanel = (props: EditorExtensionProps) => {
}; };
const sortPagesByDate = ( const sortPagesByDate = (
pages: Page[], pages: PageMeta[],
field: 'updatedDate' | 'createDate', field: 'updatedDate' | 'createDate',
order: 'asc' | 'desc' = 'desc' order: 'asc' | 'desc' = 'desc'
) => { ) => {
return [...pages].sort((a, b) => { return [...pages].sort((a, b) => {
return ( return (order === 'asc' ? 1 : -1) * dayjs(b[field]).diff(dayjs(a[field]));
(order === 'asc' ? 1 : -1) *
dayjs(b.meta[field]).diff(dayjs(a.meta[field]))
);
}); });
}; };
@@ -141,21 +147,21 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
const nodeRef = useRef<HTMLDivElement>(null); const nodeRef = useRef<HTMLDivElement>(null);
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const [activeItem, setActiveItem] = useState<NavItemName>('createdToday'); const [activeItem, setActiveItem] = useState<NavItemName>('createdToday');
const pageMetas = useBlockSuitePageMeta(workspace);
const navigateHelper = useNavigateHelper(); const navigateHelper = useNavigateHelper();
const getTodaysPages = useCallback( const getTodaysPages = useCallback(
(field: 'createDate' | 'updatedDate') => { (field: 'createDate' | 'updatedDate') => {
const pages: Page[] = []; return sortPagesByDate(
Array.from(workspace.pages.values()).forEach(page => { pageMetas.filter(pageMeta => {
if (page.meta.trash) return; if (pageMeta.trash) return false;
if (page.meta[field] && dayjs(page.meta[field]).isSame(date, 'day')) { return pageMeta[field] && dayjs(pageMeta[field]).isSame(date, 'day');
pages.push(page); }),
} field
}); );
return sortPagesByDate(pages, field);
}, },
[date, workspace.pages] [date, pageMetas]
); );
const createdToday = useMemo( const createdToday = useMemo(
@@ -224,14 +230,15 @@ const JournalDailyCountBlock = ({ workspace, date }: JournalBlockProps) => {
<Scrollable.Scrollbar /> <Scrollable.Scrollbar />
<Scrollable.Viewport> <Scrollable.Viewport>
<div className={styles.dailyCountContent} ref={nodeRef}> <div className={styles.dailyCountContent} ref={nodeRef}>
{renderList.map((page, index) => ( {renderList.map((pageMeta, index) => (
<PageItem <PageItem
onClick={() => onClick={() =>
navigateHelper.openPage(workspace.id, page.id) navigateHelper.openPage(workspace.id, pageMeta.id)
} }
tabIndex={name === activeItem ? 0 : -1} tabIndex={name === activeItem ? 0 : -1}
key={index} key={index}
page={page} pageMeta={pageMeta}
workspace={workspace}
/> />
))} ))}
</div> </div>
@@ -282,7 +289,8 @@ const ConflictList = ({
<PageItem <PageItem
aria-label={page.meta.title} aria-label={page.meta.title}
aria-selected={isCurrent} aria-selected={isCurrent}
page={page} pageMeta={page.meta}
workspace={workspace}
key={page.id} key={page.id}
right={ right={
<Menu <Menu