Panel: die volle Fernbedienung ueber der Senderliste

Was laeuft, wo, aus welcher Quelle, mit Fortschrittsbalken. Sprachkanal
waehlen, Sender abspielen, Ueberspringen, Zum Radio, Stopp,
Lautstaerke-Schieber. Einreihen per Link oder Suchbegriff, Warteschlange
mit Hoch/Runter/Weg und Leeren. Darunter ein aufklappbarer yt-dlp-Block:
Zustand, Fassung, cookies.txt, eigene Argumente, Aktualisieren -- und die
letzte Fehlerzeile im Klartext.

Steht ueber der Senderliste, weil man oefter etwas abspielt als die Liste
pflegt.

Die Abfrage laeuft nur, solange der Community-Reiter offen ist. Sonst
ginge alle fuenf Sekunden eine Anfrage gegen eine Ansicht raus, die
niemand ansieht.

Der Balken erscheint nur bei bekannter Dauer. Bei einem Livestream gaebe
er einen Stand vor, den niemand kennt -- dort steht stattdessen "live".

Die Kanalauswahl graut aus, wo der Bot nicht rein darf. Ein Kanal, den das
Panel anbietet und in den der Bot dann nicht kommt, sieht aus wie ein
kaputter Knopf.

Geprueft: der Vite-Build laeuft durch, und ein Abgleich stellt alle 30
Feldpfade, die die Oberflaeche vom Stand liest, gegen die echte
API-Antwort -- 0 fehlen. Der Abgleich hat eine Gegenprobe mit bekanntem
Ausgang (ein Feld, das es nicht gibt, muss als fehlend erkannt werden) und
prueft vorher, ob die sonst leeren Zweige (Warteschlange, Cookies, letzter
Fehler) ueberhaupt besetzt sind -- sonst meldet er "ungueltig" statt "in
Ordnung". Seine erste Fassung hatte Fehlalarm geschlagen (?. und .map als
fehlende Felder gelesen); das ist behoben.

NICHT geprueft: das tatsaechliche Rendern im Browser -- hier ist weder
Browser noch DOM-Werkzeug vorhanden.
This commit is contained in:
2026-08-28 13:50:06 +02:00
parent 1ac349029f
commit dbec4e9775
3 changed files with 536 additions and 3 deletions
+55
View File
@@ -3250,3 +3250,58 @@ button.with-icon, a.with-icon { justify-content: center; }
@media (max-width: 560px) {
.radio-form-row { grid-template-columns: 1fr; }
}
/* ── Radio-Fernbedienung ──────────────────────────────────────────────── */
.radio-remote {
border: 1px solid var(--border);
background: var(--bg2);
padding: 1rem;
margin-bottom: 1.2rem;
display: flex;
flex-direction: column;
gap: .9rem;
}
.radio-now { border-left: 3px solid var(--accent); padding-left: .8rem; }
.radio-now-head { display: flex; gap: .7rem; align-items: flex-start; }
.radio-badge { font-size: 1.4rem; line-height: 1.2; }
.radio-now-text { min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.radio-now-text strong { color: var(--text); overflow-wrap: anywhere; }
.radio-now-sub { color: var(--text-dim); font-size: .72rem; overflow-wrap: anywhere; }
.radio-progress { display: flex; align-items: center; gap: .6rem; margin-top: .5rem; }
.radio-progress-bar { flex: 1; height: 4px; background: var(--bg3); overflow: hidden; }
.radio-progress-bar span {
display: block; height: 100%; background: var(--accent);
/* Der Balken springt sonst bei jeder Abfrage; fuenf Sekunden Abstand
zwischen zwei Staenden sieht ohne das aus wie ein Ruckeln. */
transition: width .6s linear;
}
.radio-progress-text { color: var(--text-dim); font-size: .68rem; font-variant-numeric: tabular-nums; }
.radio-add { display: flex; gap: .5rem; }
.radio-add input { flex: 1; min-width: 0; }
.radio-station-pick { max-width: 16rem; }
.radio-fehler {
background: var(--bg3);
border: 1px solid var(--border);
padding: .55rem .7rem;
font-size: .68rem;
/* Eine Fehlerzeile von yt-dlp ist lang und darf nicht die Seite
breiter machen -- sie bricht um statt zu schieben. */
white-space: pre-wrap;
overflow-wrap: anywhere;
margin: 0 0 .6rem;
color: var(--text-dim);
}
.radio-yt { border-top: 1px solid var(--border); padding-top: .8rem; }
.radio-yt > summary { cursor: pointer; color: var(--text-dim); font-size: .74rem; }
.radio-yt > summary:hover { color: var(--text); }
.radio-yt textarea { width: 100%; font-family: var(--mono, monospace); font-size: .68rem; }
.radio-yt .field { margin-top: .7rem; }
@media (max-width: 700px) {
.radio-add { flex-direction: column; }
.radio-station-pick { max-width: none; }
}