Image from clipboard also in replies

This commit is contained in:
2026-06-29 00:16:58 +02:00
parent aa0def2949
commit e4389de288
4 changed files with 40 additions and 27 deletions
+1
View File
@@ -26,6 +26,7 @@
<section id="reply-box" hidden> <section id="reply-box" hidden>
<form id="reply-form"> <form id="reply-form">
<textarea name="content" rows="3" maxlength="1000" placeholder="Antworten…"></textarea> <textarea name="content" rows="3" maxlength="1000" placeholder="Antworten…"></textarea>
<p class="muted" id="reply-paste-msg"></p>
<input name="file" type="file" accept="image/*"> <input name="file" type="file" accept="image/*">
<button type="submit">Antworten</button> <button type="submit">Antworten</button>
</form> </form>
+4 -26
View File
@@ -97,32 +97,10 @@ document.getElementById("entry-form").addEventListener("submit", async (e) => {
}); });
// --- Bild aus der Zwischenablage einfügen --- // --- Bild aus der Zwischenablage einfügen ---
// Strg+V im Textfeld: liegt ein Bild in der Zwischenablage, übernehmen wir es in setupClipboardPaste(
// den File-Input (über DataTransfer, weil sich .files nicht direkt setzen lässt). document.getElementById("entry-form"),
// Liegt kein Bild vor (Text o. Ä.), tun wir nichts und lassen den normalen Paste document.getElementById("paste-msg")
// durchlaufen -> preventDefault nur, wenn wir wirklich ein Bild gegriffen haben. );
document.getElementById("entry-form").addEventListener("paste", (e) => {
const item = [...(e.clipboardData?.items ?? [])].find(
(it) => it.kind === "file" && it.type.startsWith("image/")
);
if (!item) return;
const original = item.getAsFile();
if (!original) return;
e.preventDefault();
// Browser benennt Clipboard-Bilder uneinheitlich ("grafik.png" o. Ä.) -> neu
// verpacken mit sprechendem Namen. Endung aus dem MIME-Typ, sonst png.
const ext = (original.type.split("/")[1] || "png").toLowerCase();
const file = new File([original], `zwischenablage.${ext}`, { type: original.type });
const input = document.querySelector("#entry-form input[name='file']");
const dt = new DataTransfer();
dt.items.add(file);
input.files = dt.files;
document.getElementById("paste-msg").textContent = "Bild aus Zwischenablage übernommen.";
});
// --- Statuszeile unter dem Titel --- // --- Statuszeile unter dem Titel ---
// Tage ohne Datenverlust (fester Startpunkt, Kontinuität seit der alten // Tage ohne Datenverlust (fester Startpunkt, Kontinuität seit der alten
+5 -1
View File
@@ -3,7 +3,10 @@
// pid aus dem Pfad /e/<pid>. // pid aus dem Pfad /e/<pid>.
const pid = location.pathname.split("/")[2] || ""; const pid = location.pathname.split("/")[2] || "";
document.getElementById("reply-form").addEventListener("submit", async (e) => { const replyForm = document.getElementById("reply-form");
setupClipboardPaste(replyForm, document.getElementById("reply-paste-msg"));
replyForm.addEventListener("submit", async (e) => {
e.preventDefault(); e.preventDefault();
const fd = new FormData(e.target); const fd = new FormData(e.target);
fd.append("reply_to", pid); fd.append("reply_to", pid);
@@ -11,6 +14,7 @@ document.getElementById("reply-form").addEventListener("submit", async (e) => {
if (res.ok) { if (res.ok) {
e.target.reset(); e.target.reset();
document.getElementById("reply-msg").textContent = ""; document.getElementById("reply-msg").textContent = "";
document.getElementById("reply-paste-msg").textContent = "";
load(); load();
} else { } else {
document.getElementById("reply-msg").textContent = document.getElementById("reply-msg").textContent =
+30
View File
@@ -40,6 +40,36 @@ function linkify(s) {
.replace(/\n/g, "<br>"); .replace(/\n/g, "<br>");
} }
// setupClipboardPaste erlaubt Strg+V eines Bildes aus der Zwischenablage direkt
// im Formular: das Bild wandert in den File-Input (über DataTransfer, weil sich
// .files nicht direkt setzen lässt). Liegt kein Bild vor (Text o. Ä.), tun wir
// nichts und lassen den normalen Paste durchlaufen -> preventDefault nur, wenn
// wir wirklich ein Bild gegriffen haben. msgEl (optional) zeigt den Hinweis.
function setupClipboardPaste(form, msgEl) {
form.addEventListener("paste", (e) => {
const item = [...(e.clipboardData?.items ?? [])].find(
(it) => it.kind === "file" && it.type.startsWith("image/")
);
if (!item) return;
const original = item.getAsFile();
if (!original) return;
e.preventDefault();
// Browser benennt Clipboard-Bilder uneinheitlich ("grafik.png" o. Ä.) -> neu
// verpacken mit sprechendem Namen. Endung aus dem MIME-Typ, sonst png.
const ext = (original.type.split("/")[1] || "png").toLowerCase();
const file = new File([original], `zwischenablage.${ext}`, { type: original.type });
const input = form.querySelector("input[name='file']");
const dt = new DataTransfer();
dt.items.add(file);
input.files = dt.files;
if (msgEl) msgEl.textContent = "Bild aus Zwischenablage übernommen.";
});
}
function renderEntry(e) { function renderEntry(e) {
const el = document.createElement("article"); const el = document.createElement("article");
el.className = "card"; el.className = "card";