Filipe: "in dieser kachel soll wenn ich live bin um 20h bis 22h ein
live button der richtig geil ist mit einem live roten punkt symbol am
besten, das soll aufblinken fuer zwei stunden. man soll nicht drauf
druecken koennen aber so dass es auffaellt. ... die leute sollen auch
automatisch eine benarichtigung bekommen um 20 uhr dass ich live bin."
EINE AUSKUNFT, EINE AUSLEGUNG (workspace/assets/js/live.js)
Drei Stellen sollen dasselbe wissen: die Kachel "Draussen" auf der
Startseite, die Kanalkarten auf der Draussen-Seite, die Pulskarte
darunter. Drei Abfragen waeren drei Auslegungen -- und spaetestens
beim naechsten Umbau steht auf der Kachel LIVE und daneben "wartet".
DER DRITTE AUSGANG IST HIER DIE EIGENTLICHE ARBEIT
Die oeffentliche Seite (assets/js/streamplan.js) faengt jeden Fehler
ab und setzt istLive = false. Aus "wir konnten nicht fragen" wird
dort "er sendet nicht" -- wer das liest, macht zu und verpasst den
Stream. Der Dienst SAGT sogar, ob er nachsehen konnte (autoHealthy);
gelesen wird es dort nicht.
Hier gibt es drei Antworten: live / wartet / weiss-nicht. Bei
"weiss nicht" blinkt nichts -- aber es behauptet auch niemand, dass
nichts laeuft. Sechs Antworten des Dienstes durchgespielt.
BLINKEN OHNE FLACKERN
Hausregel vom 12.08.2026: keine aggressiven Flacker-Effekte. Das ist
kein Widerspruch zu "richtig geil", sondern dieselbe Sache: Ein Rot,
das im Sekundentakt umspringt, liest man als "Alarm, ich sehe weg".
Eins, das atmet und einen Saum nach aussen schickt, liest man als
"jetzt gerade". 1,4 Sekunden, ueberall derselbe Takt -- zwei Rhythmen
nebeneinander waeren Unruhe, einer ist ein Herzschlag. Die Pruefung
verlangt ausdruecklich >= 1 s und einen einheitlichen Takt; nach dem
Wort "animation" zu suchen waere auch bei 0,1 s gruen.
Bei Bewegungsarmut steht alles still -- der rote Punkt bleibt
sichtbar, er bewegt sich nur nicht. Im Kontrastmodus sagt es ein
Rahmen, weil Farben dort nichts tragen.
KEIN KNOPF, UND ES SIEHT AUCH NICHT SO AUS
pointer-events: none ist die halbe Antwort; die andere ist die Form.
Etwas, das wie ein Knopf aussieht und nichts tut, ist eine Sackgasse.
Deshalb eine Marke wie auf einer Kamera: Punkt plus Wort. Das Wort
steht auch fuer Vorleseprogramme da -- ein stummer roter Kreis waere
die halbe Auskunft.
DIE KACHEL WIRD UEBER IHR ZIEL ERKANNT, NICHT UEBER DEN NAMEN.
Der Name hat sich in diesem Haus schon zweimal geaendert ("Unsere
Seiten" -> "Draussen"), das Ziel nie. Am 21.09. hat genau dieser
Unterschied eine ganze Hinweisspalte lahmgelegt.
DIE BENACHRICHTIGUNG ENTSCHEIDET DER DIENST, NICHT DIE UHR.
Eine Meldung "er ist live", waehrend er nicht sendet, funktioniert
genau einmal: Beim zweiten Mal weiss jeder, dass sie nichts bedeutet.
Deshalb prueft der Lauf (alle fuenf Minuten) den echten Status; bei
"weiss nicht" wird NICHTS verschickt. Ein Merkmal mit Datum haelt es
bei einer pro Abend -- sonst kaemen in zwei Stunden 24.
Eigene Art "dogfather_live", vorgegeben an und trotzdem abschaltbar:
Wer jeden Abend dieselbe Meldung bekommt und nie hinschaut, schaltet
sonst ALLES ab, und dann erreicht ihn auch keine Aufgabe mehr.
EIN FEHLER, DEN DIE PRUEFUNG GEFANGEN HAT: Der Versand las aus
"push_geraete" -- diese Tabelle gibt es nicht, sie heisst
push_anmeldungen. Der Block steht in einem try/catch; der Fehler
waere still geblieben, und die Benachrichtigung waere nie gekommen.
Die Pruefung verlangt jetzt ausdruecklich, dass die Tabelle im
Schema existiert.
NEU: pruef-livepunkt 49/0, mit drei Gegenproben.
Daneben gruen: pruef-css-klassen 30/0, pruef-push 24/0,
pruef-draussen 39/0, pruef-zwischenspeicher 27/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
156 lines
5.7 KiB
JavaScript
156 lines
5.7 KiB
JavaScript
/* =====================================================================
|
|
live.js — IST ER GERADE LIVE? Eine Auskunft, eine Auslegung.
|
|
=====================================================================
|
|
|
|
Filipe am 22.09.2026: „in dieser kachel soll wenn ich live bin um
|
|
20h bis 22h ein live button der richtig geil ist mit einem live
|
|
roten punkt symbol am besten, das soll aufblinken für zwei stunden.
|
|
man soll nicht drauf drücken können aber so dass es auffällt."
|
|
|
|
WARUM DAS EINE EIGENE DATEI IST
|
|
Drei Stellen sollen ab jetzt dasselbe wissen: die Kachel „Draußen"
|
|
auf der Startseite, die Kanalkarten auf der Draußen-Seite und die
|
|
Pulskarte darunter. Drei Abfragen wären drei Auslegungen — und
|
|
spätestens beim nächsten Umbau widersprechen sie sich. Dann steht
|
|
auf der Kachel LIVE und auf der Seite daneben „wartet".
|
|
|
|
DER DRITTE AUSGANG IST HIER DER WICHTIGE
|
|
Die öffentliche Seite (`assets/js/streamplan.js`) fängt jeden
|
|
Fehler ab und setzt `istLive = false`. Aus „wir konnten nicht
|
|
fragen" wird dort „er sendet nicht" — und wer das liest, macht zu
|
|
und verpasst den Stream. Der Dienst SAGT sogar, ob er nachsehen
|
|
konnte (`autoHealthy`); gelesen wird es dort nicht.
|
|
|
|
Hier gibt es drei Antworten: live / wartet / weiss-nicht. Bei
|
|
„weiss-nicht" blinkt nichts — aber es behauptet auch niemand, dass
|
|
nichts läuft.
|
|
|
|
BLINKEN, NICHT FLACKERN
|
|
Das Haus hat die Regel „keine aggressiven Flacker-Effekte,
|
|
prefers-reduced-motion respektieren" (12.08.2026). Ein LIVE-Punkt,
|
|
der zehnmal pro Sekunde an und aus geht, ist genau das — und auf
|
|
einem Handy in der Hosentasche kein bisschen auffälliger als einer,
|
|
der ruhig atmet. Deshalb ein Puls von 1,4 Sekunden: unübersehbar,
|
|
ohne in den Augen wehzutun. Wer Bewegungsarmut eingestellt hat,
|
|
bekommt einen ruhigen roten Punkt — er sieht dasselbe, es bewegt
|
|
sich nur nicht.
|
|
===================================================================== */
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
var POSTFACH = 'https://postfach.dogfather-universe.com';
|
|
var TAKT = 30000;
|
|
|
|
var lage = { zustand: 'laedt', titel: '' };
|
|
var zuhoerer = [];
|
|
var uhr = 0;
|
|
var laeuft = false;
|
|
|
|
/** Eine Auslegung, an einer Stelle.
|
|
*
|
|
* `live` — es läuft, belegt.
|
|
* `wartet` — der Dienst hat nachgesehen, es läuft nichts.
|
|
* `weissnicht` — wir konnten nicht nachsehen. NICHT dasselbe wie
|
|
* „wartet", und deshalb ein eigener Zustand. */
|
|
function auswerten(d) {
|
|
if (!d || d.ok !== true) return { zustand: 'weissnicht', titel: '' };
|
|
if (d.live) return { zustand: 'live', titel: d.title || '' };
|
|
/* Hat jemand den Status von Hand gesetzt, gilt der -- die
|
|
Gesundheit des automatischen Prüfers spielt dann keine Rolle. */
|
|
if (d.source === 'automatisch' && d.autoHealthy === false) {
|
|
return { zustand: 'weissnicht', titel: '' };
|
|
}
|
|
return { zustand: 'wartet', titel: '' };
|
|
}
|
|
|
|
function melden() {
|
|
for (var i = 0; i < zuhoerer.length; i++) {
|
|
try { zuhoerer[i](lage); } catch (f) { /* ein Zuhörer darf den Rest nicht aufhalten */ }
|
|
}
|
|
}
|
|
|
|
async function holen() {
|
|
if (laeuft) return lage;
|
|
laeuft = true;
|
|
try {
|
|
var antwort = await fetch(POSTFACH + '/live-status', { cache: 'no-store' });
|
|
if (!antwort.ok) throw new Error('HTTP ' + antwort.status);
|
|
lage = auswerten(await antwort.json());
|
|
} catch (f) {
|
|
lage = { zustand: 'weissnicht', titel: '' };
|
|
} finally {
|
|
laeuft = false;
|
|
}
|
|
melden();
|
|
return lage;
|
|
}
|
|
|
|
function anschalten() {
|
|
if (uhr) return;
|
|
uhr = setInterval(holen, TAKT);
|
|
}
|
|
function ausschalten() {
|
|
if (!uhr) return;
|
|
clearInterval(uhr);
|
|
uhr = 0;
|
|
}
|
|
|
|
/** Meldet sich sofort mit dem aktuellen Stand und danach bei jeder
|
|
* Änderung. Gibt eine Funktion zum Abmelden zurück. */
|
|
function beobachten(rueckruf) {
|
|
zuhoerer.push(rueckruf);
|
|
try { rueckruf(lage); } catch (f) { /* Zugabe */ }
|
|
anschalten();
|
|
holen();
|
|
return function () {
|
|
var i = zuhoerer.indexOf(rueckruf);
|
|
if (i >= 0) zuhoerer.splice(i, 1);
|
|
if (!zuhoerer.length) ausschalten();
|
|
};
|
|
}
|
|
|
|
/* IM HINTERGRUND WIRD NICHT GEFRAGT. Ein Tab, der seit gestern
|
|
offen ist, braucht keine 2880 Abfragen -- und beim Zurückkommen
|
|
ist die erste Frage ohnehin die wichtigste. */
|
|
document.addEventListener('visibilitychange', function () {
|
|
if (document.hidden) { ausschalten(); return; }
|
|
if (zuhoerer.length) { anschalten(); holen(); }
|
|
});
|
|
|
|
/** Baut das LIVE-Abzeichen: roter Punkt plus Wort.
|
|
*
|
|
* `aria-hidden` und `pointer-events: none` (im CSS): Filipe
|
|
* ausdrücklich — „man soll nicht drauf drücken können aber so dass
|
|
* es auffällt". Ein Abzeichen, das aussieht wie ein Knopf und
|
|
* nichts tut, ist eine Sackgasse; eins, das gar nicht erst nach
|
|
* Knopf aussieht, ist eine Auskunft.
|
|
*
|
|
* Für Vorleseprogramme steht der Text trotzdem da -- unsichtbar
|
|
* wäre er die halbe Auskunft. */
|
|
function abzeichen(text) {
|
|
var a = document.createElement('span');
|
|
a.className = 'live-marke';
|
|
a.setAttribute('role', 'status');
|
|
var p = document.createElement('span');
|
|
p.className = 'live-marke__punkt';
|
|
p.setAttribute('aria-hidden', 'true');
|
|
a.appendChild(p);
|
|
var w = document.createElement('span');
|
|
w.className = 'live-marke__wort';
|
|
w.textContent = text || 'LIVE';
|
|
a.appendChild(w);
|
|
return a;
|
|
}
|
|
|
|
window.LiveStatus = {
|
|
beobachten: beobachten,
|
|
holen: holen,
|
|
abzeichen: abzeichen,
|
|
/* Nur zum Messen -- eine Prüfung soll die Auslegung prüfen
|
|
können, ohne den echten Dienst zu brauchen. */
|
|
auswerten: auswerten,
|
|
get lage() { return lage; },
|
|
};
|
|
}());
|