"use client" import { Extension } from "@tiptap/core" import { Plugin, PluginKey } from "@tiptap/pm/state" import { buildInsertGraphicAttrs } from "@/lib/drive/extensions/docs-graphic" function readImageFile(file: File): Promise { return new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = () => resolve(reader.result as string) reader.onerror = reject reader.readAsDataURL(file) }) } export const DocsGraphicPasteDrop = Extension.create({ name: "docsGraphicPasteDrop", addProseMirrorPlugins() { const editor = this.editor return [ new Plugin({ key: new PluginKey("docsGraphicPasteDrop"), props: { handlePaste(view, event) { const items = event.clipboardData?.items if (!items) return false for (const item of items) { if (!item.type.startsWith("image/")) continue const file = item.getAsFile() if (!file) continue event.preventDefault() void readImageFile(file).then((src) => { editor .chain() .focus() .insertDocsGraphic( buildInsertGraphicAttrs("image", { src, width: 280, height: 180 }) ) .run() }) return true } return false }, handleDrop(view, event) { const files = event.dataTransfer?.files if (!files?.length) return false const file = [...files].find((f) => f.type.startsWith("image/")) if (!file) return false event.preventDefault() void readImageFile(file).then((src) => { const coords = view.posAtCoords({ left: event.clientX, top: event.clientY, }) const chain = editor.chain().focus() if (coords?.pos != null) chain.setTextSelection(coords.pos) chain .insertDocsGraphic( buildInsertGraphicAttrs("image", { src, width: 280, height: 180 }) ) .run() }) return true }, }, }), ] }, })