Videos: Stufe 7 -- aus einem Wunsch wird ein Video, mit Namen

"Ein Video aus einem Wunsch zeigt den Namen." Wer sich etwas
gewuenscht hat, soll sehen, dass daraus etwas geworden ist -- das ist
der Sinn eines Wunschbretts. Ohne die Verbindung ist die Galerie eine
Sammlung, und der Wunsch von letzter Woche bleibt unbeantwortet im
Raum stehen.

DER KNOPF STEHT AM WUNSCH, nicht im Formular oben. Das ist dieselbe
Entscheidung wie bei den Kettenknoepfen daneben, aus demselben Grund
(dort woertlich): "Wer ein Formular ausfuellt, denkt nicht an den
Wunsch von letzter Woche." Hier denkt er an nichts anderes.

DAS LECK, das es nicht geben darf: Der Titel der Quelle wird auf der
Kachel ANGEZEIGT. Eine Kette in die Content-Planung waere deshalb kein
Schoenheitsfehler, sondern ein Weg, interne Arbeit in die Community zu
tragen. Die Quelle muss ein Community-Brett sein -- dieselbe Regel wie
beim "Daraus"-Knopf.

ZWEI WEGE, EIN ZIEL: "Daraus ein Highlight machen" gibt es laenger.
Wer ihn geht und DANACH das Video einfuegt, bekaeme sonst ein zweites
Highlight aus demselben Wunsch -- zwei Wege zum selben Ziel, die
nichts voneinander wissen. Das Video haengt sich jetzt an den
vorhandenen Eintrag. Der Titel bleibt dabei der des Wunsches: Er
stammt von einem Menschen, der von TikTok ist eine Bildunterschrift
mit Schlagwoertern.

Geprueft: pruef-video 51 -> 67. Gegenprobe (Brett-Pruefung und
Anhaengen ausgebaut) macht 6 rot, darunter "ein Eintrag aus der
Content-Planung kommt NICHT als Quelle durch (201)".

