diff --git a/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor-container.tsx b/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor-container.tsx index da4d446096..a009ea779f 100644 --- a/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor-container.tsx +++ b/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor-container.tsx @@ -25,14 +25,13 @@ import type { DefaultOpenProperty } from '../../components/doc-properties'; import { BlocksuiteDocEditor, BlocksuiteEdgelessEditor } from './lit-adaper'; import * as styles from './styles.css'; -interface BlocksuiteEditorContainerProps { +interface BlocksuiteEditorContainerProps + extends React.HTMLAttributes { page: Store; mode: DocMode; shared?: boolean; readonly?: boolean; - className?: string; defaultOpenProperty?: DefaultOpenProperty; - style?: React.CSSProperties; } export interface AffineEditorContainer extends HTMLElement { @@ -51,7 +50,7 @@ export const BlocksuiteEditorContainer = forwardRef< AffineEditorContainer, BlocksuiteEditorContainerProps >(function AffineEditorContainer( - { page, mode, className, style, shared, readonly, defaultOpenProperty }, + { page, mode, shared, readonly, defaultOpenProperty, ...props }, ref ) { const rootRef = useRef(null); @@ -159,15 +158,16 @@ export const BlocksuiteEditorContainer = forwardRef< return (
{mode === 'page' ? ( diff --git a/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor.tsx b/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor.tsx index 34ee1acc1c..6b53c52133 100644 --- a/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor.tsx +++ b/packages/frontend/core/src/blocksuite/block-suite-editor/blocksuite-editor.tsx @@ -16,8 +16,8 @@ import type { Store } from '@blocksuite/affine/store'; import { Slot } from '@radix-ui/react-slot'; import { useLiveData, useService } from '@toeverything/infra'; import { cssVar } from '@toeverything/theme'; -import type { CSSProperties } from 'react'; -import { useEffect, useMemo, useState } from 'react'; +import type { CSSProperties, HTMLAttributes } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import type { DefaultOpenProperty } from '../../components/doc-properties'; import { @@ -26,7 +26,7 @@ import { } from './blocksuite-editor-container'; import { NoPageRootError } from './no-page-error'; -export type EditorProps = { +export interface EditorProps extends HTMLAttributes { page: Store; mode: DocMode; shared?: boolean; @@ -34,9 +34,7 @@ export type EditorProps = { defaultOpenProperty?: DefaultOpenProperty; // on Editor ready onEditorReady?: (editor: AffineEditorContainer) => (() => void) | void; - style?: CSSProperties; - className?: string; -}; +} const BlockSuiteEditorImpl = ({ mode, @@ -47,6 +45,7 @@ const BlockSuiteEditorImpl = ({ style, onEditorReady, defaultOpenProperty, + ...props }: EditorProps) => { useEffect(() => { const disposable = page.slots.blockUpdated.subscribe(() => { @@ -111,6 +110,7 @@ const BlockSuiteEditorImpl = ({ return ( { fontFamily: s.fontFamily, customFontFamily: s.customFontFamily, fullWidthLayout: s.fullWidthLayout, + disableMiddleClickPaste: s.disableMiddleClickPaste, })) ); const fontFamily = useMemo(() => { @@ -169,12 +170,24 @@ export const BlockSuiteEditor = (props: EditorProps) => { }; }, [props.page]); + const handleMouseDown = useCallback( + (e: React.MouseEvent) => { + if (settings.disableMiddleClickPaste && e.button === 1) { + e.preventDefault(); + } + }, + [settings.disableMiddleClickPaste] + ); + if (error) { throw error; } return ( - + {isLoading ? ( ) : ( diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx index 7f3d0c5efa..85e6537bb3 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx @@ -487,6 +487,36 @@ const SpellCheckSettings = () => { ); }; +const MiddleClickPasteSettings = () => { + const t = useI18n(); + const editorSettingService = useService(EditorSettingService); + const settings = useLiveData(editorSettingService.editorSetting.settings$); + const onToggleMiddleClickPaste = useCallback( + (checked: boolean) => { + editorSettingService.editorSetting.set( + 'disableMiddleClickPaste', + checked + ); + }, + [editorSettingService.editorSetting] + ); + return ( + + + + ); +}; + export const General = () => { const t = useI18n(); @@ -497,6 +527,7 @@ export const General = () => { {BUILD_CONFIG.isElectron && } + {environment.isLinux && } {/* // TODO(@akumatus): implement these settings */} diff --git a/packages/frontend/core/src/modules/editor-setting/schema.ts b/packages/frontend/core/src/modules/editor-setting/schema.ts index 4ff375c53a..4bbb4f5e18 100644 --- a/packages/frontend/core/src/modules/editor-setting/schema.ts +++ b/packages/frontend/core/src/modules/editor-setting/schema.ts @@ -34,6 +34,8 @@ const AffineEditorSettingSchema = z.object({ 'open-in-center-peek', ]) .default('open-in-active-view'), + // linux only: + disableMiddleClickPaste: z.boolean().default(false), }); export const EditorSettingSchema = BSEditorSettingSchema.merge( diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts index c05b581d25..97e48a5224 100644 --- a/packages/frontend/i18n/src/i18n.gen.ts +++ b/packages/frontend/i18n/src/i18n.gen.ts @@ -5167,6 +5167,14 @@ export function useAFFiNEI18N(): { * `Page` */ ["com.affine.settings.editorSettings.page"](): string; + /** + * `Middle click paste` + */ + ["com.affine.settings.editorSettings.general.middle-click-paste.title"](): string; + /** + * `Disable default middle click paste behavior on Linux.` + */ + ["com.affine.settings.editorSettings.general.middle-click-paste.description"](): string; /** * `Display bi-directional links on the doc.` */ diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index df21a8f824..fe8bc9a396 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1287,6 +1287,8 @@ "com.affine.settings.editorSettings.general.spell-check.title": "Spell check", "com.affine.settings.editorSettings.general.spell-check.restart-hint": "Settings changed; please restart the app. <1>Restart", "com.affine.settings.editorSettings.page": "Page", + "com.affine.settings.editorSettings.general.middle-click-paste.title": "Middle click paste", + "com.affine.settings.editorSettings.general.middle-click-paste.description": "Disable default middle click paste behavior on Linux.", "com.affine.settings.editorSettings.page.display-bi-link.description": "Display bi-directional links on the doc.", "com.affine.settings.editorSettings.page.display-bi-link.title": "Display bi-directional links", "com.affine.settings.editorSettings.page.display-doc-info.description": "Display document information on the doc.",