From 5dd2dddd74b0332983487bb5163a3744a911e505 Mon Sep 17 00:00:00 2001 From: CatsJuice Date: Thu, 12 Dec 2024 07:14:05 +0000 Subject: [PATCH] feat(mobile): show page back by url search (#9100) close AF-1911 --- .../core/src/components/hooks/use-journal.ts | 4 +-- .../src/mobile/components/app-tabs/create.tsx | 7 ++-- .../mobile/components/app-tabs/journal.tsx | 7 ++-- .../src/mobile/components/doc-card/index.tsx | 1 + .../workspace/detail/mobile-detail-page.tsx | 17 +++++---- .../modules/workbench/entities/workbench.ts | 7 +++- .../e2e/back-button-visibility.spec.ts | 35 +++++++++++++++++++ tests/affine-mobile/e2e/utils.ts | 12 +++++++ 8 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 tests/affine-mobile/e2e/back-button-visibility.spec.ts diff --git a/packages/frontend/core/src/components/hooks/use-journal.ts b/packages/frontend/core/src/components/hooks/use-journal.ts index 25156d62f1..7c679865db 100644 --- a/packages/frontend/core/src/components/hooks/use-journal.ts +++ b/packages/frontend/core/src/components/hooks/use-journal.ts @@ -61,9 +61,7 @@ export const useJournalRouteHelper = () => { const openJournal = useCallback( (maybeDate: MaybeDate, newTab?: boolean) => { const page = getJournalByDate(maybeDate); - workbench.openDoc(page.id, { - at: newTab ? 'new-tab' : 'active', - }); + workbench.openDoc(page.id, { at: newTab ? 'new-tab' : 'active' }); track.$.navigationPanel.journal.navigate({ to: 'journal', }); diff --git a/packages/frontend/core/src/mobile/components/app-tabs/create.tsx b/packages/frontend/core/src/mobile/components/app-tabs/create.tsx index 900bfacdde..94681eb6c0 100644 --- a/packages/frontend/core/src/mobile/components/app-tabs/create.tsx +++ b/packages/frontend/core/src/mobile/components/app-tabs/create.tsx @@ -1,4 +1,5 @@ import { usePageHelper } from '@affine/core/components/blocksuite/block-suite-page-list/utils'; +import { WorkbenchService } from '@affine/core/modules/workbench'; import track from '@affine/track'; import { EditIcon } from '@blocksuite/icons/rc'; import { useService, WorkspaceService } from '@toeverything/infra'; @@ -8,6 +9,7 @@ import type { AppTabCustomFCProps } from './data'; import { TabItem } from './tab-item'; export const AppTabCreate = ({ tab }: AppTabCustomFCProps) => { + const workbench = useService(WorkbenchService).workbench; const workspaceService = useService(WorkspaceService); const currentWorkspace = workspaceService.workspace; const pageHelper = usePageHelper(currentWorkspace.docCollection); @@ -15,10 +17,11 @@ export const AppTabCreate = ({ tab }: AppTabCustomFCProps) => { const createPage = useCallback( (isActive: boolean) => { if (isActive) return; - pageHelper.createPage(undefined, true); + const doc = pageHelper.createPage(undefined, false); + workbench.openDoc({ docId: doc.id, fromTab: 'true' }); track.$.navigationPanel.$.createDoc(); }, - [pageHelper] + [pageHelper, workbench] ); return ( diff --git a/packages/frontend/core/src/mobile/components/app-tabs/journal.tsx b/packages/frontend/core/src/mobile/components/app-tabs/journal.tsx index 53b731b246..138757a8ea 100644 --- a/packages/frontend/core/src/mobile/components/app-tabs/journal.tsx +++ b/packages/frontend/core/src/mobile/components/app-tabs/journal.tsx @@ -1,4 +1,3 @@ -import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal'; import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta'; import { JournalService } from '@affine/core/modules/journal'; import { WorkbenchService } from '@affine/core/modules/workbench'; @@ -21,8 +20,10 @@ export const AppTabJournal = ({ tab }: AppTabCustomFCProps) => { docDisplayMetaService.icon$(maybeDocId, { compareDate: new Date() }) ); - const { openToday } = useJournalRouteHelper(); - const handleOpenToday = useCallback(() => openToday(false), [openToday]); + const handleOpenToday = useCallback(() => { + const docId = journalService.ensureJournalByDate(new Date()).id; + workbench.openDoc({ docId, fromTab: 'true' }, { at: 'active' }); + }, [journalService, workbench]); const Icon = journalDate ? JournalIcon : TodayIcon; diff --git a/packages/frontend/core/src/mobile/components/doc-card/index.tsx b/packages/frontend/core/src/mobile/components/doc-card/index.tsx index 328b62c0df..7c4256bd2b 100644 --- a/packages/frontend/core/src/mobile/components/doc-card/index.tsx +++ b/packages/frontend/core/src/mobile/components/doc-card/index.tsx @@ -70,6 +70,7 @@ export const DocCard = forwardRef( ref={ref} className={clsx(styles.card, className)} data-testid="doc-card" + data-doc-id={meta.id} {...attrs} >
diff --git a/packages/frontend/core/src/mobile/pages/workspace/detail/mobile-detail-page.tsx b/packages/frontend/core/src/mobile/pages/workspace/detail/mobile-detail-page.tsx index cbafe84169..4ec730b57d 100644 --- a/packages/frontend/core/src/mobile/pages/workspace/detail/mobile-detail-page.tsx +++ b/packages/frontend/core/src/mobile/pages/workspace/detail/mobile-detail-page.tsx @@ -5,7 +5,6 @@ import { useRegisterBlocksuiteEditorCommands } from '@affine/core/components/hoo import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor'; import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta'; import { usePageDocumentTitle } from '@affine/core/components/hooks/use-global-state'; -import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal'; import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper'; import { PageDetailEditor } from '@affine/core/components/page-detail-editor'; import { DetailPageWrapper } from '@affine/core/desktop/pages/workspace/detail-page/detail-page-wrapper'; @@ -244,20 +243,26 @@ const MobileDetailPage = ({ const t = useI18n(); const docDisplayMetaService = useService(DocDisplayMetaService); const journalService = useService(JournalService); - + const workbench = useService(WorkbenchService).workbench; const [showTitle, setShowTitle] = useState(checkShowTitle); - const { openJournal } = useJournalRouteHelper(); const titleInfo = useLiveData(docDisplayMetaService.title$(pageId)); const title = typeof titleInfo === 'string' ? titleInfo : t[titleInfo.i18nKey](); const allJournalDates = useLiveData(journalService.allJournalDates$); + const location = useLiveData(workbench.location$); + const fromTab = location.search.includes('fromTab'); + const handleDateChange = useCallback( (date: string) => { - openJournal(date); + const docId = journalService.ensureJournalByDate(date).id; + workbench.openDoc( + { docId, fromTab: fromTab ? 'true' : undefined }, + { replaceHistory: true } + ); }, - [openJournal] + [fromTab, journalService, workbench] ); useGlobalEvent( @@ -273,7 +278,7 @@ const MobileDetailPage = ({ pageId={pageId} > + )), options?: WorkbenchOpenOptions ) { const isString = typeof id === 'string'; diff --git a/tests/affine-mobile/e2e/back-button-visibility.spec.ts b/tests/affine-mobile/e2e/back-button-visibility.spec.ts new file mode 100644 index 0000000000..bd1211dfe0 --- /dev/null +++ b/tests/affine-mobile/e2e/back-button-visibility.spec.ts @@ -0,0 +1,35 @@ +import { test } from '@affine-test/kit/mobile'; +import { expect, type Page } from '@playwright/test'; + +import { expandCollapsibleSection, openTab } from './utils'; + +const locateBack = (page: Page) => page.getByTestId('page-header-back'); + +test('new doc via app tab should not show back', async ({ page }) => { + // directly open new doc, should not show back + await openTab(page, 'New Page'); + await expect(locateBack(page)).not.toBeVisible(); + const docId = await page.evaluate(() => location.pathname.split('/').pop()); + + // back to home, and open the doc, should show back + await openTab(page, 'home'); + await expandCollapsibleSection(page, 'recent'); + const docCard = page.locator( + `[data-testid="doc-card"][data-doc-id="${docId}"]` + ); + await docCard.click(); + await expect(locateBack(page)).toBeVisible(); +}); + +// TODO(@CatsJuice): mobile @ menu is not ready +// test('jump to linked doc should show back', async ({ page }) => { +// await openTab(page, 'New Page'); +// await expect(locateBack(page)).not.toBeVisible(); +// const docId = await page.evaluate(() => location.pathname.split('/').pop()); +// await page.keyboard.type('Test Doc'); +// await page.keyboard.press('Enter'); +// await page.waitForTimeout(100); +// await createLinkedPage(page, 'Test Linked Doc'); + +// await expect(locateBack(page)).toBeVisible(); +// }); diff --git a/tests/affine-mobile/e2e/utils.ts b/tests/affine-mobile/e2e/utils.ts index 4a71832ff7..fa4f8bfe79 100644 --- a/tests/affine-mobile/e2e/utils.ts +++ b/tests/affine-mobile/e2e/utils.ts @@ -41,3 +41,15 @@ export async function openExplorerNodeMenu(page: Page, node: Locator) { await expect(menu).toBeVisible(); return menu; } + +export async function openTab( + page: Page, + name: 'home' | 'all' | 'Journal' | 'New Page' +) { + const tab = page.locator('#app-tabs').getByRole('tab', { name }); + await expect(tab).toBeVisible(); + await tab.click(); + // eslint-disable-next-line unicorn/prefer-dom-node-dataset + const isActive = await tab.getAttribute('data-active'); + expect(isActive).toBe('true'); +}