fix: insert link action in quick search callback (#7165)

This commit is contained in:
pengx17 2024-06-07 04:39:19 +00:00
parent f20b78b824
commit e6ec506226
No known key found for this signature in database
GPG Key ID: 23F23D9E8B3971ED
12 changed files with 126 additions and 65 deletions

View File

@ -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 = (

View File

@ -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);

View File

@ -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'),

View File

@ -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>;
});

View File

@ -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>
);
};

View File

@ -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({

View File

@ -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();

View File

@ -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;

View File

@ -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",

View File

@ -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",

View File

@ -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": "프리젠테이션 시작",

View File

@ -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": "Начать презентацию",