Fix paste of files (#5655)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-05-23 19:43:11 +04:00 committed by GitHub
parent 9cd8b7a001
commit f1791c9e21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 20 deletions

View File

@ -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={[

View File

@ -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<string, string> = {}
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,

View File

@ -244,35 +244,43 @@
dispatch('update', { message: event.detail, attachments: attachments.size })
}
async function pasteAction (evt: ClipboardEvent): Promise<void> {
let t: HTMLElement | null = evt.target as HTMLElement
async function loadFiles (evt: ClipboardEvent): Promise<void> {
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
}
</script>
<div class="no-print" bind:this={refContainer} on:paste={pasteAction}>
<div class="no-print" bind:this={refContainer}>
<input
bind:this={inputFile}
multiple
@ -300,6 +308,8 @@
autofocus={autofocus ? 'end' : false}
loading={loading || progress}
{boundary}
canEmbedFiles={false}
canEmbedImages={false}
extraActions={[
...extraActions,
{
@ -318,6 +328,7 @@
on:blur
on:message={onMessage}
on:update={onUpdate}
onPaste={pasteAction}
{placeholder}
>
<div slot="header">