mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-11 22:18:54 +08:00
fix(editor): should check text length and stop event propagation when adding a link (#10391)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import type { EditorHost } from '@blocksuite/block-std';
|
import { type EditorHost, TextSelection } from '@blocksuite/block-std';
|
||||||
import type { TemplateResult } from 'lit';
|
import type { TemplateResult } from 'lit';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -26,6 +26,7 @@ export interface TextFormatConfig {
|
|||||||
hotkey?: string;
|
hotkey?: string;
|
||||||
activeWhen: (host: EditorHost) => boolean;
|
activeWhen: (host: EditorHost) => boolean;
|
||||||
action: (host: EditorHost) => void;
|
action: (host: EditorHost) => void;
|
||||||
|
textChecker?: (host: EditorHost) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const textFormatConfigs: TextFormatConfig[] = [
|
export const textFormatConfigs: TextFormatConfig[] = [
|
||||||
@@ -124,5 +125,14 @@ export const textFormatConfigs: TextFormatConfig[] = [
|
|||||||
action: host => {
|
action: host => {
|
||||||
host.std.command.chain().pipe(toggleLink).run();
|
host.std.command.chain().pipe(toggleLink).run();
|
||||||
},
|
},
|
||||||
|
// should check text length
|
||||||
|
textChecker: host => {
|
||||||
|
const textSelection = host.std.selection.find(TextSelection);
|
||||||
|
if (!textSelection || textSelection.isCollapsed()) return false;
|
||||||
|
|
||||||
|
return Boolean(
|
||||||
|
textSelection.from.length + (textSelection.to?.length ?? 0)
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -20,8 +20,14 @@ export const textFormatKeymap = (std: BlockStdScope) =>
|
|||||||
const textSelection = selection.find(TextSelection);
|
const textSelection = selection.find(TextSelection);
|
||||||
if (!textSelection) return;
|
if (!textSelection) return;
|
||||||
|
|
||||||
|
const allowed = config.textChecker?.(std.host) ?? true;
|
||||||
|
if (!allowed) return;
|
||||||
|
|
||||||
|
const event = ctx.get('keyboardState').raw;
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
config.action(std.host);
|
config.action(std.host);
|
||||||
ctx.get('keyboardState').raw.preventDefault();
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,13 +8,11 @@ import { I18nService } from '@affine/core/modules/i18n';
|
|||||||
import { UrlService } from '@affine/core/modules/url';
|
import { UrlService } from '@affine/core/modules/url';
|
||||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { TextSelection } from '@blocksuite/affine/block-std';
|
|
||||||
import { useService, useServiceOptional } from '@toeverything/infra';
|
import { useService, useServiceOptional } from '@toeverything/infra';
|
||||||
import { useStore } from 'jotai';
|
import { useStore } from 'jotai';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import type { AffineEditorContainer } from '../../blocksuite/block-suite-editor';
|
|
||||||
import { usePageHelper } from '../../blocksuite/block-suite-page-list/utils';
|
import { usePageHelper } from '../../blocksuite/block-suite-page-list/utils';
|
||||||
import {
|
import {
|
||||||
PreconditionStrategy,
|
PreconditionStrategy,
|
||||||
@@ -29,40 +27,19 @@ import {
|
|||||||
} from '../../commands';
|
} from '../../commands';
|
||||||
import { EditorSettingService } from '../../modules/editor-setting';
|
import { EditorSettingService } from '../../modules/editor-setting';
|
||||||
import { CMDKQuickSearchService } from '../../modules/quicksearch/services/cmdk';
|
import { CMDKQuickSearchService } from '../../modules/quicksearch/services/cmdk';
|
||||||
import { useActiveBlocksuiteEditor } from './use-block-suite-editor';
|
|
||||||
import { useNavigateHelper } from './use-navigate-helper';
|
import { useNavigateHelper } from './use-navigate-helper';
|
||||||
|
|
||||||
function hasLinkPopover(editor: AffineEditorContainer | null) {
|
function registerCMDKCommand(service: CMDKQuickSearchService) {
|
||||||
const textSelection = editor?.host?.std.selection.find(TextSelection);
|
|
||||||
if (editor && textSelection && textSelection.from.length > 0) {
|
|
||||||
const formatBar = editor.host?.querySelector('affine-format-bar-widget');
|
|
||||||
if (formatBar) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerCMDKCommand(
|
|
||||||
service: CMDKQuickSearchService,
|
|
||||||
editor: AffineEditorContainer | null
|
|
||||||
) {
|
|
||||||
return registerAffineCommand({
|
return registerAffineCommand({
|
||||||
id: 'affine:show-quick-search',
|
id: 'affine:show-quick-search',
|
||||||
preconditionStrategy: PreconditionStrategy.Never,
|
preconditionStrategy: PreconditionStrategy.Never,
|
||||||
category: 'affine:general',
|
category: 'affine:general',
|
||||||
keyBinding: {
|
keyBinding: {
|
||||||
binding: '$mod+K',
|
binding: '$mod+K',
|
||||||
capture: true,
|
|
||||||
},
|
},
|
||||||
label: '',
|
label: '',
|
||||||
icon: '',
|
icon: '',
|
||||||
run() {
|
run() {
|
||||||
// Due to a conflict with the shortcut for creating a link after selecting text in blocksuite,
|
|
||||||
// opening the quick search modal is disabled when link-popup is visitable.
|
|
||||||
if (hasLinkPopover(editor)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
service.toggle();
|
service.toggle();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -76,7 +53,6 @@ export function useRegisterWorkspaceCommands() {
|
|||||||
const urlService = useService(UrlService);
|
const urlService = useService(UrlService);
|
||||||
const pageHelper = usePageHelper(currentWorkspace.docCollection);
|
const pageHelper = usePageHelper(currentWorkspace.docCollection);
|
||||||
const navigationHelper = useNavigateHelper();
|
const navigationHelper = useNavigateHelper();
|
||||||
const [editor] = useActiveBlocksuiteEditor();
|
|
||||||
const cmdkQuickSearchService = useService(CMDKQuickSearchService);
|
const cmdkQuickSearchService = useService(CMDKQuickSearchService);
|
||||||
const editorSettingService = useService(EditorSettingService);
|
const editorSettingService = useService(EditorSettingService);
|
||||||
const workspaceDialogService = useService(WorkspaceDialogService);
|
const workspaceDialogService = useService(WorkspaceDialogService);
|
||||||
@@ -88,12 +64,12 @@ export function useRegisterWorkspaceCommands() {
|
|||||||
useServiceOptional(DesktopApiService)?.handler.updater.quitAndInstall;
|
useServiceOptional(DesktopApiService)?.handler.updater.quitAndInstall;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsub = registerCMDKCommand(cmdkQuickSearchService, editor);
|
const unsub = registerCMDKCommand(cmdkQuickSearchService);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsub();
|
unsub();
|
||||||
};
|
};
|
||||||
}, [cmdkQuickSearchService, editor]);
|
}, [cmdkQuickSearchService]);
|
||||||
|
|
||||||
// register AffineUpdatesCommands
|
// register AffineUpdatesCommands
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user