feat(core): add history shortcut (#4595)

This commit is contained in:
JimmFly 2023-10-16 20:27:06 +08:00 committed by GitHub
parent 07b5d18441
commit efca651429
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 209 additions and 100 deletions

View File

@ -27,7 +27,9 @@ import { forwardRef, useCallback, useEffect, useMemo } from 'react';
import { openWorkspaceListModalAtom } from '../../atoms';
import { useHistoryAtom } from '../../atoms/history';
import { useAppSetting } from '../../atoms/settings';
import { useGeneralShortcuts } from '../../hooks/affine/use-shortcuts';
import { useTrashModalHelper } from '../../hooks/affine/use-trash-modal-helper';
import { useRegisterBlocksuiteEditorCommands } from '../../hooks/use-shortcut-commands';
import type { AllWorkspace } from '../../shared';
import { currentCollectionsAtom } from '../../utils/user-setting';
import { CollectionsList } from '../pure/workspace-slider-bar/collections';
@ -105,6 +107,8 @@ export const RootAppSidebar = ({
const [openUserWorkspaceList, setOpenUserWorkspaceList] = useAtom(
openWorkspaceListModalAtom
);
const generalShortcutsInfo = useGeneralShortcuts();
const onClickNewPage = useCallback(async () => {
const page = createPage();
await page.waitForLoaded();
@ -161,7 +165,7 @@ export const RootAppSidebar = ({
const closeUserWorkspaceList = useCallback(() => {
setOpenUserWorkspaceList(false);
}, [setOpenUserWorkspaceList]);
useRegisterBlocksuiteEditorCommands(router.back, router.forward);
return (
<>
<AppSidebar
@ -173,6 +177,7 @@ export const RootAppSidebar = ({
environment.isMacOs
)
}
generalShortcutsInfo={generalShortcutsInfo}
>
<MoveToTrash.ConfirmModal
open={trashConfirmOpen}

View File

@ -81,9 +81,8 @@ export const useWinGeneralKeyboardShortcuts = (): ShortcutMap => {
// not implement yet
// [t('appendDailyNote')]: 'Ctrl + Alt + A',
[t('expandOrCollapseSidebar')]: ['Ctrl', '/'],
// not implement yet
// [t('goBack')]: 'Ctrl + [',
// [t('goForward')]: 'Ctrl + ]',
[t('goBack')]: ['Ctrl + ['],
[t('goForward')]: ['Ctrl + ]'],
}),
[t]
);
@ -98,9 +97,8 @@ export const useMacGeneralKeyboardShortcuts = (): ShortcutMap => {
// not implement yet
// [t('appendDailyNote')]: '⌘ + ⌥ + A',
[t('expandOrCollapseSidebar')]: ['⌘', '/'],
// not implement yet
// [t('goBack')]: '⌘ + [',
// [t('goForward')]: '⌘ + ]',
[t('goBack')]: ['⌘ + ['],
[t('goForward')]: ['⌘ + ]'],
}),
[t]
);

View File

@ -0,0 +1,49 @@
import {
PreconditionStrategy,
registerAffineCommand,
} from '@toeverything/infra/command';
import { useEffect } from 'react';
export function useRegisterBlocksuiteEditorCommands(
back: () => unknown,
forward: () => unknown
) {
useEffect(() => {
const unsubs: Array<() => void> = [];
unsubs.push(
registerAffineCommand({
id: 'affine:shortcut-history-go-back',
category: 'affine:general',
preconditionStrategy: PreconditionStrategy.Never,
icon: 'none',
label: 'go back',
keyBinding: {
binding: '$mod+[',
},
run() {
back();
},
})
);
unsubs.push(
registerAffineCommand({
id: 'affine:shortcut-history-go-forward',
category: 'affine:general',
preconditionStrategy: PreconditionStrategy.Never,
icon: 'none',
label: 'go forward',
keyBinding: {
binding: '$mod+]',
},
run() {
forward();
},
})
);
return () => {
unsubs.forEach(unsub => unsub());
};
}, [back, forward]);
}

View File

@ -110,7 +110,10 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
data-enable-animation={enableAnimation && !isResizing}
>
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
<SidebarHeader router={props.router} />
<SidebarHeader
router={props.router}
generalShortcutsInfo={props.generalShortcutsInfo}
/>
<div className={navBodyStyle} data-testid="sliderBar-inner">
{props.children}
</div>

View File

@ -1,6 +1,9 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import { Tooltip } from '@toeverything/components/tooltip';
import { useAtomValue } from 'jotai';
import { useMemo } from 'react';
import type { History } from '..';
import {
@ -17,10 +20,32 @@ export type SidebarHeaderProps = {
forward: () => unknown;
history: History;
};
generalShortcutsInfo?: {
shortcuts: {
[title: string]: string[];
};
};
};
export const SidebarHeader = (props: SidebarHeaderProps) => {
const open = useAtomValue(appSidebarOpenAtom);
const t = useAFFiNEI18N();
const shortcuts = props.generalShortcutsInfo?.shortcuts;
const shortcutsObject = useMemo(() => {
const goBack = t['com.affine.keyboardShortcuts.goBack']();
const goBackShortcut = shortcuts?.[goBack];
const goForward = t['com.affine.keyboardShortcuts.goForward']();
const goForwardShortcut = shortcuts?.[goForward];
return {
goBack,
goBackShortcut,
goForward,
goForwardShortcut,
};
}, [shortcuts, t]);
return (
<div
className={navHeaderStyle}
@ -29,6 +54,10 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
>
<SidebarSwitch show={open} />
<div className={navHeaderNavigationButtons}>
<Tooltip
content={`${shortcutsObject.goBack} ${shortcutsObject.goBackShortcut}`}
side="bottom"
>
<IconButton
className={navHeaderButton}
data-testid="app-sidebar-arrow-button-back"
@ -39,6 +68,11 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
>
<ArrowLeftSmallIcon />
</IconButton>
</Tooltip>
<Tooltip
content={`${shortcutsObject.goForward} ${shortcutsObject.goForwardShortcut}`}
side="bottom"
>
<IconButton
className={navHeaderButton}
data-testid="app-sidebar-arrow-button-forward"
@ -56,6 +90,7 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
>
<ArrowRightSmallIcon />
</IconButton>
</Tooltip>
</div>
</div>
);

View File

@ -1,12 +1,19 @@
import { platform } from 'node:os';
// import { platform } from 'node:os';
import { test } from '@affine-test/kit/electron';
import { withCtrlOrMeta } from '@affine-test/kit/utils/keyboard';
import { getBlockSuiteEditorTitle } from '@affine-test/kit/utils/page-logic';
import {
clickSideBarCurrentWorkspaceBanner,
clickSideBarSettingButton,
} from '@affine-test/kit/utils/sidebar';
import { expect } from '@playwright/test';
import { expect, type Page } from '@playwright/test';
const historyShortcut = async (page: Page, command: 'goBack' | 'goForward') => {
await withCtrlOrMeta(page, () =>
page.keyboard.press(command === 'goBack' ? '[' : ']', { delay: 50 })
);
};
test('new page', async ({ page, workspace }) => {
await page.getByTestId('new-page-button').click({
@ -18,8 +25,8 @@ test('new page', async ({ page, workspace }) => {
});
// macOS only
if (platform() === 'darwin') {
test('app sidebar router forward/back', async ({ page }) => {
// if (platform() === 'darwin') {
test('app sidebar router forward/back', async ({ page }) => {
await page.getByTestId('help-island').click();
await page.getByTestId('easy-guide').click();
await page.getByTestId('onboarding-modal-next-button').click();
@ -64,9 +71,7 @@ if (platform() === 'darwin') {
}
await page.click('[data-testid="app-sidebar-arrow-button-back"]');
await page.waitForTimeout(1000);
await page.click('[data-testid="app-sidebar-arrow-button-back"]');
await page.waitForTimeout(1000);
{
const title = (await page
.locator('.affine-doc-page-block-title')
@ -74,17 +79,31 @@ if (platform() === 'darwin') {
expect(title.trim()).toBe('test1');
}
await page.click('[data-testid="app-sidebar-arrow-button-forward"]');
await page.waitForTimeout(1000);
await page.click('[data-testid="app-sidebar-arrow-button-forward"]');
await page.waitForTimeout(1000);
{
const title = (await page
.locator('.affine-doc-page-block-title')
.textContent()) as string;
expect(title.trim()).toBe('test3');
}
});
}
await historyShortcut(page, 'goBack');
await historyShortcut(page, 'goBack');
{
const title = (await page
.locator('.affine-doc-page-block-title')
.textContent()) as string;
expect(title.trim()).toBe('test1');
}
await historyShortcut(page, 'goForward');
await historyShortcut(page, 'goForward');
{
const title = (await page
.locator('.affine-doc-page-block-title')
.textContent()) as string;
expect(title.trim()).toBe('test3');
}
});
// }
test('clientBorder value should disable by default on window', async ({
page,