diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx index b6bfbfea54..2650995dbb 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx @@ -1,7 +1,9 @@ import { EditorLoading } from '@affine/component/page-detail-skeleton'; import { usePageMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta'; +import { useJournalHelper } from '@affine/core/hooks/use-journal'; +import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; -import { DateTimeIcon, PageIcon } from '@blocksuite/icons'; +import { LinkedPageIcon, TodayIcon } from '@blocksuite/icons'; import type { AffineEditorContainer } from '@blocksuite/presets'; import type { Page } from '@blocksuite/store'; import { use } from 'foxact/use'; @@ -12,12 +14,14 @@ import { Suspense, useCallback, useEffect, + useMemo, useRef, } from 'react'; import { type Map as YMap } from 'yjs'; import { BlocksuiteEditorContainer } from './blocksuite-editor-container'; import type { InlineRenderers } from './specs'; +import * as styles from './styles.css'; export type ErrorBoundaryProps = { onReset?: () => void; @@ -67,54 +71,55 @@ function usePageRoot(page: Page) { return page.root; } -// TODO: this is a placeholder proof-of-concept implementation -function CustomPageReference({ - reference, -}: { +interface PageReferenceProps { reference: HTMLElementTagNameMap['affine-reference']; -}) { - const workspace = reference.page.workspace; - const meta = usePageMetaHelper(workspace); + pageMetaHelper: ReturnType; + journalHelper: ReturnType; + t: ReturnType; +} + +// TODO: this is a placeholder proof-of-concept implementation +function customPageReference({ + reference, + pageMetaHelper, + journalHelper, + t, +}: PageReferenceProps) { + const { isPageJournal, getLocalizedJournalDateString } = journalHelper; assertExists( reference.delta.attributes?.reference?.pageId, 'pageId should exist for page reference' ); - const referencedPage = meta.getPageMeta( - reference.delta.attributes.reference.pageId - ); - const title = referencedPage?.title ?? 'not found'; - let icon = ; - let lTitle = title.toLowerCase(); - if (title.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/)) { - lTitle = new Date(title).toLocaleDateString(undefined, { - year: 'numeric', - month: 'short', - day: 'numeric', - }); - icon = ; + const pageId = reference.delta.attributes.reference.pageId; + const referencedPage = pageMetaHelper.getPageMeta(pageId); + let title = + referencedPage?.title ?? t['com.affine.editor.reference-not-found'](); + let icon = ; + const isJournal = isPageJournal(pageId); + const localizedJournalDate = getLocalizedJournalDateString(pageId); + if (isJournal && localizedJournalDate) { + title = localizedJournalDate; + icon = ; } return ( - - {icon} {lTitle} - + <> + {icon} + {title} + ); } -const customRenderers: InlineRenderers = { +// we cannot pass components to lit renderers, but give them the rendered elements +const customRenderersFactory: ( + opts: Omit +) => InlineRenderers = opts => ({ pageReference(reference) { - return ; + return customPageReference({ + ...opts, + reference, + }); }, -}; +}); /** * TODO: Define error to unexpected state together in the future. @@ -177,6 +182,18 @@ const BlockSuiteEditorImpl = forwardRef( }; }, []); + const pageMetaHelper = usePageMetaHelper(page.workspace); + const journalHelper = useJournalHelper(page.workspace); + const t = useAFFiNEI18N(); + + const customRenderers = useMemo(() => { + return customRenderersFactory({ + pageMetaHelper, + journalHelper, + t, + }); + }, [journalHelper, pageMetaHelper, t]); + return ( { + const { localizedJournalDate, isTodayJournal } = useJournalInfoHelper( + page.workspace, + page.id + ); + const t = useAFFiNEI18N(); + + return ( + + {localizedJournalDate} + {isTodayJournal ? ( + {t['com.affine.today']()} + ) : null} + + ); +}; diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx index 5b985106e1..aca1678c46 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx @@ -1,4 +1,5 @@ import { createReactComponentFromLit } from '@affine/component'; +import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { BiDirectionalLinkPanel, DocEditor, @@ -8,8 +9,15 @@ import { } from '@blocksuite/presets'; import { type Page } from '@blocksuite/store'; import clsx from 'clsx'; -import React, { forwardRef, useEffect, useMemo, useRef } from 'react'; +import React, { + forwardRef, + useCallback, + useEffect, + useMemo, + useRef, +} from 'react'; +import { BlocksuiteEditorJournalDocTitle } from './journal-doc-title'; import { docModeSpecs, edgelessModeSpecs, @@ -52,6 +60,22 @@ export const BlocksuiteDocEditor = forwardRef< BlocksuiteDocEditorProps >(function BlocksuiteDocEditor({ page, customRenderers }, ref) { const titleRef = useRef(null); + const docRef = useRef(null); + const { isJournal } = useJournalInfoHelper(page.workspace, page.id); + + const onDocRef = useCallback( + (el: DocEditor) => { + docRef.current = el; + if (ref) { + if (typeof ref === 'function') { + ref(el); + } else { + ref.current = el; + } + } + }, + [ref] + ); const specs = useMemo(() => { return patchSpecs(docModeSpecs, customRenderers); @@ -63,6 +87,8 @@ export const BlocksuiteDocEditor = forwardRef< if (titleRef.current) { const richText = titleRef.current.querySelector('rich-text'); richText?.inlineEditor?.focusEnd(); + } else { + docRef.current?.querySelector('affine-doc-page')?.focusFirstParagraph(); } }); }, []); @@ -70,12 +96,16 @@ export const BlocksuiteDocEditor = forwardRef< return (
- + {!isJournal ? ( + + ) : ( + + )} {/* We will replace page meta tags with our own implementation */} { const handleRef = useRef(null); const { journalDate } = useJournalInfoHelper(workspace, page.id); - const { openJournal } = useJournalHelper(workspace); + const { openJournal } = useJournalRouteHelper(workspace); const [date, setDate] = useState( (journalDate ?? dayjs()).format('YYYY-MM-DD') ); diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-header/journal/today-button.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-header/journal/today-button.tsx index 98d9b036f5..b6e3c21870 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-header/journal/today-button.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-header/journal/today-button.tsx @@ -1,5 +1,5 @@ import { Button } from '@affine/component'; -import { useJournalHelper } from '@affine/core/hooks/use-journal'; +import { useJournalRouteHelper } from '@affine/core/hooks/use-journal'; import type { BlockSuiteWorkspace } from '@affine/core/shared'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useCallback } from 'react'; @@ -10,7 +10,7 @@ export interface JournalTodayButtonProps { export const JournalTodayButton = ({ workspace }: JournalTodayButtonProps) => { const t = useAFFiNEI18N(); - const journalHelper = useJournalHelper(workspace); + const journalHelper = useJournalRouteHelper(workspace); const onToday = useCallback(() => { journalHelper.openToday(); diff --git a/packages/frontend/core/src/components/page-list/page-group.tsx b/packages/frontend/core/src/components/page-list/page-group.tsx index 77dc4ba191..a3ce3bbf66 100644 --- a/packages/frontend/core/src/components/page-list/page-group.tsx +++ b/packages/frontend/core/src/components/page-list/page-group.tsx @@ -1,7 +1,14 @@ +import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title'; +import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import type { Tag } from '@affine/env/filter'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; -import { EdgelessIcon, PageIcon, ToggleCollapseIcon } from '@blocksuite/icons'; +import { + EdgelessIcon, + PageIcon, + TodayIcon, + ToggleCollapseIcon, +} from '@blocksuite/icons'; import type { PageMeta, Workspace } from '@blocksuite/store'; import * as Collapsible from '@radix-ui/react-collapsible'; import clsx from 'clsx'; @@ -212,6 +219,28 @@ function tagIdToTagOption( ); } +const PageTitle = ({ id, workspace }: { id: string; workspace: Workspace }) => { + const title = useBlockSuiteWorkspacePageTitle(workspace, id); + return title; +}; + +const UnifiedPageIcon = ({ + id, + workspace, + isPreferredEdgeless, +}: { + id: string; + workspace: Workspace; + isPreferredEdgeless: (id: string) => boolean; +}) => { + const isEdgeless = isPreferredEdgeless(id); + const { isJournal } = useJournalInfoHelper(workspace, id); + if (isJournal) { + return ; + } + return isEdgeless ? : ; +}; + function pageMetaToPageItemProp( pageMeta: PageMeta, props: RequiredProps @@ -237,7 +266,7 @@ function pageMetaToPageItemProp( : undefined; const itemProps: PageListItemProps = { pageId: pageMeta.id, - title: pageMeta.title, + title: , preview: ( ), @@ -250,10 +279,12 @@ function pageMetaToPageItemProp( ? `/workspace/${props.blockSuiteWorkspace.id}/${pageMeta.id}` : undefined, onClick: props.selectable ? toggleSelection : undefined, - icon: props.isPreferredEdgeless?.(pageMeta.id) ? ( - - ) : ( - + icon: ( + ), tags: pageMeta.tags diff --git a/packages/frontend/core/src/components/root-app-sidebar/journal-button.tsx b/packages/frontend/core/src/components/root-app-sidebar/journal-button.tsx index cf37a082be..b53c3c3eef 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/journal-button.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/journal-button.tsx @@ -1,8 +1,8 @@ import { MenuItem } from '@affine/component/app-sidebar'; import { currentPageIdAtom } from '@affine/core/atoms/mode'; import { - useJournalHelper, useJournalInfoHelper, + useJournalRouteHelper, } from '@affine/core/hooks/use-journal'; import type { BlockSuiteWorkspace } from '@affine/core/shared'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; @@ -19,7 +19,7 @@ export const AppSidebarJournalButton = ({ }: AppSidebarJournalButtonProps) => { const t = useAFFiNEI18N(); const currentPageId = useAtomValue(currentPageIdAtom); - const { openToday } = useJournalHelper(workspace); + const { openToday } = useJournalRouteHelper(workspace); const { journalDate, isJournal } = useJournalInfoHelper( workspace, currentPageId diff --git a/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.ts b/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.ts deleted file mode 100644 index fc48a6b5e6..0000000000 --- a/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @vitest-environment happy-dom - */ -import 'fake-indexeddb/auto'; - -import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; -import { assertExists } from '@blocksuite/global/utils'; -import type { Page } from '@blocksuite/store'; -import { Schema, Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; -import { renderHook } from '@testing-library/react'; -import { describe, expect, test, vi } from 'vitest'; -import { beforeEach } from 'vitest'; - -import { useBlockSuiteWorkspacePageTitle } from '../use-block-suite-workspace-page-title'; - -let blockSuiteWorkspace: BlockSuiteWorkspace; - -const schema = new Schema(); -schema.register(AffineSchemas).register(__unstableSchemas); - -beforeEach(async () => { - vi.useFakeTimers({ toFake: ['requestIdleCallback'] }); - blockSuiteWorkspace = new BlockSuiteWorkspace({ id: 'test', schema }); - const initPage = async (page: Page) => { - await page.waitForLoaded(); - expect(page).not.toBeNull(); - assertExists(page); - const pageBlockId = page.addBlock('affine:page', { - title: new page.Text(''), - }); - const frameId = page.addBlock('affine:note', {}, pageBlockId); - page.addBlock('affine:paragraph', {}, frameId); - }; - await initPage(blockSuiteWorkspace.createPage({ id: 'page0' })); - await initPage(blockSuiteWorkspace.createPage({ id: 'page1' })); - await initPage(blockSuiteWorkspace.createPage({ id: 'page2' })); -}); - -describe('useBlockSuiteWorkspacePageTitle', () => { - test('basic', async () => { - const pageTitleHook = renderHook(() => - useBlockSuiteWorkspacePageTitle(blockSuiteWorkspace, 'page0') - ); - expect(pageTitleHook.result.current).toBe('Untitled'); - blockSuiteWorkspace.setPageMeta('page0', { title: '1' }); - pageTitleHook.rerender(); - expect(pageTitleHook.result.current).toBe('1'); - }); -}); diff --git a/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.tsx b/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.tsx new file mode 100644 index 0000000000..c7d4365801 --- /dev/null +++ b/packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.tsx @@ -0,0 +1,102 @@ +/** + * @vitest-environment happy-dom + */ +import 'fake-indexeddb/auto'; + +import { + currentWorkspaceAtom, + WorkspacePropertiesAdapter, +} from '@affine/core/modules/workspace'; +import { WorkspaceFlavour } from '@affine/env/workspace'; +import type { Workspace } from '@affine/workspace/workspace'; +import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models'; +import { assertExists } from '@blocksuite/global/utils'; +import { type Page, Workspace as BlockSuiteWorkspace } from '@blocksuite/store'; +import { Schema } from '@blocksuite/store'; +import { render } from '@testing-library/react'; +import { createStore, Provider } from 'jotai'; +import { Suspense } from 'react'; +import { describe, expect, test, vi } from 'vitest'; +import { beforeEach } from 'vitest'; + +import { useBlockSuiteWorkspacePageTitle } from '../use-block-suite-workspace-page-title'; + +let blockSuiteWorkspace: BlockSuiteWorkspace; +const store = createStore(); + +const schema = new Schema(); +schema.register(AffineSchemas).register(__unstableSchemas); + +const Component = () => { + const title = useBlockSuiteWorkspacePageTitle(blockSuiteWorkspace, 'page0'); + return
title: {title}
; +}; + +// todo: this module has some side-effects that will break the tests +vi.mock('@affine/workspace-impl', () => ({ + default: {}, +})); + +beforeEach(async () => { + vi.useFakeTimers({ toFake: ['requestIdleCallback'] }); + + blockSuiteWorkspace = new BlockSuiteWorkspace({ id: 'test', schema }); + + const workspace = { + blockSuiteWorkspace, + flavour: WorkspaceFlavour.LOCAL, + } as Workspace; + + store.set(currentWorkspaceAtom, workspace); + + blockSuiteWorkspace = workspace.blockSuiteWorkspace; + + const initPage = async (page: Page) => { + await page.waitForLoaded(); + expect(page).not.toBeNull(); + assertExists(page); + const pageBlockId = page.addBlock('affine:page', { + title: new page.Text(''), + }); + const frameId = page.addBlock('affine:note', {}, pageBlockId); + page.addBlock('affine:paragraph', {}, frameId); + }; + await initPage(blockSuiteWorkspace.createPage({ id: 'page0' })); + await initPage(blockSuiteWorkspace.createPage({ id: 'page1' })); + await initPage(blockSuiteWorkspace.createPage({ id: 'page2' })); +}); + +describe('useBlockSuiteWorkspacePageTitle', () => { + test('basic', async () => { + const { findByText, rerender } = render( + + + + + + ); + expect(await findByText('title: Untitled')).toBeDefined(); + blockSuiteWorkspace.setPageMeta('page0', { title: '1' }); + rerender( + + + + + + ); + expect(await findByText('title: 1')).toBeDefined(); + }); + + test('journal', async () => { + const adapter = new WorkspacePropertiesAdapter(blockSuiteWorkspace); + adapter.setJournalPageDateString('page0', '2021-01-01'); + const { findByText } = render( + + + + + + ); + expect(await findByText('title: Jan 1, 2021')).toBeDefined(); + }); +}); diff --git a/packages/frontend/core/src/hooks/use-affine-adapter.ts b/packages/frontend/core/src/hooks/use-affine-adapter.ts index 8e0be39bda..b55a92e996 100644 --- a/packages/frontend/core/src/hooks/use-affine-adapter.ts +++ b/packages/frontend/core/src/hooks/use-affine-adapter.ts @@ -5,7 +5,7 @@ import { useEffect, useMemo, useReducer } from 'react'; import { currentWorkspacePropertiesAdapterAtom, WorkspacePropertiesAdapter, -} from '../modules/workspace'; +} from '../modules/workspace/properties'; const useReactiveAdapter = (adapter: WorkspacePropertiesAdapter) => { const [, forceUpdate] = useReducer(c => c + 1, 0); diff --git a/packages/frontend/core/src/hooks/use-block-suite-workspace-page-title.ts b/packages/frontend/core/src/hooks/use-block-suite-workspace-page-title.ts index 443ada4347..4b6fc4a23c 100644 --- a/packages/frontend/core/src/hooks/use-block-suite-workspace-page-title.ts +++ b/packages/frontend/core/src/hooks/use-block-suite-workspace-page-title.ts @@ -3,6 +3,8 @@ import type { Workspace } from '@blocksuite/store'; import type { Atom } from 'jotai'; import { atom, useAtomValue } from 'jotai'; +import { useJournalInfoHelper } from './use-journal'; + const weakMap = new WeakMap>>(); function getAtom(w: Workspace, pageId: string): Atom { @@ -35,5 +37,10 @@ export function useBlockSuiteWorkspacePageTitle( ) { const titleAtom = getAtom(blockSuiteWorkspace, pageId); assertExists(titleAtom); - return useAtomValue(titleAtom); + const title = useAtomValue(titleAtom); + const { localizedJournalDate } = useJournalInfoHelper( + blockSuiteWorkspace, + pageId + ); + return localizedJournalDate || title; } diff --git a/packages/frontend/core/src/hooks/use-journal.ts b/packages/frontend/core/src/hooks/use-journal.ts index 4fe46c6bae..646f692a08 100644 --- a/packages/frontend/core/src/hooks/use-journal.ts +++ b/packages/frontend/core/src/hooks/use-journal.ts @@ -25,8 +25,6 @@ function toDayjs(j?: string | false) { export const useJournalHelper = (workspace: BlockSuiteWorkspace) => { const bsWorkspaceHelper = useBlockSuiteWorkspaceHelper(workspace); - const navigateHelper = useNavigateHelper(); - const adapter = useWorkspacePropertiesAdapter(workspace); /** @@ -82,25 +80,15 @@ export const useJournalHelper = (workspace: BlockSuiteWorkspace) => { [_createJournal, getJournalsByDate] ); - /** - * open journal by date, create one if not exist - */ - const openJournal = useCallback( - (maybeDate: MaybeDate) => { - const page = getJournalByDate(maybeDate); - navigateHelper.openPage(workspace.id, page.id); + const isPageTodayJournal = useCallback( + (pageId: string) => { + const date = dayjs().format(JOURNAL_DATE_FORMAT); + const d = adapter.getJournalPageDateString(pageId); + return isPageJournal(pageId) && d === date; }, - [getJournalByDate, navigateHelper, workspace.id] + [adapter, isPageJournal] ); - /** - * open today's journal - */ - const openToday = useCallback(() => { - const date = dayjs().format(JOURNAL_DATE_FORMAT); - openJournal(date); - }, [openJournal]); - const getJournalDateString = useCallback( (pageId: string) => { return adapter.getJournalPageDateString(pageId); @@ -123,9 +111,8 @@ export const useJournalHelper = (workspace: BlockSuiteWorkspace) => { getJournalByDate, getJournalDateString, getLocalizedJournalDateString, - openJournal, - openToday, isPageJournal, + isPageTodayJournal, }), [ getJournalByDate, @@ -133,9 +120,40 @@ export const useJournalHelper = (workspace: BlockSuiteWorkspace) => { getJournalsByDate, getLocalizedJournalDateString, isPageJournal, + isPageTodayJournal, + ] + ); +}; + +// split useJournalRouteHelper since it requires a context, which may not work in lit +export const useJournalRouteHelper = (workspace: BlockSuiteWorkspace) => { + const navigateHelper = useNavigateHelper(); + const { getJournalByDate } = useJournalHelper(workspace); + /** + * open journal by date, create one if not exist + */ + const openJournal = useCallback( + (maybeDate: MaybeDate) => { + const page = getJournalByDate(maybeDate); + navigateHelper.openPage(workspace.id, page.id); + }, + [getJournalByDate, navigateHelper, workspace.id] + ); + + /** + * open today's journal + */ + const openToday = useCallback(() => { + const date = dayjs().format(JOURNAL_DATE_FORMAT); + openJournal(date); + }, [openJournal]); + + return useMemo( + () => ({ openJournal, openToday, - ] + }), + [openJournal, openToday] ); }; @@ -143,17 +161,28 @@ export const useJournalInfoHelper = ( workspace: BlockSuiteWorkspace, pageId?: string | null ) => { - const { isPageJournal, getJournalDateString } = useJournalHelper(workspace); - const journalDate = useMemo( - () => (pageId ? toDayjs(getJournalDateString(pageId)) : null), - [getJournalDateString, pageId] - ); + const { + isPageJournal, + getJournalDateString, + getLocalizedJournalDateString, + isPageTodayJournal, + } = useJournalHelper(workspace); return useMemo( () => ({ isJournal: pageId ? isPageJournal(pageId) : false, - journalDate, + journalDate: pageId ? toDayjs(getJournalDateString(pageId)) : null, + localizedJournalDate: pageId + ? getLocalizedJournalDateString(pageId) + : null, + isTodayJournal: pageId ? isPageTodayJournal(pageId) : false, }), - [isPageJournal, journalDate, pageId] + [ + getJournalDateString, + getLocalizedJournalDateString, + isPageJournal, + isPageTodayJournal, + pageId, + ] ); }; diff --git a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx index 8b1fa7eadf..a24fad4a2d 100644 --- a/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx +++ b/packages/frontend/core/src/pages/workspace/detail-page/detail-page.tsx @@ -139,6 +139,7 @@ const DetailPageImpl = memo(function DetailPageImpl({ page }: { page: Page }) { } } catch {} setPageMode(currentPageId, mode); + // fixme: it seems pageLinkClicked is not triggered sometimes? const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => { return openPage(blockSuiteWorkspace.id, pageId); }); 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 f97008b0ea..b6df10577c 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,9 +6,11 @@ import { } from '@affine/component'; import { MoveToTrash } from '@affine/core/components/page-list'; import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper'; +import { useBlockSuiteWorkspacePageTitle } from '@affine/core/hooks/use-block-suite-workspace-page-title'; import { useJournalHelper, useJournalInfoHelper, + useJournalRouteHelper, } from '@affine/core/hooks/use-journal'; import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; @@ -44,6 +46,7 @@ interface PageItemProps extends HTMLAttributes { } const PageItem = ({ page, right, className, ...attrs }: PageItemProps) => { const { isJournal } = useJournalInfoHelper(page.workspace, page.id); + const title = useBlockSuiteWorkspacePageTitle(page.workspace, page.id); const Icon = isJournal ? TodayIcon @@ -59,7 +62,7 @@ const PageItem = ({ page, right, className, ...attrs }: PageItemProps) => {
- {page.meta.title} + {title} {right}
); @@ -81,7 +84,7 @@ const EditorJournalPanel = (props: EditorExtensionProps) => { page.workspace, page.id ); - const { openJournal } = useJournalHelper(workspace); + const { openJournal } = useJournalRouteHelper(workspace); const [date, setDate] = useState(dayjs().format('YYYY-MM-DD')); useEffect(() => { diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 6abf39ac63..4fc3ca9fbc 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1049,5 +1049,6 @@ "com.affine.journal.daily-count-created-empty-tips": "You haven't created anything yet", "com.affine.journal.daily-count-updated-empty-tips": "You haven't updated anything yet", "com.affine.journal.conflict-show-more": "{{count}} more articles", - "com.affine.journal.app-sidebar-title": "Journals" + "com.affine.journal.app-sidebar-title": "Journals", + "com.affine.editor.reference-not-found": "Linked page not found" } diff --git a/test.txt b/test.txt new file mode 100644 index 0000000000..dec6048b25 --- /dev/null +++ b/test.txt @@ -0,0 +1,16 @@ + + RUN v1.1.3 /Users/pengx17/Documents/GitHub/AFFiNE + + ✓ packages/frontend/core/src/hooks/__tests__/use-block-suite-workspace-page-title.spec.tsx (1 test) 11ms + +⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯ + +Vitest caught 2 unhandled errors during the test run. +This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected. +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ + Test Files 1 passed (1) + Tests 1 passed (1) + Errors 2 errors + Start at 18:09:25 + Duration 1.63s (transform 536ms, setup 40ms, collect 1.31s, tests 11ms, environment 86ms, prepare 38ms) + diff --git a/vitest.config.ts b/vitest.config.ts index 721cf12c93..fbfe90d02a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -14,6 +14,9 @@ export default defineConfig({ alias: { // prevent tests using two different sources of yjs yjs: resolve(rootDir, 'node_modules/yjs'), + '@affine/core': fileURLToPath( + new URL('./packages/frontend/core/src', import.meta.url) + ), }, }, test: {