Screenshots an einen Beitrag hängen

Filipe (Runde vom 23.09.2026): „mach das man da bitte screenshots
oder kurzschnitte von den live reinposten kann. nach dem selben
prinzip wie bei den anderen nebendran."

ES FEHLTE WENIGER, ALS MEINE EIGENE NOTIZ BEHAUPTETE. Dort stand „ein
eigener Brocken (Upload, Groessenpruefung, Sicherheit), kein
Nebenbei". Nachgemessen statt geglaubt: Die Spalte `dateien.eintrag_id`
gibt es seit dem Video-Einlesen, die Karten zeichnen ihren
Bildstreifen bereits, und die Auslieferung entscheidet die
Sichtbarkeit schon am BEITRAG statt an der Ablage. Gefehlt hat genau
ein Weg -- das Hochladen. Wieder ein Beleg dafuer, dass auch meine
eigenen Listen altern.

„NACH DEM SELBEN PRINZIP" IST WOERTLICH GENOMMEN: `dateiErkennen` aus
dem Chat (eine Fassung, drei Benutzer -- Chat, Support, Beitraege),
derselbe Ordner wie die Dateiablage (die Auslieferung kennt nur einen
Pfad), `express.raw` mit Rechtepruefung VOR der Annahme des Rumpfes.

DER KNOPF STEHT AN DER KARTE, nicht im Anlege-Formular. Ein
Bildschirmfoto faellt einem meist spaeter ein -- beim Nachschauen,
wenn jemand fragt. Wer es nur beim Anlegen mitgeben koennte, muesste
den Beitrag loeschen und neu schreiben. Er erscheint nur, solange
noch Platz ist (drei je Beitrag), damit er nie eine Absage bringt.

ZWEI FEHLER IN MEINEM EIGENEN CODE, beide beim ersten Laden gefunden:
`DATEN_ORDNER` war nicht importiert, und `bereichVon()` hatte ich
erfunden -- es gibt sie nicht. Der Bereich steht am Eintrag selbst
und ist dort auch richtiger: Er kommt aus der Datenbank, nicht aus
der Adresse.

UND ZWEI MESSFEHLER, beide dieselbe Sorte wie den ganzen Tag: Ich
fragte „darf die Community?" an einem Beitrag, den sie gar nicht
sieht (404 -- richtige Antwort, falsche Frage), dann an einem
freigegebenen (403 -- sie braucht eine Stufe zum Schreiben, auch das
richtig). Die Frage, die wirklich zaehlt, ist eine andere: Gilt fuer
ein Bild dieselbe Regel wie fuer einen Beitrag? Gemessen: Beitrag
403, Bild 403. Ein zweiter Weg mit anderen Rechten waere die Tuer,
die niemand bemerkt.

Gemessen: pruef-eintrag-bild, 24 Pruefungen, 0 Fehler -- darunter
als Bild getarntes HTML (415), SVG (415, es ist XML und darf Skripte
enthalten), PDF (415), die Grenze von drei am Server, und das
Abnehmen samt Datei. Gruen: pruef-highlights (31), pruef-anhaenge,
pruef-fassungen, pruef-galerie, pruef-video, pruef-css-klassen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-24 11:44:01 +02:00
co-authored by Claude Opus 5
parent 7acd7a7674
commit d231e989cf
43 changed files with 1184 additions and 615 deletions
+67
View File
@@ -381,6 +381,53 @@
haette man sie achtmal aendern muessen. */
const hole = (pfad, optionen) => window.holen(pfad, optionen);
/** Ein Bild auswaehlen und an den Beitrag haengen.
*
* DAS DATEIFELD WIRD JEDES MAL NEU GEBAUT und danach weggeworfen.
* Ein dauerhaftes im HTML waere ein Feld fuer vierzig Karten --
* und beim zweiten Mal dieselbe Datei, weil der Browser den Wert
* behaelt, wenn man denselben Namen erneut waehlt.
*
* DIE VORSCHAU GIBT ES HIER NICHT. Beim Support ist sie wichtig
* (man schreibt einen Text dazu und will sehen, was man mitgibt);
* hier geht das Bild sofort raus und steht eine Sekunde spaeter
* als Streifen an der Karte. Eine Vorschau dazwischen waere ein
* Schritt, den niemand braucht. */
function bildWaehlen(e) {
const feld = document.createElement('input');
feld.type = 'file';
feld.accept = 'image/png,image/jpeg,image/webp,image/gif';
feld.addEventListener('change', async () => {
const datei = feld.files?.[0];
if (!datei) return;
/* Die Grenze steht hier nur als Freundlichkeit -- abgelehnt
wird am Server. Sie erspart es, zwoelf Megabyte erst
hochzuladen, um danach eine Absage zu lesen. */
if (datei.size > 12 * 1024 * 1024) {
melde('Das Bild ist größer als 12 MB – bitte ein kleineres.');
return;
}
melde('Bild wird hochgeladen …');
try {
const a = await hole(
`/workspace/api/bereich/${bereich}/${e.id}/bild`,
{
method: 'POST',
headers: { 'x-name': encodeURIComponent(datei.name || 'Bild') },
body: datei,
});
if (!a.ok) {
melde(sagWas((await a.json().catch(() => ({}))).fehler,
'Das Bild ließ sich nicht anhängen.'));
return;
}
melde('Bild ist dran.');
await laden();
} catch { /* umgeleitet */ }
});
feld.click();
}
function tuKnopf(text, tu) {
const b = el('button', 'schritt', text);
b.type = 'button';
@@ -1346,6 +1393,26 @@
}));
}
/* ==== EIN BILD ANHAENGEN (24.09.2026) =========================
Filipe: "mach das man da bitte screenshots oder kurzschnitte
von den live reinposten kann. nach dem selben prinzip wie bei
den anderen nebendran."
DER KNOPF STEHT AN DER KARTE, nicht im Anlege-Formular. Das ist
der Unterschied zu "beim Schreiben ein Bild mitschicken": Ein
Bildschirmfoto faellt einem meist spaeter ein -- beim
Nachschauen, beim Erklaeren, wenn jemand fragt. Wer es nur beim
Anlegen mitgeben koennte, muesste den Beitrag loeschen und neu
schreiben.
ER ERSCHEINT NUR, WENN NOCH PLATZ IST. Drei Bilder je Beitrag
(der Server setzt die Grenze durch); beim vierten waere der
Knopf einer, der eine Absage bringt. */
if (darfEintragen() && (e.bilder || []).length < 3) {
knoepfe.append(tuKnopf('Bild anhängen', () => bildWaehlen(e)));
}
if (LEITUNG.has(ich.rolle) || e.erstellt_von === ich.id) {
knoepfe.append(tuKnopf('löschen', async () => {
/* EIN FREMDER BEITRAG AUF EINEM TREFF-BRETT BRAUCHT EINEN