- EntryPage: Vorfahren, Fokus, Antworten mit unverändertem Markup - Bearbeiten/Löschen für eigene Beiträge, Antwortformular mit Zwischenablage-Bild - useMe(): eigenes Konto oder null (401 = nicht angemeldet) - nach Änderungen Thread und Feeds invalidieren Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import type { ClipboardEvent } from "react";
|
|
|
|
// pasteImage 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. Gibt true zurück, wenn ein Bild
|
|
// übernommen wurde.
|
|
export function pasteImage(e: ClipboardEvent<HTMLFormElement>): boolean {
|
|
const item = [...(e.clipboardData?.items ?? [])].find(
|
|
(it) => it.kind === "file" && it.type.startsWith("image/"),
|
|
);
|
|
const original = item?.getAsFile();
|
|
if (!original) return false;
|
|
e.preventDefault();
|
|
|
|
// Browser benennen 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 = e.currentTarget.querySelector<HTMLInputElement>("input[name='file']");
|
|
if (!input) return false;
|
|
const dt = new DataTransfer();
|
|
dt.items.add(file);
|
|
input.files = dt.files;
|
|
return true;
|
|
}
|