feat(core): show searched result with results group and add duplicate commands (#5073)
[TOV-65](https://linear.app/affine-design/issue/TOV-65/should-show-searched-result-without-categories) https://github.com/toeverything/AFFiNE/assets/102217452/50fba70b-7efa-4e47-ba8a-de21e400166c
This commit is contained in:
@@ -20,23 +20,15 @@ import {
|
|||||||
MenuItem,
|
MenuItem,
|
||||||
MenuSeparator,
|
MenuSeparator,
|
||||||
} from '@toeverything/components/menu';
|
} from '@toeverything/components/menu';
|
||||||
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
|
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||||
import {
|
import { useAtomValue } from 'jotai';
|
||||||
useBlockSuitePageMeta,
|
|
||||||
usePageMetaHelper,
|
|
||||||
} from '@toeverything/hooks/use-block-suite-page-meta';
|
|
||||||
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
|
||||||
import { useCallback, useRef, useState } from 'react';
|
import { useCallback, useRef, useState } from 'react';
|
||||||
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
|
|
||||||
|
|
||||||
import { setPageModeAtom } from '../../../atoms';
|
|
||||||
import { currentModeAtom } from '../../../atoms/mode';
|
import { currentModeAtom } from '../../../atoms/mode';
|
||||||
import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper';
|
import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper';
|
||||||
import { useExportPage } from '../../../hooks/affine/use-export-page';
|
import { useExportPage } from '../../../hooks/affine/use-export-page';
|
||||||
import { useTrashModalHelper } from '../../../hooks/affine/use-trash-modal-helper';
|
import { useTrashModalHelper } from '../../../hooks/affine/use-trash-modal-helper';
|
||||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||||
import { useNavigateHelper } from '../../../hooks/use-navigate-helper';
|
|
||||||
import { toast } from '../../../utils';
|
import { toast } from '../../../utils';
|
||||||
import { PageHistoryModal } from '../../affine/page-history-modal/history-modal';
|
import { PageHistoryModal } from '../../affine/page-history-modal/history-modal';
|
||||||
import { HeaderDropDownButton } from '../../pure/header-drop-down-button';
|
import { HeaderDropDownButton } from '../../pure/header-drop-down-button';
|
||||||
@@ -50,7 +42,6 @@ type PageMenuProps = {
|
|||||||
export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
||||||
const t = useAFFiNEI18N();
|
const t = useAFFiNEI18N();
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
const { openPage } = useNavigateHelper();
|
|
||||||
|
|
||||||
// fixme(himself65): remove these hooks ASAP
|
// fixme(himself65): remove these hooks ASAP
|
||||||
const [workspace] = useCurrentWorkspace();
|
const [workspace] = useCurrentWorkspace();
|
||||||
@@ -64,11 +55,9 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
|||||||
const currentMode = useAtomValue(currentModeAtom);
|
const currentMode = useAtomValue(currentModeAtom);
|
||||||
const favorite = pageMeta.favorite ?? false;
|
const favorite = pageMeta.favorite ?? false;
|
||||||
|
|
||||||
const { setPageMeta, setPageTitle } = usePageMetaHelper(blockSuiteWorkspace);
|
const { togglePageMode, toggleFavorite, duplicate } =
|
||||||
const { togglePageMode, toggleFavorite } =
|
|
||||||
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
||||||
const { importFile } = usePageHelper(blockSuiteWorkspace);
|
const { importFile } = usePageHelper(blockSuiteWorkspace);
|
||||||
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
|
||||||
const { setTrashModal } = useTrashModalHelper(blockSuiteWorkspace);
|
const { setTrashModal } = useTrashModalHelper(blockSuiteWorkspace);
|
||||||
|
|
||||||
const [historyModalOpen, setHistoryModalOpen] = useState(false);
|
const [historyModalOpen, setHistoryModalOpen] = useState(false);
|
||||||
@@ -107,34 +96,11 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const exportHandler = useExportPage(currentPage);
|
const exportHandler = useExportPage(currentPage);
|
||||||
const setPageMode = useSetAtom(setPageModeAtom);
|
|
||||||
|
|
||||||
const duplicate = useAsyncCallback(async () => {
|
const handleDuplicate = useCallback(() => {
|
||||||
const currentPageMeta = currentPage.meta;
|
duplicate(pageId);
|
||||||
const newPage = createPage();
|
}, [duplicate, pageId]);
|
||||||
await newPage.waitForLoaded();
|
|
||||||
|
|
||||||
const update = encodeStateAsUpdate(currentPage.spaceDoc);
|
|
||||||
applyUpdate(newPage.spaceDoc, update);
|
|
||||||
|
|
||||||
setPageMeta(newPage.id, {
|
|
||||||
tags: currentPageMeta.tags,
|
|
||||||
favorite: currentPageMeta.favorite,
|
|
||||||
});
|
|
||||||
setPageMode(newPage.id, currentMode);
|
|
||||||
setPageTitle(newPage.id, `${currentPageMeta.title}(1)`);
|
|
||||||
openPage(blockSuiteWorkspace.id, newPage.id);
|
|
||||||
}, [
|
|
||||||
blockSuiteWorkspace.id,
|
|
||||||
createPage,
|
|
||||||
currentMode,
|
|
||||||
currentPage.meta,
|
|
||||||
currentPage.spaceDoc,
|
|
||||||
openPage,
|
|
||||||
setPageMeta,
|
|
||||||
setPageMode,
|
|
||||||
setPageTitle,
|
|
||||||
]);
|
|
||||||
const EditMenu = (
|
const EditMenu = (
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -199,7 +165,7 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
|||||||
</MenuIcon>
|
</MenuIcon>
|
||||||
}
|
}
|
||||||
data-testid="editor-option-menu-duplicate"
|
data-testid="editor-option-menu-duplicate"
|
||||||
onSelect={duplicate}
|
onSelect={handleDuplicate}
|
||||||
style={menuItemStyle}
|
style={menuItemStyle}
|
||||||
>
|
>
|
||||||
{t['com.affine.header.option.duplicate']()}
|
{t['com.affine.header.option.duplicate']()}
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
|
|||||||
const { openPage, jumpToSubPath } = useNavigateHelper();
|
const { openPage, jumpToSubPath } = useNavigateHelper();
|
||||||
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
||||||
const pageSettings = useAtomValue(pageSettingsAtom);
|
const pageSettings = useAtomValue(pageSettingsAtom);
|
||||||
|
|
||||||
const isPreferredEdgeless = useCallback(
|
const isPreferredEdgeless = useCallback(
|
||||||
(pageId: string) => pageSettings[pageId]?.mode === 'edgeless',
|
(pageId: string) => pageSettings[pageId]?.mode === 'edgeless',
|
||||||
[pageSettings]
|
[pageSettings]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setPageMode = useSetAtom(setPageModeAtom);
|
const setPageMode = useSetAtom(setPageModeAtom);
|
||||||
|
|
||||||
const createPageAndOpen = useCallback(
|
const createPageAndOpen = useCallback(
|
||||||
(mode?: 'page' | 'edgeless') => {
|
(mode?: 'page' | 'edgeless') => {
|
||||||
const page = createPage();
|
const page = createPage();
|
||||||
@@ -31,9 +34,11 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
|
|||||||
},
|
},
|
||||||
[blockSuiteWorkspace.id, createPage, openPage, setPageMode]
|
[blockSuiteWorkspace.id, createPage, openPage, setPageMode]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createEdgelessAndOpen = useCallback(() => {
|
const createEdgelessAndOpen = useCallback(() => {
|
||||||
return createPageAndOpen('edgeless');
|
return createPageAndOpen('edgeless');
|
||||||
}, [createPageAndOpen]);
|
}, [createPageAndOpen]);
|
||||||
|
|
||||||
const importFileAndOpen = useAsyncCallback(async () => {
|
const importFileAndOpen = useAsyncCallback(async () => {
|
||||||
const { showImportModal } = await import('@blocksuite/blocks');
|
const { showImportModal } = await import('@blocksuite/blocks');
|
||||||
const onSuccess = (pageIds: string[], isWorkspaceFile: boolean) => {
|
const onSuccess = (pageIds: string[], isWorkspaceFile: boolean) => {
|
||||||
@@ -55,6 +60,7 @@ export const usePageHelper = (blockSuiteWorkspace: BlockSuiteWorkspace) => {
|
|||||||
};
|
};
|
||||||
showImportModal({ workspace: blockSuiteWorkspace, onSuccess });
|
showImportModal({ workspace: blockSuiteWorkspace, onSuccess });
|
||||||
}, [blockSuiteWorkspace, openPage, jumpToSubPath]);
|
}, [blockSuiteWorkspace, openPage, jumpToSubPath]);
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return {
|
return {
|
||||||
createPage: createPageAndOpen,
|
createPage: createPageAndOpen,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export const searchInput = style({
|
|||||||
color: 'var(--affine-text-primary-color)',
|
color: 'var(--affine-text-primary-color)',
|
||||||
fontSize: 'var(--affine-font-h-5)',
|
fontSize: 'var(--affine-font-h-5)',
|
||||||
padding: '21px 24px',
|
padding: '21px 24px',
|
||||||
|
marginBottom: '8px',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
borderBottom: '1px solid var(--affine-border-color)',
|
borderBottom: '1px solid var(--affine-border-color)',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
@@ -114,13 +115,6 @@ globalStyle(`${root} [cmdk-group][hidden]`, {
|
|||||||
display: 'none',
|
display: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
globalStyle(
|
|
||||||
`${root} [cmdk-group]:not([hidden]):first-of-type [cmdk-group-heading]`,
|
|
||||||
{
|
|
||||||
paddingTop: 16,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
globalStyle(`${root} [cmdk-list]`, {
|
globalStyle(`${root} [cmdk-list]`, {
|
||||||
maxHeight: 400,
|
maxHeight: 400,
|
||||||
minHeight: 120,
|
minHeight: 120,
|
||||||
@@ -187,3 +181,11 @@ globalStyle(
|
|||||||
color: 'var(--affine-error-color)',
|
color: 'var(--affine-error-color)',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const resultGroupHeader = style({
|
||||||
|
padding: '8px',
|
||||||
|
color: 'var(--affine-text-secondary-color)',
|
||||||
|
fontSize: 'var(--affine-font-xs)',
|
||||||
|
fontWeight: 600,
|
||||||
|
lineHeight: '1.67',
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Command } from '@affine/cmdk';
|
import { Command } from '@affine/cmdk';
|
||||||
|
import { useCommandState } from '@affine/cmdk';
|
||||||
import { formatDate } from '@affine/component/page-list';
|
import { formatDate } from '@affine/component/page-list';
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||||
import type { PageMeta } from '@blocksuite/store';
|
import type { PageMeta } from '@blocksuite/store';
|
||||||
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
|
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
|
||||||
import type { CommandCategory } from '@toeverything/infra/command';
|
import type { CommandCategory } from '@toeverything/infra/command';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
import { Suspense, useLayoutEffect, useMemo, useState } from 'react';
|
import { Suspense, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -71,7 +72,7 @@ const QuickSearchGroup = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Command.Group key={category} heading={t[i18nkey]()}>
|
<Command.Group key={category} heading={query ? '' : t[i18nkey]()}>
|
||||||
{commands.map(command => {
|
{commands.map(command => {
|
||||||
const label =
|
const label =
|
||||||
typeof command.label === 'string'
|
typeof command.label === 'string'
|
||||||
@@ -129,18 +130,43 @@ const QuickSearchCommands = ({
|
|||||||
}: {
|
}: {
|
||||||
onOpenChange?: (open: boolean) => void;
|
onOpenChange?: (open: boolean) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const t = useAFFiNEI18N();
|
||||||
const groups = useCMDKCommandGroups();
|
const groups = useCMDKCommandGroups();
|
||||||
|
|
||||||
return groups.map(([category, commands]) => {
|
const query = useAtomValue(cmdkQueryAtom);
|
||||||
return (
|
const resultCount = useCommandState(state => state.filtered.count);
|
||||||
<QuickSearchGroup
|
const resultGroupHeader = useMemo(() => {
|
||||||
key={category}
|
if (query) {
|
||||||
onOpenChange={onOpenChange}
|
return (
|
||||||
category={category}
|
<div className={styles.resultGroupHeader}>
|
||||||
commands={commands}
|
{
|
||||||
/>
|
// hack: use resultCount to determine if it is creation or results
|
||||||
);
|
// because the creation(as 2 results) is always shown at the top when there is no result
|
||||||
});
|
resultCount === 2
|
||||||
|
? t['com.affine.cmdk.affine.category.affine.creation']()
|
||||||
|
: t['com.affine.cmdk.affine.category.results']()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}, [query, resultCount, t]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{resultGroupHeader}
|
||||||
|
{groups.map(([category, commands]) => {
|
||||||
|
return (
|
||||||
|
<QuickSearchGroup
|
||||||
|
key={category}
|
||||||
|
onOpenChange={onOpenChange}
|
||||||
|
category={category}
|
||||||
|
commands={commands}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CMDKContainer = ({
|
export const CMDKContainer = ({
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
|
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
|
||||||
import {
|
import {
|
||||||
useBlockSuitePageMeta,
|
useBlockSuitePageMeta,
|
||||||
usePageMetaHelper,
|
usePageMetaHelper,
|
||||||
} from '@toeverything/hooks/use-block-suite-page-meta';
|
} from '@toeverything/hooks/use-block-suite-page-meta';
|
||||||
|
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
|
||||||
|
|
||||||
import { setPageModeAtom } from '../../atoms';
|
import { setPageModeAtom } from '../../atoms';
|
||||||
import { currentModeAtom } from '../../atoms/mode';
|
import { currentModeAtom } from '../../atoms/mode';
|
||||||
import type { BlockSuiteWorkspace } from '../../shared';
|
import type { BlockSuiteWorkspace } from '../../shared';
|
||||||
import { getWorkspaceSetting } from '../../utils/workspace-setting';
|
import { getWorkspaceSetting } from '../../utils/workspace-setting';
|
||||||
|
import { useNavigateHelper } from '../use-navigate-helper';
|
||||||
import { useReferenceLinkHelper } from './use-reference-link-helper';
|
import { useReferenceLinkHelper } from './use-reference-link-helper';
|
||||||
|
|
||||||
export function useBlockSuiteMetaHelper(
|
export function useBlockSuiteMetaHelper(
|
||||||
blockSuiteWorkspace: BlockSuiteWorkspace
|
blockSuiteWorkspace: BlockSuiteWorkspace
|
||||||
) {
|
) {
|
||||||
const { setPageMeta, getPageMeta, setPageReadonly } =
|
const { setPageMeta, getPageMeta, setPageReadonly, setPageTitle } =
|
||||||
usePageMetaHelper(blockSuiteWorkspace);
|
usePageMetaHelper(blockSuiteWorkspace);
|
||||||
const { addReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace);
|
const { addReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace);
|
||||||
const metas = useBlockSuitePageMeta(blockSuiteWorkspace);
|
const metas = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||||
const setPageMode = useSetAtom(setPageModeAtom);
|
const setPageMode = useSetAtom(setPageModeAtom);
|
||||||
const currentMode = useAtomValue(currentModeAtom);
|
const currentMode = useAtomValue(currentModeAtom);
|
||||||
|
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
|
||||||
|
const { openPage } = useNavigateHelper();
|
||||||
|
|
||||||
const switchToPageMode = useCallback(
|
const switchToPageMode = useCallback(
|
||||||
(pageId: string) => {
|
(pageId: string) => {
|
||||||
@@ -140,6 +146,40 @@ export function useBlockSuiteMetaHelper(
|
|||||||
[setPageMeta]
|
[setPageMeta]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const duplicate = useAsyncCallback(
|
||||||
|
async (pageId: string) => {
|
||||||
|
const currentPageMeta = getPageMeta(pageId);
|
||||||
|
const newPage = createPage();
|
||||||
|
const currentPage = blockSuiteWorkspace.getPage(pageId);
|
||||||
|
|
||||||
|
await newPage.waitForLoaded();
|
||||||
|
if (!currentPageMeta || !currentPage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = encodeStateAsUpdate(currentPage.spaceDoc);
|
||||||
|
applyUpdate(newPage.spaceDoc, update);
|
||||||
|
|
||||||
|
setPageMeta(newPage.id, {
|
||||||
|
tags: currentPageMeta.tags,
|
||||||
|
favorite: currentPageMeta.favorite,
|
||||||
|
});
|
||||||
|
setPageMode(newPage.id, currentMode);
|
||||||
|
setPageTitle(newPage.id, `${currentPageMeta.title}(1)`);
|
||||||
|
openPage(blockSuiteWorkspace.id, newPage.id);
|
||||||
|
},
|
||||||
|
[
|
||||||
|
blockSuiteWorkspace,
|
||||||
|
createPage,
|
||||||
|
currentMode,
|
||||||
|
getPageMeta,
|
||||||
|
openPage,
|
||||||
|
setPageMeta,
|
||||||
|
setPageMode,
|
||||||
|
setPageTitle,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
switchToPageMode,
|
switchToPageMode,
|
||||||
switchToEdgelessMode,
|
switchToEdgelessMode,
|
||||||
@@ -155,5 +195,7 @@ export function useBlockSuiteMetaHelper(
|
|||||||
removeToTrash,
|
removeToTrash,
|
||||||
restoreFromTrash,
|
restoreFromTrash,
|
||||||
permanentlyDeletePage,
|
permanentlyDeletePage,
|
||||||
|
|
||||||
|
duplicate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function useRegisterBlocksuiteEditorCommands(
|
|||||||
}));
|
}));
|
||||||
}, [pageId, setPageHistoryModalState]);
|
}, [pageId, setPageHistoryModalState]);
|
||||||
|
|
||||||
const { togglePageMode, toggleFavorite, restoreFromTrash } =
|
const { togglePageMode, toggleFavorite, restoreFromTrash, duplicate } =
|
||||||
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
||||||
const exportHandler = useExportPage(currentPage);
|
const exportHandler = useExportPage(currentPage);
|
||||||
const { setTrashModal } = useTrashModalHelper(blockSuiteWorkspace);
|
const { setTrashModal } = useTrashModalHelper(blockSuiteWorkspace);
|
||||||
@@ -125,6 +125,19 @@ export function useRegisterBlocksuiteEditorCommands(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
unsubs.push(
|
||||||
|
registerAffineCommand({
|
||||||
|
id: `editor:${mode}-duplicate`,
|
||||||
|
preconditionStrategy,
|
||||||
|
category: `editor:${mode}`,
|
||||||
|
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
|
||||||
|
label: t['com.affine.header.option.duplicate'](),
|
||||||
|
run() {
|
||||||
|
duplicate(pageId);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
unsubs.push(
|
unsubs.push(
|
||||||
registerAffineCommand({
|
registerAffineCommand({
|
||||||
id: `editor:${mode}-export-to-pdf`,
|
id: `editor:${mode}-export-to-pdf`,
|
||||||
@@ -234,5 +247,6 @@ export function useRegisterBlocksuiteEditorCommands(
|
|||||||
trash,
|
trash,
|
||||||
isCloudWorkspace,
|
isCloudWorkspace,
|
||||||
openHistoryModal,
|
openHistoryModal,
|
||||||
|
duplicate,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,6 +486,7 @@
|
|||||||
"com.affine.cmdk.affine.category.editor.edgeless": "Edgeless Commands",
|
"com.affine.cmdk.affine.category.editor.edgeless": "Edgeless Commands",
|
||||||
"com.affine.cmdk.affine.category.editor.insert-object": "Insert Object",
|
"com.affine.cmdk.affine.category.editor.insert-object": "Insert Object",
|
||||||
"com.affine.cmdk.affine.category.editor.page": "Page Commands",
|
"com.affine.cmdk.affine.category.editor.page": "Page Commands",
|
||||||
|
"com.affine.cmdk.affine.category.results": "Results",
|
||||||
"com.affine.cmdk.affine.client-border-style.to": "Change Client Border Style to",
|
"com.affine.cmdk.affine.client-border-style.to": "Change Client Border Style to",
|
||||||
"com.affine.cmdk.affine.color-mode.to": "Change Colour Mode to",
|
"com.affine.cmdk.affine.color-mode.to": "Change Colour Mode to",
|
||||||
"com.affine.cmdk.affine.color-scheme.to": "Change Colour Scheme to",
|
"com.affine.cmdk.affine.color-scheme.to": "Change Colour Scheme to",
|
||||||
|
|||||||
Reference in New Issue
Block a user