From f1791c9e21fe6eec9c67ded66c55e194f4b5da02 Mon Sep 17 00:00:00 2001 From: Kristina Date: Thu, 23 May 2024 19:43:11 +0400 Subject: [PATCH] Fix paste of files (#5655) Signed-off-by: Kristina Fefelova --- .../src/components/ReferenceInput.svelte | 7 +++ .../src/components/TextEditor.svelte | 14 +++++- .../src/components/AttachmentRefInput.svelte | 47 ++++++++++++------- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/packages/text-editor/src/components/ReferenceInput.svelte b/packages/text-editor/src/components/ReferenceInput.svelte index 5904b418ad..8f8bee4711 100644 --- a/packages/text-editor/src/components/ReferenceInput.svelte +++ b/packages/text-editor/src/components/ReferenceInput.svelte @@ -37,6 +37,7 @@ import { EmojiExtension } from './extension/emoji' import { IsEmptyContentExtension } from './extension/isEmptyContent' import Send from './icons/Send.svelte' + import { EditorView } from '@tiptap/pm/view' export let content: Markup = EmptyMarkup export let showHeader = false @@ -52,6 +53,9 @@ export let focusable: boolean = false export let boundary: HTMLElement | undefined = undefined export let autofocus: FocusPosition = false + export let canEmbedFiles = true + export let canEmbedImages = true + export let onPaste: ((view: EditorView, event: ClipboardEvent) => boolean) | undefined = undefined const dispatch = createEventDispatcher() const buttonSize = 'medium' @@ -151,6 +155,8 @@ bind:this={textEditor} {autofocus} {boundary} + {canEmbedFiles} + {canEmbedImages} on:content={(ev) => { if (canSubmit) { dispatch('message', ev.detail) @@ -172,6 +178,7 @@ EmojiExtension.configure(), IsEmptyContentExtension.configure({ onChange: (value) => (isEmpty = value) }) ]} + {onPaste} on:update placeholder={placeholder ?? textEditorPlugin.string.EditorPlaceholder} textFormatCategories={[ diff --git a/packages/text-editor/src/components/TextEditor.svelte b/packages/text-editor/src/components/TextEditor.svelte index 9678b0990d..8be0d12641 100644 --- a/packages/text-editor/src/components/TextEditor.svelte +++ b/packages/text-editor/src/components/TextEditor.svelte @@ -35,6 +35,7 @@ import { InlineStyleToolbarExtension } from './extension/inlineStyleToolbar' import { SubmitExtension } from './extension/submit' import { EditorKit } from '../kits/editor-kit' + import { EditorView } from '@tiptap/pm/view' export let content: Markup = EmptyMarkup export let placeholder: IntlString = textEditorPlugin.string.EditorPlaceholder @@ -44,6 +45,9 @@ export let editorAttributes: Record = {} export let boundary: HTMLElement | undefined = undefined export let autofocus: FocusPosition = false + export let canEmbedFiles = true + export let canEmbedImages = true + export let onPaste: ((view: EditorView, event: ClipboardEvent) => boolean) | undefined = undefined let element: HTMLElement let editor: Editor @@ -163,11 +167,17 @@ void ph.then(() => { editor = new Editor({ element, - editorProps: { attributes: mergeAttributes(defaultEditorAttributes, editorAttributes) }, + editorProps: { + attributes: mergeAttributes(defaultEditorAttributes, editorAttributes), + handlePaste: onPaste + }, content: markupToJSON(content), autofocus, extensions: [ - EditorKit, + EditorKit.configure({ + file: canEmbedFiles ? {} : false, + image: canEmbedImages ? {} : false + }), ...(supportSubmit ? [Handle] : []), // order important Placeholder.configure({ placeholder: placeHolderStr }), ...extensions, diff --git a/plugins/attachment-resources/src/components/AttachmentRefInput.svelte b/plugins/attachment-resources/src/components/AttachmentRefInput.svelte index 87deea9770..aa22278a57 100644 --- a/plugins/attachment-resources/src/components/AttachmentRefInput.svelte +++ b/plugins/attachment-resources/src/components/AttachmentRefInput.svelte @@ -244,35 +244,43 @@ dispatch('update', { message: event.detail, attachments: attachments.size }) } - async function pasteAction (evt: ClipboardEvent): Promise { - let t: HTMLElement | null = evt.target as HTMLElement + async function loadFiles (evt: ClipboardEvent): Promise { + progress = true + const files = (evt.clipboardData?.files ?? []) as File[] + + for (const file of files) { + await createAttachment(file) + } + + progress = false + } + + function pasteAction (_: any, evt: ClipboardEvent): boolean { + let target: HTMLElement | null = evt.target as HTMLElement let allowed = false - while (t != null) { - t = t.parentElement - if (t === refContainer) { + + while (target != null) { + target = target.parentElement + if (target === refContainer) { allowed = true } } if (!allowed) { - return + return false } - const items = evt.clipboardData?.items ?? [] - progress = true - for (const index in items) { - const item = items[index] - if (item.kind === 'file') { - const blob = item.getAsFile() - if (blob !== null) { - await createAttachment(blob) - } - } + const hasFiles = Array.from(evt.clipboardData?.items ?? []).some((i) => i.kind === 'file') + + if (!hasFiles) { + return false } - progress = false + + void loadFiles(evt) + return true } -
+