UND DAS BILDSCHIRMFOTO HAT ETWAS GEFUNDEN, das keine Zahl gemeldet
haette: Das Eingabefeld erschien am ENDE der Karte, unter der
Fusszeile -- getrennt von dem Knopf, den man gerade gedrueckt hatte.
Alle Pruefungen waren gruen, das Feld war da und reagierte. Jetzt
haengt es an der Knopfreihe.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-18 17:00:16 +02:00
co-authored by Claude Opus 5
parent fb55377e19
commit 59c84bd248
38 changed files with 726 additions and 413 deletions
+37
View File
@@ -1396,3 +1396,40 @@
color: color-mix(in srgb, var(--akzent) 42%, #ffffff);
}
/* ---- „Video dazu einfügen" an einer Wunschkarte (Stufe 7) ----------
Eine Zeile, kein Kasten mit Rahmen: Es ist ein Zwischenschritt, der
gleich wieder verschwindet. Ein aufwendig gestaltetes Formular an
dieser Stelle sähe aus, als gehörte es dauerhaft zur Karte. */
.videodazu {
display: flex;
flex-wrap: wrap;
gap: .5rem;
align-items: center;
margin-top: .7rem;
padding-top: .7rem;
border-top: 1px solid rgba(140, 160, 185, .18);
}
.videodazu__feld {
flex: 1 1 15rem;
min-width: 0;
padding: .45rem .6rem;
border: 1px solid rgba(140, 160, 185, .35);
border-radius: .55rem;
background: rgba(10, 18, 30, .55);
color: #e8f1fa;
font-size: .9rem;
}
.videodazu__feld:focus-visible {
outline: 2px solid #6ea8d8;
outline-offset: 1px;
}
.videodazu__senden { flex: 0 0 auto; }
/* Die Rückmeldung bekommt eine eigene Zeile, damit eine lange
Fehlermeldung das Feld nicht aus der Zeile drückt. */
.videodazu__sagt {
flex: 1 0 100%;
margin: 0;
min-height: 1.1em;
color: #9fb3c9;
font-size: .84rem;
}
+80
View File
@@ -869,6 +869,36 @@
}));
}
/* ---- VIDEO DAZU (Stufe 7, 18.09.2026) --------------------------
„Ein Video aus einem Wunsch zeigt den Namen." Der Knopf steht
AN DEM WUNSCH -- aus demselben Grund wie die Kettenknoepfe
darueber: Wer oben im Formular einen Link einfuegt, denkt nicht
an den Wunsch von letzter Woche. Hier denkt er an nichts
anderes.
Er verschwindet, sobald aus dem Wunsch ein Highlight MIT Video
geworden ist. Steht dort schon ein Highlight ohne Video, bleibt
er -- der Server haengt das Video dann an den vorhandenen
Eintrag, statt ein zweites anzulegen. */
if (VIDEO_AUS.includes(bereich)
&& !(e.wurde || []).some((w) => w.bereich === 'highlight' && w.hat_video)) {
knoepfe.append(tuKnopf('Video dazu einfügen', () => {
/* Schon offen? Dann wieder zu. Ein Knopf, der beim zweiten
Druecken ein zweites Feld baut, ist ein Fehler, den man
erst sieht, wenn drei davon dastehen. */
const alt = k.querySelector('.videodazu');
if (alt) { alt.remove(); return; }
/* DIREKT UNTER DIE KNOPFREIHE, nicht ans Ende der Karte.
Zuerst stand hier `k.append` -- und das Bildschirmfoto zeigte
das Feld UNTER der Fusszeile („18.09.2026 - von Lena"),
getrennt von dem Knopf, den man gerade gedrueckt hat. Eine
Zahl haette das nie gemeldet: Das Feld war da, es reagierte,
alle Pruefungen gruen. */
knoepfe.insertAdjacentElement('afterend', videoDazuFeld(e));
}));
}
/* VIER ZUSTAENDE STATT EINES UMSCHALTERS (17.09.2026).
"erledigt / wieder offen" reicht fuer einen Vorfall. Ein Wunsch
@@ -1095,6 +1125,56 @@
Link einfuegen, den Rest macht der Server. Nur bei den Highlights:
Dort gehoeren Clips hin, und ein Feld an jedem anderen Brett waere
eine Einladung, sie ueberall hinzuschreiben. */
/* Aus welchen Brettern heraus ein Video eingefuegt werden kann.
„mitmachen" und „regeln" stehen bewusst nicht dabei: Dort geht es
nicht um Inhalte, aus denen ein Clip wird. */
const VIDEO_AUS = ['wunsch', 'ansteht'];
/** Das Eingabefeld, das direkt an der Karte aufgeht. */
function videoDazuFeld(e) {
const kasten = el('div', 'videodazu');
const feld = el('input', 'videodazu__feld');
feld.type = 'url';
feld.placeholder = 'TikTok-Link einfügen';
/* Ohne Beschriftung waere das Feld fuer eine Vorleseansage ein
Kaestchen ohne Bedeutung. Sichtbar ist der Knopftext daneben. */
feld.setAttribute('aria-label', 'TikTok-Link zu diesem Eintrag');
const senden = el('button', 'schritt videodazu__senden', 'Übernehmen');
senden.type = 'button';
const sagt = el('p', 'videodazu__sagt');
senden.addEventListener('click', async () => {
const url = feld.value.trim();
if (!url) { feld.focus(); return; }
senden.disabled = true;
sagt.textContent = 'Wird geholt …';
try {
const a = await hole('/workspace/api/bereich/highlight/video', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url, aus: e.id }),
});
const r = await a.json().catch(() => ({}));
if (!a.ok) {
/* Der Grund des Servers, nicht „Ging nicht" -- er weiss, ob
der Account fremd war oder die Adresse keine ist. */
sagt.textContent = r.fehler || 'Ging nicht.';
senden.disabled = false;
return;
}
await laden();
} finally { senden.disabled = false; }
});
feld.addEventListener('keydown', (ev) => {
if (ev.key === 'Enter') { ev.preventDefault(); senden.click(); }
});
kasten.append(feld, senden, sagt);
/* Der Fokus wandert ins Feld: Wer den Knopf gedrueckt hat, will
tippen, nicht erst noch zielen. */
setTimeout(() => feld.focus(), 0);
return kasten;
}
function videoFeldZeigen() {
const ziel = $('videoholen');
if (!ziel) return;