mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 16:32:04 +03:00
fix: insert link action in quick search callback (#7165)
This commit is contained in:
parent
f20b78b824
commit
e6ec506226
@ -16,9 +16,11 @@ import { CollectionService } from '@affine/core/modules/collection';
|
||||
import { WorkspaceSubPath } from '@affine/core/shared';
|
||||
import { mixpanel } from '@affine/core/utils';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
EdgelessIcon,
|
||||
LinkIcon,
|
||||
PageIcon,
|
||||
TodayIcon,
|
||||
ViewLayersIcon,
|
||||
@ -36,6 +38,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { usePageHelper } from '../../../components/blocksuite/block-suite-page-list/utils';
|
||||
import { useNavigateHelper } from '../../../hooks/use-navigate-helper';
|
||||
import { filterSortAndGroupCommands } from './filter-commands';
|
||||
import * as hlStyles from './highlight.css';
|
||||
import type { CMDKCommand, CommandContext } from './types';
|
||||
|
||||
export const cmdkValueAtom = atom('');
|
||||
@ -254,9 +257,17 @@ export const usePageCommands = () => {
|
||||
|
||||
results.push({
|
||||
id: 'affine:pages:create-page',
|
||||
label: t['com.affine.cmdk.affine.create-new-page-as']({
|
||||
keyWord: query,
|
||||
}),
|
||||
label: (
|
||||
<Trans
|
||||
i18nKey="com.affine.cmdk.affine.create-new-page-as"
|
||||
values={{
|
||||
keyWord: query,
|
||||
}}
|
||||
components={{
|
||||
1: <span className={hlStyles.highlightKeyword} />,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
alwaysShow: true,
|
||||
category: 'affine:creation',
|
||||
run: async () => {
|
||||
@ -273,9 +284,17 @@ export const usePageCommands = () => {
|
||||
|
||||
results.push({
|
||||
id: 'affine:pages:create-edgeless',
|
||||
label: t['com.affine.cmdk.affine.create-new-edgeless-as']({
|
||||
keyWord: query,
|
||||
}),
|
||||
label: (
|
||||
<Trans
|
||||
i18nKey="com.affine.cmdk.affine.create-new-edgeless-as"
|
||||
values={{
|
||||
keyWord: query,
|
||||
}}
|
||||
components={{
|
||||
1: <span className={hlStyles.highlightKeyword} />,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
alwaysShow: true,
|
||||
category: 'affine:creation',
|
||||
run: async () => {
|
||||
@ -309,7 +328,6 @@ export const useSearchCallbackCommands = () => {
|
||||
const pageHelper = usePageHelper(workspace.docCollection);
|
||||
const pageMetaHelper = useDocMetaHelper(workspace.docCollection);
|
||||
const query = useLiveData(quickSearch.query$);
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const onSelectPage = useCallback(
|
||||
(searchResult: SearchCallbackResult) => {
|
||||
@ -332,35 +350,52 @@ export const useSearchCallbackCommands = () => {
|
||||
results.every(command => command.originalValue !== query) &&
|
||||
query.trim()
|
||||
) {
|
||||
results.push({
|
||||
id: 'affine:pages:create-page',
|
||||
label: t['com.affine.cmdk.affine.create-new-doc-and-insert']({
|
||||
keyWord: query,
|
||||
}),
|
||||
alwaysShow: true,
|
||||
category: 'affine:creation',
|
||||
run: async () => {
|
||||
const page = pageHelper.createPage('page', false);
|
||||
page.load();
|
||||
pageMetaHelper.setDocTitle(page.id, query);
|
||||
mixpanel.track('DocCreated', {
|
||||
control: 'cmdk',
|
||||
type: 'doc',
|
||||
});
|
||||
onSelectPage({ docId: page.id });
|
||||
},
|
||||
icon: <PageIcon />,
|
||||
});
|
||||
if (query.startsWith('http://') || query.startsWith('https://')) {
|
||||
results.push({
|
||||
id: 'affine:pages:create-page',
|
||||
label: <Trans i18nKey="com.affine.cmdk.affine.insert-link" />,
|
||||
alwaysShow: true,
|
||||
category: 'affine:creation',
|
||||
run: async () => {
|
||||
onSelectPage({
|
||||
query,
|
||||
action: 'insert',
|
||||
});
|
||||
},
|
||||
icon: <LinkIcon />,
|
||||
});
|
||||
} else {
|
||||
results.push({
|
||||
id: 'affine:pages:create-page',
|
||||
label: (
|
||||
<Trans
|
||||
i18nKey="com.affine.cmdk.affine.create-new-doc-and-insert"
|
||||
values={{
|
||||
keyWord: query,
|
||||
}}
|
||||
components={{
|
||||
1: <span className={hlStyles.highlightKeyword} />,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
alwaysShow: true,
|
||||
category: 'affine:creation',
|
||||
run: async () => {
|
||||
const page = pageHelper.createPage('page', false);
|
||||
page.load();
|
||||
pageMetaHelper.setDocTitle(page.id, query);
|
||||
mixpanel.track('DocCreated', {
|
||||
control: 'cmdk',
|
||||
type: 'doc',
|
||||
});
|
||||
onSelectPage({ docId: page.id });
|
||||
},
|
||||
icon: <PageIcon />,
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}, [
|
||||
searchedDocsCommands,
|
||||
query,
|
||||
t,
|
||||
pageHelper,
|
||||
pageMetaHelper,
|
||||
onSelectPage,
|
||||
]);
|
||||
}, [searchedDocsCommands, query, pageHelper, pageMetaHelper, onSelectPage]);
|
||||
};
|
||||
|
||||
export const collectionToCommand = (
|
||||
|
@ -74,12 +74,22 @@ export const getCommandScore = (command: CMDKCommand, search: string) => {
|
||||
if (search.trim() === '') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const label = command.label;
|
||||
|
||||
const title =
|
||||
(typeof command?.label === 'string'
|
||||
? command.label
|
||||
: command?.label.title) || '';
|
||||
label && typeof label === 'object' && 'title' in label
|
||||
? label.title
|
||||
: typeof label === 'string'
|
||||
? label
|
||||
: '';
|
||||
|
||||
const subTitle =
|
||||
(typeof command?.label === 'string' ? '' : command?.label.subTitle) || '';
|
||||
label && typeof label === 'object' && 'title' in label
|
||||
? label.subTitle ?? ''
|
||||
: typeof label === 'string'
|
||||
? label
|
||||
: '';
|
||||
|
||||
const catWeight = getCategoryWeight(command.category);
|
||||
|
||||
|
@ -10,16 +10,22 @@ export const highlightText = style({
|
||||
textOverflow: 'ellipsis',
|
||||
});
|
||||
export const highlightKeyword = style({
|
||||
display: 'inline-block',
|
||||
verticalAlign: 'bottom',
|
||||
color: cssVar('primaryColor'),
|
||||
whiteSpace: 'pre',
|
||||
overflow: 'visible',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
flexShrink: 0,
|
||||
maxWidth: '360px',
|
||||
});
|
||||
export const labelTitle = style({
|
||||
fontSize: cssVar('fontBase'),
|
||||
lineHeight: '24px',
|
||||
fontWeight: 400,
|
||||
textAlign: 'justify',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
});
|
||||
export const labelContent = style({
|
||||
fontSize: cssVar('fontXs'),
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { memo } from 'react';
|
||||
import { memo, type ReactNode } from 'react';
|
||||
|
||||
import * as styles from './highlight.css';
|
||||
import { useHighlight } from './use-highlight';
|
||||
@ -14,7 +14,7 @@ type HighlightProps = {
|
||||
};
|
||||
|
||||
type HighlightLabelProps = {
|
||||
label: SearchResultLabel;
|
||||
label: SearchResultLabel | ReactNode;
|
||||
highlight: string;
|
||||
};
|
||||
|
||||
@ -44,16 +44,20 @@ export const HighlightLabel = memo(function HighlightLabel({
|
||||
label,
|
||||
highlight,
|
||||
}: HighlightLabelProps) {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.labelTitle}>
|
||||
<Highlight text={label.title} highlight={highlight} />
|
||||
</div>
|
||||
{label.subTitle ? (
|
||||
<div className={styles.labelContent}>
|
||||
<Highlight text={label.subTitle} highlight={highlight} />
|
||||
if (label && typeof label === 'object' && 'title' in label) {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.labelTitle}>
|
||||
<Highlight text={label.title} highlight={highlight} />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
{label.subTitle ? (
|
||||
<div className={styles.labelContent}>
|
||||
<Highlight text={label.subTitle} highlight={highlight} />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className={styles.labelTitle}>{label}</div>;
|
||||
});
|
||||
|
@ -174,6 +174,8 @@ export const CMDKContainer = ({
|
||||
const [opening, setOpening] = useState(open);
|
||||
const { syncing, progress } = useDocEngineStatus();
|
||||
const showLoading = useDebouncedValue(syncing, 500);
|
||||
const quickSearch = useService(QuickSearchService).quickSearch;
|
||||
const mode = useLiveData(quickSearch.mode$);
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@ -235,7 +237,7 @@ export const CMDKContainer = ({
|
||||
<Command.List data-opening={opening ? true : undefined}>
|
||||
{children}
|
||||
</Command.List>
|
||||
<NotFoundGroup />
|
||||
{mode === 'commands' ? <NotFoundGroup /> : null}
|
||||
</Command>
|
||||
);
|
||||
};
|
||||
|
@ -25,7 +25,10 @@ export const notFoundTitle = style({
|
||||
color: cssVar('textSecondaryColor'),
|
||||
fontWeight: '600',
|
||||
lineHeight: '20px',
|
||||
textAlign: 'justify',
|
||||
whiteSpace: 'nowrap',
|
||||
wordBreak: 'break-word',
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
padding: '8px',
|
||||
});
|
||||
export const notFoundText = style({
|
||||
|
@ -9,10 +9,8 @@ import * as styles from './not-found.css';
|
||||
export const NotFoundGroup = () => {
|
||||
const quickSearch = useService(QuickSearchService).quickSearch;
|
||||
const query = useLiveData(quickSearch.query$);
|
||||
const mode = useLiveData(quickSearch.mode$);
|
||||
// hack: we know that the filtered count is 3 when there is no result (create page & edgeless & append to journal, for mode === 'cmdk')
|
||||
const renderNoResult =
|
||||
useCommandState(state => state.filtered.count === 3) && mode === 'commands';
|
||||
const renderNoResult = useCommandState(state => state.filtered.count === 3);
|
||||
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { CommandCategory } from '@affine/core/commands';
|
||||
import type { DocMode } from '@toeverything/infra';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export interface CommandContext {
|
||||
docMode: DocMode | undefined;
|
||||
@ -11,6 +12,7 @@ export interface CommandContext {
|
||||
export interface CMDKCommand {
|
||||
id: string;
|
||||
label:
|
||||
| ReactNode
|
||||
| string
|
||||
| {
|
||||
title: string;
|
||||
|
@ -553,9 +553,10 @@
|
||||
"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.contact-us": "Contact Us",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "New \"{{keyWord}}\" Edgeless",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "New \"{{keyWord}}\" Page",
|
||||
"com.affine.cmdk.affine.create-new-doc-and-insert": "Create \"{{keyWord}}\" Doc and insert",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "New \"<1>{{keyWord}}</1>\" Edgeless",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "New \"<1>{{keyWord}}</1>\" Page",
|
||||
"com.affine.cmdk.affine.create-new-doc-and-insert": "Create \"<1>{{keyWord}}</1>\" Doc and insert",
|
||||
"com.affine.cmdk.affine.insert-link": "Insert this link to the current doc",
|
||||
"com.affine.cmdk.affine.display-language.to": "Change Display Language to",
|
||||
"com.affine.cmdk.affine.editor.add-to-favourites": "Add to Favourites",
|
||||
"com.affine.cmdk.affine.editor.edgeless.presentation-start": "Start Presentation",
|
||||
|
@ -547,7 +547,7 @@
|
||||
"com.affine.cmdk.affine.color-scheme.to": "Changer le thème de couleur pour",
|
||||
"com.affine.cmdk.affine.contact-us": "Nous contacter",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "Créer une nouvelle page sans bord sous :",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "Nouveau document \"{{keyWord}}\" ",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "Nouveau document \"<1>{{keyWord}}</1>\" ",
|
||||
"com.affine.cmdk.affine.display-language.to": "Changer la langue d'affichage pour",
|
||||
"com.affine.cmdk.affine.editor.add-to-favourites": "Ajouter aux Favoris",
|
||||
"com.affine.cmdk.affine.editor.edgeless.presentation-start": "Commencer la Présentation",
|
||||
|
@ -518,8 +518,8 @@
|
||||
"com.affine.cmdk.affine.color-mode.to": "색상 모드를 다음과 같이 변경",
|
||||
"com.affine.cmdk.affine.color-scheme.to": "색 구성표를 다음과 같이 변경",
|
||||
"com.affine.cmdk.affine.contact-us": "Contact Us",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "새 \"{{keyWord}}\" Edgeless",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "새 \"{{keyWord}}\" 페이지",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "새 \"<1>{{keyWord}}</1>\" Edgeless",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "새 \"<1>{{keyWord}}</1>\" 페이지",
|
||||
"com.affine.cmdk.affine.display-language.to": "표시 언어를 다음과 같이 변경",
|
||||
"com.affine.cmdk.affine.editor.add-to-favourites": "즐겨찾기에 추가",
|
||||
"com.affine.cmdk.affine.editor.edgeless.presentation-start": "프리젠테이션 시작",
|
||||
|
@ -549,8 +549,8 @@
|
||||
"com.affine.cmdk.affine.color-mode.to": "Изменить тему на",
|
||||
"com.affine.cmdk.affine.color-scheme.to": "Изменить цветовую схему на",
|
||||
"com.affine.cmdk.affine.contact-us": "Связаться с нами",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "Новый Холст \"{{keyWord}}\"\n",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "Новый документ \"{{keyWord}}\"",
|
||||
"com.affine.cmdk.affine.create-new-edgeless-as": "Новый Холст \"<1>{{keyWord}}</1>\"\n",
|
||||
"com.affine.cmdk.affine.create-new-page-as": "Новый документ \"<1>{{keyWord}}</1>\"",
|
||||
"com.affine.cmdk.affine.display-language.to": "Изменить язык интерфейса на",
|
||||
"com.affine.cmdk.affine.editor.add-to-favourites": "Добавить в Избранное",
|
||||
"com.affine.cmdk.affine.editor.edgeless.presentation-start": "Начать презентацию",
|
||||
|
Loading…
Reference in New Issue
Block a user