feat: D1-15 implement drag-and-drop image chain (import+thumbnails+link+insert) with tests

This commit is contained in:
2026-05-30 09:34:41 +02:00
parent 1b37f1fcec
commit 257a06e5d1
12 changed files with 1517 additions and 1065 deletions

View File

@@ -118,6 +118,36 @@ export const MonacoEditor = {
}, 120);
};
this.dropEvent = this.el.dataset.monacoDropEvent || "";
this.dropPostId = this.el.dataset.monacoDropPostId || "";
this.handleDragOver = (event) => {
if (event.dataTransfer && Array.from(event.dataTransfer.types || []).includes("Files")) {
event.preventDefault();
event.dataTransfer.dropEffect = "copy";
}
};
this.handleDrop = (event) => {
if (!this.dropEvent || !event.dataTransfer) {
return;
}
const files = Array.from(event.dataTransfer.files || []);
const images = files.filter((file) => (file.type || "").startsWith("image/") && file.path);
if (images.length === 0) {
return;
}
event.preventDefault();
event.stopPropagation();
images.forEach((file) => {
this.pushEvent(this.dropEvent, { "post-id": this.dropPostId, path: file.path });
});
};
this.handleInsert = ({ id, content }) => {
if (!this.editor || !content || String(id) !== String(this.editorId)) {
return;
@@ -197,6 +227,11 @@ export const MonacoEditor = {
if (this.insertEvent) {
this.handleEvent(this.insertEvent, this.handleInsert);
}
if (this.dropEvent) {
this.el.addEventListener("dragover", this.handleDragOver);
this.el.addEventListener("drop", this.handleDrop);
}
})
.catch((error) => {
console.error("Failed to load Monaco editor", error);
@@ -232,6 +267,12 @@ export const MonacoEditor = {
window.clearTimeout(this.syncTimer);
this.visibleSizeObserver?.disconnect();
this.changeSubscription?.dispose();
if (this.dropEvent) {
this.el.removeEventListener("dragover", this.handleDragOver);
this.el.removeEventListener("drop", this.handleDrop);
}
unregisterMonacoEditor(this.editorId || this.el.id);
this.editor?.dispose();
}