e00a905ce8a1a1cf3fb62c12b4ec5d7cc77c0c69
37
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3d859cbed5 |
Eine untaugliche Zweitfassung erkennt der Server selbst
NACHGEMESSEN AN DEN SECHS, DIE HEUTE NACHT LIVE ENTSTANDEN SIND --
vier tragen das Loch am Anfang, weil sie gebaut wurden, bevor es
bekannt war:
387,6 s Zeitachse fuer wenige Sekunden Ton
164,2 s
134,1 s
63,8 s
9,7 s (in Ordnung)
3,3 s (in Ordnung)
Sie gehoeren dem Dienstbenutzer; von aussen sind sie nicht
wegzuraeumen. Und mit „gibt es schon, dann weiter" waeren sie fuer
immer so geblieben.
EIN SCHALTER „alles neu ab Fassung 2" WAERE DIE BEQUEME LOESUNG und
die falsche: eine Zahl, die jemand hochzaehlen muss, wird beim
naechsten Mal vergessen. Gefragt wird deshalb die DATEI SELBST --
nach dem, was schiefgehen kann: Passt ihre Zeitachse zu der
Tonmenge, die sie traegt? AAC packt 1024 Abtastwerte in einen
Rahmen; Rahmenzahl mal 1024 durch die Abtastrate ist die echte
Laenge. Mehr als anderthalb Sekunden darueber heisst: Loch.
Was nicht passt, wird beim naechsten Nachruestlauf weggeraeumt und
neu gebaut -- einmal, denn danach passt es.
ZWEI FEHLER IN DIESER FUNKTION, BEIDE VON DER GEGENPROBE GEFUNDEN
Und beide waeren still geblieben:
1. ffprobe GIBT DIE WERTE IN SEINER REIHENFOLGE AUS, nicht in
meiner: erst `sample_rate`, dann `nb_frames`. Ich hatte
`[rahmen, rate, dauer]` destrukturiert und damit 48000 Rahmen
bei 95 Hz gerechnet -- eine „echte Laenge" von einer halben
Million Sekunden. Die Funktion haette JEDE Datei fuer tauglich
erklaert, immer. Gelesen wird jetzt mit Namen.
2. DER DATEINAME FEHLTE IM AUFRUF. ffprobe antwortete „You have to
specify one input file", der `catch` machte daraus ein
freundliches „taugt" -- und wieder sagte die Funktion zu allem
ja.
Das ist zweimal dieselbe Sorte: gruen und wertlos. Gefunden hat es
nicht das Lesen, sondern die Frage „kann sie ueberhaupt NEIN
sagen?". Genau dafuer gibt es die Gegenprobe.
WIE MAN EINE DATEI MIT LOCH NACHSTELLT -- UND WIE NICHT
`-itsoffset 40` war der naheliegende Weg und ergab 2,5 s: Der
MP4-Baukasten rechnet einen reinen Anfangsversatz wieder heraus.
Dasselbe mit `-copyts`, `-output_ts_offset` und `-muxdelay`. Was
bleibt, ist eine Zeitachse, die laenger ist als ihr Ton -- und das
stellt eine stumme Bildspur von 40 Sekunden her. Der Weg dorthin
ist ein anderer als bei `MediaRecorder`; die ZAHLEN, die die
Funktion liest, sind dieselben.
GEPRUEFT -- pruef-chat-anhaenge 164 -> 168 ok
eine Fassung mit zu langer Zeitachse nachgestellt (40,0 s)
und sie wird als untauglich erkannt
der Nachruestlauf ersetzt sie (40,0 s → 2,5 s)
und die neue gilt als tauglich — er wandelt sie nicht ewig weiter
Die letzte Zeile ist die zweite Gegenprobe: Ein Lauf, der bei jedem
Durchgang alles neu wandelt, waere eine Warnung, die immer kommt.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d70d00cedc |
Jede Sprachnachricht in einer Fassung, die JEDES Geraet abspielt
Miss im Support, Meldung #12 -- fuenf Runden seit dem 23.09.: „Bei mir laesst sich die Nachricht nicht abspielen." Zuletzt: „Jetzt laedt es die ganze Zeit." Bei allen anderen ging es. GEMESSEN, BEVOR GEBAUT WURDE · Alle sechs Sprachnachrichten im Haus sind audio/webm (Opus). · Miss' Geraet: iPhone, iOS 18.7, WebKit. · Seit der Umstellung am 02.10. (neue Aufnahmen bevorzugen MP4) wurde KEINE EINZIGE neue aufgenommen. Ihr Problem betrifft also ausschliesslich die sechs alten Dateien -- und jede kuenftige aus einem Firefox, der nichts anderes kann. WAS ICH NICHT MESSEN KONNTE, und das gehoert dazu: Ob WebKit WebM/Opus abspielen kann, laesst sich auf diesem Rechner nicht nachsehen -- Playwrights WebKit startet hier nicht (libegl.dll fehlt). Die Vermutung „iPhones koennen kein WebM" ist begruendet, aber von mir nicht gemessen. GENAU DESHALB STELLT DIE LOESUNG DIE FRAGE NICHT. Statt zu raten, welches Geraet welchen Behaelter kann, legt der Server neben jede Sprachnachricht eine zweite Fassung in dem Format, bei dem sich seit zwanzig Jahren alle einig sind: AAC in MP4. Gibt es sie, wird sie abgespielt -- bei jedem, nicht nur auf iPhones. Kein Geraetename im Code, keine Liste, die altert. helfer-ffmpeg.mjs ffmpeg finden, umwandeln, drei Ausgaenge beim Hochladen nebenher, nicht davor: Die Nachricht wartet nicht auf ffmpeg toeneNachruesten() das Netz darunter -- fuer die sechs von frueher und fuer den Fall, dass eine Umwandlung einmal nicht geklappt hat ?form=mp4 dieselbe Route, dieselben Rechte; eine zweite haette dieselbe Sichtbarkeitspruefung ein zweites Mal gebraucht ffmpeg IST ABGESPROCHEN INSTALLIERT (Debian 7.1.5, auf Nachfrage freigegeben). Fehlt es, passiert nichts Schlimmes: Die Sprachnachricht geht wie bisher im Originalformat hinaus, und es steht EINMAL eine Zeile im Protokoll -- nicht bei jedem Hochladen. DREI ENTSCHEIDUNGEN, DIE NICHT NAHELIEGEND WAREN 1. `-movflags +faststart` IST NICHT KOSMETIK. Ohne es steht die Inhaltsuebersicht einer MP4 am ENDE. Das Abspielgeraet muss dann erst bis ans Ende lesen, bevor es anfangen kann -- genau das „laedt die ganze Zeit" aus Miss' Runde 5. Geprueft wird die Reihenfolge der Kaesten in der Datei, nicht die Zeile im Aufruf. 2. DAS ORIGINAL BLEIBT LIEGEN. Ohne `?form=mp4` kommt weiter die WebM. Sie ist das, was aufgenommen wurde; sie durch eine Umrechnung zu ersetzen hiesse, das Original wegzuwerfen. 3. EIN GEMEINSAMER LOESCHER. Zwei Stellen entfernen Anhaenge (Gespraech wegraeumen, Nachricht zuruecknehmen). Beide nahmen genau eine Datei -- ab heute waere bei jeder geloeschten Sprachnachricht eine m4a liegengeblieben, ohne Zeile, die auf sie zeigt. Dieselbe Luecke hatte ich gestern bei den Supportbildern gefunden; hier steht sie von Anfang an an EINER Stelle. ZWEI FUNDE DER PRUEFUNG, BEIDE MEINE EIGENEN · `anhang_datei` STAND NICHT IN DER ABFRAGE der Nachrichtenliste. Die Funktion, die auf der Platte nachsieht, bekam deshalb nichts und sagte brav „gibt es keine zweite Fassung" -- fuer JEDE Nachricht. Alles war gebaut, nichts kam an. Gefunden hat das die Pruefung, nicht das Lesen. · Mein erster Anlauf mass die Aufnahme ueber den Knopf -- und die ist seit dem 02.10. schon MP4, braucht also gar keine zweite Fassung. Die Pruefung wurde rot und hatte recht: Gemessen werden muss der Fall, den es bei Miss gibt. Jetzt nimmt sie ausdruecklich eine WebM auf. Dazu zweimal derselbe alte Tritt: ein Gegen-Apostroph in einem Kommentar INNERHALB eines Template-Literals. Der Server startet dann gar nicht. Steht jetzt als Warnung an beiden Stellen. GEPRUEFT -- pruef-chat-anhaenge 146 -> 163 ok Eine echte WebM/Opus-Aufnahme (31 972 Bytes) wird hochgeladen; die zweite Fassung entsteht von selbst und kommt als audio/mp4 heraus, mit „ftyp"-Marke, mit Accept-Ranges. ffprobe sagt: Original Opus, Zweitfassung AAC, 2,40 s gegen 2,46 s. Die Inhaltsuebersicht steht bei Byte 32, die Tondaten ab 1270 -- also vorne. Beim Loeschen gehen beide Dateien. Gegenproben: ein Bild bekommt keine zweite Fassung; eine halbierte Laenge waere aufgefallen; das Original bleibt unter seiner eigenen Adresse abrufbar. Der dritte Ausgang hat einen eigenen Zaehler: Fehlt ffmpeg, steht „KONNTE NICHT NACHSEHEN" mit Anleitung da -- nicht gruen und nicht rot. Und der Block raeumt hinter sich auf: Mein Probebild liess eine spaetere Pruefung rot werden, weil es die Gespraechsliste veraendert hatte. Eine Pruefung, die den Stand fuer die naechste verschiebt, ist schlimmer als keine. Dazu gruen: pruef-struktur 102 (92 Module) · pruef-ports 10 · pruef-gifs 17 · pruef-treffchat 114 · pruef-chat-optik · pruef-aufbewahrung 45. NUR DAS AGENTURHAUS? NEIN -- der Chat gehoert beiden Haeusern, und die Aenderung gilt fuer beide gleich. Sie aendert nichts an Sichtbarkeit oder Rechten: Wer eine Nachricht hoeren darf, hoert sie jetzt in einem Format, das sein Geraet kann. OFFEN BLEIBT DIE ANTWORT VON MISS. Ob es bei ihr jetzt laeuft, weiss nur sie -- deshalb steht ihre Meldung weiter offen und nicht auf erledigt. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
4324547eb3 |
Teilanfragen: Sprachnachrichten kommen jetzt auch auf dem iPhone an
Filipe: „zeurst schaust du mal ob es im system liegt dass miss, die modi,
keine sprachnachrichten hoeren kann oder ob es an ihr liegt weil bei allen
anderen klappt nur bei ihr nicht"
ES LAG AM SYSTEM.
WAS GEMESSEN WURDE (nicht vermutet)
1. An ihrer Rolle liegt es nicht. Der Weg `/workspace/api/chat/anhang/:id`
fragt drei Dinge: gibt es die Nachricht, ist die Person im Raum, hat sie
das Gespraech weggeraeumt. Keine Rollenpruefung. Gegen eine Wegwerf-
Datenbank gemessen: `anmelden admin=200 modi=200`, Anhang als modi
HTTP 200, 40018 Bytes -- genau wie als admin.
2. Sie ist in allen drei Raeumen mit Sprachnachrichten, geloescht_bis = 0,
alle sechs Tondateien liegen auf der Platte. (Live-Datenbank, nur
gelesen, auf einer Kopie, Kopie danach geloescht.)
3. Sie ist die EINZIGE im Haus mit Safari. Aus dem Caddy-Protokoll, ueber
IP und Minute mit ihren Protokolleintraegen abgeglichen: iPhone,
iOS 18.7, Safari 26.6.1. Alle anderen Geraete der letzten zwei Wochen:
Android-Chrome 3900 Anfragen, Windows-Chrome/Edge/Firefox 2646.
Neun von zehn iPhone-IP-Praefixen sind ihre.
4. DER FEHLER: Der Anhang-Weg beantwortete eine Teilanfrage
(`Range: bytes=0-1`) mit einer vollen HTTP 200 -- ohne `Accept-Ranges`,
ohne `Content-Length`, als `chunked`. Zum Vergleich dieselbe Anfrage an
`express.static`: HTTP 206, `accept-ranges: bytes`,
`content-range: bytes 0-1/2480`.
Safari verlangt fuer <audio> und <video> zwingend Teilanfragen und
verweigert die Wiedergabe bei einer 200. Chrome und Firefox nehmen die
ganze Datei klaglos. Bilder brauchen das nicht -- deshalb sah sie Fotos
und hoerte nichts, und deshalb fiel es sieben Tage lang nur ihr auf.
WAS GEAENDERT IST
A) EIN GEMEINSAMER AUSLIEFERWEG (server/helfer-ausliefern.mjs)
Im Haus gaben ZEHN Stellen eine Datei mit `createReadStream(pfad)
.pipe(res)` hinaus: Chat-Anhang, Chat-GIF, Dateiablage (ansehen und
laden), Material (ansehen und laden), Steckbriefbild, Buehnenbild,
Supportbild, Wissens-PDF. Nur eine davon zu reparieren hiesse, eine
Liste zu fuehren, welche Stelle schon richtig ist -- und die naechste
neue macht es wieder falsch. Alle zehn gehen jetzt ueber
`liefereDatei(req, res, pfad)`: `Accept-Ranges`, `Content-Length`,
206 mit `Content-Range`, 416 mit `bytes */groesse`. Mehrere Bereiche in
einer Anfrage werden absichtlich nicht bedient (das darf ein Server);
die Antwort ist dann die GANZE Datei, nie eine falsche Teilmenge.
WAS ES AUSSER SAFARI BRINGT, gemessen: Eine MP4-Sprachnachricht meldete
in Chromium ohne Teilanfragen 0,23 s statt 1,96 s Laenge -- der Kopf
einer MP4 steht am Ende der Datei. Eine Ogg-Datei meldete „Infinity"
statt 2,02 s. Und ein PDF-Betrachter springt jetzt zu einer Seite, ohne
die ganze Datei zu holen.
B) AUFGENOMMEN WIRD AAC IN MP4 (workspace/assets/js/chat.js)
Die Reihenfolge der Behaelter beantwortete bisher die Frage „was kann
DIESES Geraet am liebsten". Richtig ist „was koennen die ANDEREN
abspielen" -- die hoeren es.
Gemessen mit echten Aufnahmen aus echten Browsern, danach in beiden
Engines abgespielt:
Chromium nimmt auf: webm/opus, mp4(AAC), mp4(Opus)
Firefox nimmt auf: webm/opus, ogg/opus -- MP4 gar nicht
Beide spielen alle vier Behaelter vollstaendig ab (2 s rein, 2 s raus)
ZWEI FALLEN, die die Messung gezeigt hat:
- Ein blankes `audio/mp4` ist nicht AAC: Chromium meldet darauf
`audio/mp4;codecs=opus` zurueck -- MP4 aussen, Opus innen, fuer Safari
genauso unbrauchbar wie WebM. Deshalb steht `audio/mp4;codecs=mp4a.40.2`
VOR dem blanken `audio/mp4`.
- Firefox kann kein MP4 aufnehmen und faellt sauber auf WebM/Opus
zurueck. Kein Rueckschritt -- das ist der heutige Stand.
Die Pruefung nimmt jetzt im echten Browser ueber den echten Knopf auf,
und der Server erkennt: audio/mp4, 45583 Bytes, 2734 ms.
BERICHTIGT: In zwei Kommentaren stand „Safari und das iPhone koennen
nur MP4". Das stimmt nicht. An Miss' eigener Aufnahme nachgemessen:
Behaelter WebM, Mux-Programm „WebKit", Tonspur A_OPUS. Safari NIMMT
WebM auf -- ob es WebM abspielt, ist eine andere Frage.
C) EIN AUSWEG STATT EINER VERTROESTUNG (chat.js, chat.css)
Vorher stand im Fehlerfall „Sprachnachricht laesst sich gerade nicht
laden". Das war fuer Miss die ganze Auskunft, und es stimmte nicht
einmal: Die Datei kam an, ihr Browser konnte den Behaelter nicht.
„Gerade" heisst „gleich nochmal versuchen" -- bei einem fremden
Behaelter hilft kein Versuch mehr.
Jetzt wird unterschieden (Fehlercode 4 = Format, alles andere = Laden)
und daneben steht ein Weg, der wirklich zum Ton fuehrt: Herunterladen,
44 px hoch, in der Farbe der Blase, mit eigenem Vorlesewort. Nur im
Fehlerfall -- ein Knopf an jeder Sprachnachricht waere Unordnung fuer
alle, damit einer Person geholfen ist.
WAS JETZT NACHGEZAEHLT WIRD
- pruef-chat-anhaenge: 119 -> 146 Pruefungen. Dreizehn davon messen
Teilanfragen am Foto (0-9, -8, 5-, ueber das Ende hinaus, 416, mehrere
Bereiche, unverstandener Kopf) und vergleichen jeden Abschnitt BYTEWEISE
mit der vollen Datei -- eine 206 mit den falschen Bytes waere schlimmer
als keine. Drei Gegenproben legen dieselbe Messlatte an erfundene
Antworten (die alte volle 200, falsche Gesamtgroesse, falsche Bytes) und
muessen durchfallen. Neun weitere pruefen die Sprachnachricht selbst und
den Ausweg.
- pruef-wissen-neu: +6. Der Weg zur PDF war der EINZIGE der zehn, den nie
eine Pruefung abgerufen hat -- genau der, bei dem eine Umstellung
unbemerkt danebengeht. Jetzt beide Spielarten (ansehen und laden).
- pruef-struktur: +6. Wer kuenftig wieder `createReadStream(...).pipe(res)`
schreibt, bekommt einen Befund. Mit Gegenproben in beide Richtungen; die
Probetexte sind zusammengesetzt, sonst meldet die Wache ihre eigene
Begruendung als Fund. Pruefdateien sind ausgenommen, weil sie an niemanden
ausliefern -- dort ist ein Weg ohne Teilanfragen die Gegenprobe.
(Beim ersten Lauf hat die Wache sofort meine eigene Messdatei gefunden.)
WAS NICHT NACHGESEHEN WERDEN KONNTE
Ob iOS-Safari WebM/Opus ueberhaupt abspielt. Playwrights WebKit startet auf
diesem Rechner nicht (`icuuc77.dll`, auch nach Neuinstallation), und ein
iPhone habe ich nicht. Der dritte Ausgang: konnte nicht nachsehen. Deshalb
sind A, B und C drei Sicherungen hintereinander statt einer Wette auf eine.
GEPRUEFT (alles einzeln, kein Gesamtlauf)
pruef-chat-anhaenge 146 ok pruef-material 159 ok
pruef-wissen-neu 33 ok pruef-spenden 172 ok
pruef-struktur 85 ok pruef-support 63 ok
pruef-video 74 ok pruef-steckbrief 65 ok
pruef-galerie 26 ok pruef-eintrag-bild 24 ok
pruef-chat 63 ok pruef-chat-optik 62 ok
pruef-haus-trennung 100 ok
Die beiden Haeuser bleiben getrennt (pruef-haus-trennung, 100 ok). Der
Ausliefer-Weg gehoert beiden gleichermassen und traegt nichts Haus-
spezifisches; die Aufnahme betrifft faktisch nur Team Dogi, weil nur dort
der Mikrofonknopf steht („also nur die modis rechte linke hand und
dogfather").
NICHT VON MIR, SCHON VORHER ROT: pruef-gifs meldet zwei Fehler („das GIF
steht danach wirklich im Verlauf", „die Tafel geht zu"). Gegen den
unveraenderten Stand von HEAD nachgemessen -- dieselben zwei Fehler, mit
denselben Zahlen. Ein eigener Befund, kein Nebenschaden dieser Arbeit.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4503b1a475 |
Benachrichtigungen: nicht "Verbindung offen", sondern "sieht jemand hin"
Diene im Support (vor 5 Tagen): „Die Benachrichtigungen werden nicht
angezeigt, wenn neue Nachrichten reinkommen. Erst, wenn man die App
öffnet."
ERST GEMESSEN, WAS NICHT DAS PROBLEM IST. Am echten Bestand
nachgesehen: Diene HAT ein angemeldetes Geraet (Android, Chrome, seit
dem 29.09.), und alle zehn Geraete im Haus melden `fehler = 0`. An
der Zustellung liegt es nicht.
DANN NACHGESTELLT (pruef-abzeichen, Abschnitt 8):
Verbindung offen -> KEINE Benachrichtigung
Verbindung zu -> sie kommt
Genau sein Befund.
DER GEDANKE WAR RICHTIG, DIE FRAGE FALSCH. Im Quelltext stand:
if ((zuschauer.get(personId) || new Set()).size) continue;
und daneben die Begruendung -- „wer die Seite offen hat, sieht die
Nachricht ohnehin; ihm auch noch eine Meldung aufs Handy zu schicken
ist der schnellste Weg, dass er Benachrichtigungen abschaltet." Das
stimmt. Nur beantwortet `zuschauer` eine ANDERE Frage: ob eine
VERBINDUNG offen ist. Ein Handy mit der App im Hintergrund haelt sie
weiter -- und der Server hielt Diene fuer anwesend, waehrend sein
Bildschirm schwarz war.
DIE SEITE WEISS ES, DER SERVER NICHT. `document.visibilityState` ist
die einzige Stelle, die den Unterschied kennt. Also sagt sie es --
ueber einen winzigen Weg (`/api/chat/sicht`), beim Aufbau, bei jedem
Wechsel und mit `keepalive` beim Weggehen.
MIT VERFALL, und das ist der wichtige Teil: Ein Geraet, das
abstuerzt, im Funkloch steht oder eingefroren wird, sagt gar nichts
mehr. Ohne Verfall bliebe es fuer immer „sichtbar" und fuer immer
still. Wer nicht widerspricht, gilt nach zweieinhalb Minuten als weg
-- eine Meldung zu viel ist laestig, eine zu wenig ist genau der
Fehler, den Diene gemeldet hat. Dazu alle Minute ein Lebenszeichen,
solange die App vorn liegt.
EINE STELLE FUER DIE FRAGE. Sie wurde an zwei Orten gestellt:
`siehtZu()` und eine Abschrift mitten in `chatEreignis`. Die
Abschrift war die kaputte. Jetzt fragen beide dieselbe Funktion.
GEPRUEFT -- vier Lagen, und die zweite ist die wichtigere
Gegenprobe:
App liegt hinten -> Meldung kommt (war: nichts)
sieht wirklich hin -> KEINE Meldung (Absicht bleibt)
App weggelegt -> Meldung kommt wieder
gar keine Verbindung -> Meldung kommt
Ohne die zweite Zeile hiesse die Reparatur nur „jetzt kommt immer
eine", und das waere der schnellste Weg, dass jemand
Benachrichtigungen abschaltet.
UND EINE PRUEFUNG HAT DEN FEHLER MITGETRAGEN. pruef-anruf-klingelt
hielt den WORTLAUT der kaputten Zeile fest -- genau das, wovor ihr
eigener Kommentar drei Zeilen darueber warnt („Die Pruefung hat den
alten Wortlaut bestaetigt statt sein Verhalten"). Sie prueft jetzt
beides: dass gefragt wird, und dass die Frage die richtige ist.
pruef-abzeichen 26/0, pruef-chat, pruef-anruf 132/0,
pruef-chat-kanaele 81/0, pruef-anruf-klingelt 25/0, pruef-push-ziel
38/0, pruef-arten 28/0, pruef-reaktion 421/0, pruef-struktur,
pruef-zwischenspeicher 34/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d5c84c7608 |
Abzeichen am App-Symbol - und die Zahl gehoert zu einem Haus
Die kleine Zahl auf dem Symbol des Startbildschirms. Sie fehlte ganz; setAppBadge kam im Haus kein einziges Mal vor. ZWEI ENTSCHEIDUNGEN Sie zaehlt ungelesene Nachrichten und nichts sonst. Ein Abzeichen muss weggehen koennen: Nachrichten verschwinden, sobald man sie liest; eine ueberfaellige Aufgabe verschwindet nicht dadurch, dass man die App oeffnet. Eine Zahl, die dauerhaft dasteht, ist nach drei Tagen kein Hinweis mehr, sondern ein Fleck. Und sie hat EINE Quelle. Im Browser haengt sie an chatZahlZeigen() - der einen Stelle, an der die Zahl ohnehin gesetzt wird (beim Laden, aus dem Ereignisstrom, beim Lesen). Fuer die geschlossene App - wo das Abzeichen ueberhaupt erst etwas wert ist - reist dieselbe Zahl in der Benachrichtigung mit. Der Service Worker setzt sie nur, wenn eine dabei ist: Eine Aufgabenerinnerung mit "0" haette dem Chat sein Abzeichen weggenommen. DER FUND NEBENBEI Beim Herausloesen der Abfrage fiel auf, dass sie nie nach dem Haus gefragt hat - die Raumliste zwanzig Zeilen darueber tut es laengst. Gemessen: Eine Managerin schreibt DogFather an der Agenturwand an, sein Zaehler auf crew. springt von 0 auf 1. Seit dem 24.09. soll das nicht mehr sein. Aufgefallen ist es erst jetzt, weil dieselbe Zahl ab heute auf dem Startbildschirm steht - und eine Zahl, die etwas Falsches zeigt, ist schlimmer als keine. Behoben ueber hausWo(); die Meldung nimmt das Haus des Raums, aus dem sie stammt. GEPRUEFT server/pruef-abzeichen.mjs, 19 Messungen am echten Weg: ein nachgebauter Browser macht die Benachrichtigung mit seinem privaten Schluessel auf und liest die Zahl heraus. Mit Gegenproben - ohne Zahl kommt keine mit, NaN rutscht nicht durch, eine echte Sieben schon. Und Abschnitt 7 wird rot, sobald man die Hausregel wieder herausnimmt (nachgestellt). Zwei eigene Messfehler unterwegs, beide im Text festgehalten: eine Suche, die im Kommentar landete statt im Code (jetzt ueber jsOhneKommentar), und Aufrufe ohne Host-Feld - ueber 127.0.0.1 gibt es kein Haus, die Pruefung mass also eine Regel an einer Verbindung, die sie gar nicht kennt. helfer-push-aufmachen.mjs: das Entschluesseln stand als lokale Funktion in pruef-push-weg; zwei Abschriften waeren die, die auseinanderlaufen. Nachbarlaeufe gruen: push, push-ziel, push-weg (17 unveraendert), arten, portnummern, struktur, chat, chat-kanaele, chatkachel, anruf, haus-trennung, zwischenspeicher. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
5d89d108f9 |
Die Reaction: zusammen schauen, live, mit Kamera und Chat
Filipes Kurznotiz vom 28.09.2026, von links nach rechts:
Kachel sichtbar -> geschlossen -> Vorbereitung -> Wartebereich/
Chat -> Countdown -> LIVE -> Reaction + Gaeste + Chat + PayPal
-> Ende
DREI STAENDE, NICHT SIEBEN
„Wartebereich" und „Countdown" sind keine eigenen Zustaende, sondern
das, was „Vorbereitung" auf dem Bildschirm TUT. Drei Staende, die
sich gegenseitig ausschliessen, sind pruefbar; sieben, von denen sich
vier ueberlappen, sind es nicht.
DAS VIDEO LAEUFT NICHT UEBER DIESEN SERVER
Naheliegend waere: Der Host spielt ab, alle sehen seinen Bildschirm.
Das waere aus zwei Gruenden falsch. Rechtlich ist ein
weitergesendetes YouTube-Video eine oeffentliche Wiedergabe -- genau
die Sache, fuer die Kanaele gesperrt werden. Und technisch kostet es
Bandbreite und Qualitaet.
Jeder Zuschauer laedt das Video deshalb SELBST. Uebertragen wird nur
der Spielstand: Kennung, laeuft/pausiert, Sekunde. Das sind ein paar
Byte, jeder sieht es in voller Qualitaet, und alle sind auf derselben
Sekunde. Nachgefuehrt wird erst ab anderthalb Sekunden Abweichung --
ein Player, dem man jede Sekunde eine neue Position gibt, ruckelt
sichtbar.
DIE KAMERAS LAUFEN DIREKT VON MENSCH ZU MENSCH
Ueber denselben Weg wie die Anrufe im Haus (seit 18.09.), nur mit
mehr Empfaengern. Das hat eine Grenze, und sie ist gerechnet, nicht
geraten: Bei 360p und rund 350 kbit/s sind zwoelf Zuschauer etwa
4 Mbit/s Upload beim Host. Darueber schaltet die Sendung von selbst
auf Ton um -- wer keine Kamera mehr bekommt, hoert alles, sieht das
Video und kann schreiben. Ehrlicher als eine Verbindung, die stockt,
und sichtbar im Regiepult.
Heute sind es elf Menschen im ganzen Haus (gemessen: 1 admin, 1 hand,
1 linke, 4 modi, 4 gast). Die Grenze ist weit weg -- sie steht
trotzdem drin, weil sie sonst erst auffaellt, wenn es zu spaet ist.
DIE SEITE IST ANDERS GEBAUT ALS JEDE ANDERE IM HAUS
Ueberall sonst: Kacheln, Karten, Listen -- man liest, entscheidet,
geht wieder. Hier sitzt man. Eine Stunde, mit anderen, auf EINE
Sache schauend. Deshalb kein Raster, sondern ein SAAL: grosse Flaeche
fuer das Video, Kamerabilder als schwebende Fenster darueber, der
Chat als Schiene daneben. Die Seite scrollt nicht -- ein Video, das
beim Tippen im Chat nach oben rutscht, ist der schnellste Weg, dass
jemand aufhoert zu schreiben.
Fuer den Host ein REGIEPULT: vier senkrechte Regler nebeneinander wie
an einem Mischpult, darueber die Sendung, daneben Gaeste und
Anordnung, unten drei grosse Knoepfe. Es SCHIEBT den Saal, es deckt
ihn nicht zu.
Die Kachel traegt ihren Zustand als Farbe: grau geschlossen,
bernstein in Vorbereitung, rot auf Sendung. Keine Ton-Nummer -- der
Farbraum ist bei 46 voll, und sie braucht auch keine.
PAYPAL: EINE QUELLE
Der Knopf nimmt den Weg, der auf der Unterstuetzen-Seite hinterlegt
ist -- derselbe Eintrag, dieselbe Pflege. Ist dort nichts eingetragen
oder steht er auf unsichtbar, erscheint hier kein Knopf. Eine
geratene Adresse ist an dieser Stelle die gefaehrlichste aller
Abkuerzungen.
=======================================================================
ACHT FEHLER, DIE OHNE MESSUNG LIVE GEGANGEN WAEREN
=======================================================================
1. `data-live` WAR SCHON VERGEBEN. Die Draussen-Kachel bekommt es,
sobald Filipe auf Twitch sendet. Meine Regel haette ihr waehrend
jedes Streams die Farbe genommen -- genau dann, wenn sie wichtig
ist. Heisst jetzt `data-sendung`, und pruef-reaktion haelt beides
auseinander.
2. DIE INHALTSRICHTLINIE HAETTE YOUTUBE LAUTLOS GESPERRT. Die Datei
warnt an genau dieser Stelle selbst davor: Am 27.08.2026 hat
`frame-src 'none'` den Musik-Knopf stillgelegt -- der Knopf
reagierte, das Feld ging auf, und wo die Player sein sollten,
blieb es leer. Hier waere das Ergebnis eine schwarze Leinwand vor
Publikum gewesen. youtube-nocookie.com fuer den Rahmen (setzt keine
Werbekennungen), www.youtube.com fuer die Einbett-API,
i.ytimg.com fuer die Vorschaubilder.
3. KAMERA UND MIKROFON WAREN GESPERRT. Dieselbe Falle, vor der
index.js selbst warnt -- und die am 18.09. schon einmal zugeschlagen
hat. Die Ausnahme ist jetzt eine benannte MENGE statt eines zweiten
Sonderfalls, und pruef-kamera-richtlinie.mjs haelt sie GEGEN DEN
QUELLTEXT: Welche Seite laedt ein Skript, das getUserMedia
aufruft? Genau die muss drinstehen -- und keine andere. Eine
Liste, die abgeleitet wird, kann nicht veralten.
4. ZWEI ANRUFE AN DIESELBE PERSON. Zwischen `await kameraHolen()` und
dem Anlegen der Verbindung laeuft alles andere weiter; jeder Takt
sagte wieder „den kenne ich noch nicht". Der Empfaenger antwortete
auf beide Angebote, und die zweite Antwort traf eine Verbindung,
die laengst stand.
5. DAS ANGEBOT GING HINAUS, BEVOR DER EMPFAENGER ZUHOEREN KONNTE.
Gemessen:
[spur] an [3] reaktion_signal | offen: [2,1]
...
[spur] Strom auf fuer 3 Lenny
Die Anmeldung ist ein gewoehnlicher Abruf und sofort durch, der
Ereignisstrom eine stehende Verbindung. Der Host erfaehrt vom
Neuankoemmling also zuverlaessig, BEVOR der zuhoeren kann.
Die Richtung ist jetzt umgedreht: Wer bereit ist, BITTET um den
Anruf -- er ist der Einzige, der das sicher weiss. Dazu ein
eigener, schneller Takt (2,5 s) und eine Ruecknahme, wenn ein
Angebot bei niemandem ankommt.
6. EIN VIDEO MIT TON STARTET NICHT VON ALLEIN. `videoWidth` war 640,
das Bild kam also an -- und das Fenster blieb schwarz. Kein
Fehler, keine Meldung, es passiert einfach nichts. Die Kameras
starten jetzt stumm (stumm darf losgehen), ein Knopf schaltet den
Ton frei, und die erste Beruehrung der Seite tut es ohnehin.
7. DIE LADE AM HANDY GING NICHT AUF. Gemessen: ein 390x775 grosser
Saal mit 219 px Video und 556 px Leere darunter. Statt den Knopf
zu reparieren, ist die Lade weg -- unter Kopfleiste und Video
bleiben auf einem Telefon rund 550 px, das ist mehr Chat, als eine
Lade je zeigen wuerde. Ein Zustand weniger ist besser als ein
Zustand, der funktioniert.
8. `sendBeacon` KANN NUR POST. Beim Schliessen des Fensters wird ein
gewoehnlicher Abruf abgebrochen; mein DELETE waere nie angekommen,
und jeder haette zwei Minuten lang als anwesend gegolten.
Dazu drei Funde der Hauspruefungen, alle von mir verursacht:
17 Schriftgroessen unter der Lesbarkeitsgrenze von 11,5 px, elf
Maschinenworte ohne deutschen Satz, und ein Aufbewahrungseintrag ohne
Rechtsgrundlage.
=======================================================================
GEMESSEN
pruef-reaktion 74 Punkte, 0 Fehler (11 Abschnitte)
pruef-kamera-richtlinie 10 Punkte, 0 Fehler (neu, abgeleitet)
mess-reaktion beide Kameras kommen an, 640 px, laufen --
beim Zuschauer UND beim Host. Diese Messung
hat einen Rueckgabewert: Alles andere kann
gruen sein, und trotzdem sitzt jeder vor
einem schwarzen Rechteck.
pruef-handy 180 (vorher 177), pruef-notizen 79,
pruef-aufbewahrung 45, pruef-meldungen 8, pruef-css-klassen 33,
pruef-struktur 35, pruef-crew-adresse 161,
pruef-haus-trennung 100, pruef-start-ansicht 160 -- alle 0 Fehler.
|
||
|
|
bf3c7bd718 |
Einen Aushang loest jeder fuer sich -- fuer alle nur DogFather und die rechte Hand
Filipe: "jeder soll das fixierte individuel für sich lösen können aber
niemals so dass es sich für alle löst. außer dogfather macht es oder die
rechte hand dan ist es bei jedem weg ansonsten sollen alle anderen
rollen es individuell für sich lösen können. dogfather und die rechte
hand sollen die option haben für sich selbst oder für alle zu lösen."
BIS HEUTE GAB ES NUR EIN LOESEN, UND DAS GALT FUER ALLE. Wer den Knopf
sah, nahm damit jedem im Raum den Aushang weg; wer ihn nicht sah, musste
die Ansage vom Montag bis Freitag ueber jedem Gespraech stehen lassen.
JETZT ZWEI KNOEPFE AM AUSHANG:
"lösen" nimmt ihn nur bei MIR weg -- jeder darf das, ohne
Rueckfrage. Umkehrbar: Das Menue an der Nachricht holt
ihn mit "wieder oben" zurueck. Eine Rueckfrage vor etwas
Umkehrbarem lernt man wegzuklicken, und danach klickt man
auch die weg, die zaehlt.
"bei allen" nimmt ihn jedem weg -- nur fuer DogFather und die rechte
Hand, und MIT Rueckfrage. Er traegt die Warnfarbe des
Hauses: Zwei gleich aussehende Knoepfe nebeneinander
waeren die schlechteste Loesung, man traefe den falschen
und merkte es erst, wenn jemand fragt, wo die Ansage
hin ist.
EIN EINZIGER KNOPF MIT AUSWAHLFENSTER waere kuerzer und schlechter: Der
haeufige Fall ("weg damit, kenne ich") braeuchte dann zwei Klicks, und
der seltene, folgenreiche waere genauso weit entfernt wie der harmlose.
WAS NICHT IN FILIPES SATZ STEHT UND TROTZDEM NOETIG IST: Wer einen
Aushang SELBST angeheftet hat, darf ihn auch selbst wieder fuer alle
loesen. Sonst entsteht eine Sackgasse -- es haengen hoechstens drei,
und eine Gruppenleitung, die drei angeheftet hat und keinen abnehmen
darf, koennte nie wieder etwas anheften. Sie nimmt damit nur zurueck,
was sie selbst getan hat; das ist die Kehrseite derselben Erlaubnis,
keine neue.
TECHNISCH: eine Tabelle `chat_pin_aus` (Nachricht, Person). Kein
Eintrag heisst sichtbar -- nicht umgekehrt, sonst muesste beim Anheften
fuer jeden Teilnehmer eine Zeile entstehen und wer spaeter dazukommt,
saehe den Aushang nie. Der Verbund steht in der Abfrage und nicht im
Browser: Eine Liste, die alles schickt und im Browser gefiltert wird,
ist eine Liste, die alles schickt.
GEMESSEN -- server/pruef-pin-fuer-mich.mjs (neu), 37 Pruefungen, 0 Fehler:
- Der Modi nimmt sie bei sich weg. BEI DOGFATHER UND BEIM ZWEITEN
MODI HAENGT SIE WEITER -- das ist der Kern des Auftrags, und er
laesst sich nur mit mehreren Anmeldungen messen.
- Er holt sie zurueck; zweimal wegnehmen ist kein Fehler.
- Er kann NICHT fuer alle loesen (403), und die Absage sagt, was
stattdessen geht.
- Die rechte Hand loest fuer alle -- danach ist sie bei jedem weg.
- Wer selbst angeheftet hat, loest seinen eigenen (200) und den von
DogFather nicht (403).
- Das Nachruecken stimmt: Wer einen von dreien weggenommen hat, sieht
zwei, waehrend DogFather drei sieht.
- Drei Gegenproben: fremder Raum 404, ohne Anmeldung 401, erfundene
Nummer 404.
DIE PRUEFUNG MUSSTE AUF node:http UMGEBAUT WERDEN. Sie braucht
Team-Dogi-Rollen, die es nur auf der Crew-Adresse gibt -- und den
`Host`-Kopf laesst `fetch` nicht setzen (verbotener Kopf, undici
verwirft ihn stumm). Die Anfrage kam auf 127.0.0.1 an, waehrend
`Origin` die Crew-Adresse nannte; jede schreibende Anfrage bekam 403
"fremde_herkunft". Im ersten Lauf sah das aus, als sei die neue Route
kaputt.
AUSSERDEM IN DIESER RUNDE: Die drei Faecher im Chat (Personen, Gruppen,
Kanaele) waren 38 px hoch statt 44. Gefunden vom Handy-Rundgang bei
jeder Rolle -- aber erst, seit der Sammellauf auch die Zeile UNTER dem
Befund mitschreibt. Vorher stand dort nur "1 Befund".
Die Schemaaenderung auf einer Kopie der echten Datenbank durchgespielt:
72 Tabellen, keine Zeile und keine Spalte verloren, chat_pin_aus da.
pruef-chat 63/0, pruef-chat-optik 62/0, pruef-chat-kanaele 81/0,
pruef-treffchat 110/0, pruef-chat-neu 36/0, pruef-handy-teamdogi
0 Befunde, pruef-css-klassen gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
177c3c012a |
Die Bildschau und 2520 Farben statt 360
=== 1. BILDER OEFFNEN SICH MITTIG, MIT HUSKY UND HASE ===
Filipe: "wenn man bilder aufmacht, will ich dass die in der mitte sind.
beim hochformat soll links der husky sein und rechts der hase und beim
querformat soll oben dogfather und unten team dogi stehen da wo platz
ist ... ich will nicht dahin geschmissen sondern was richtig geiles mit
einem geilen hintergrund."
WAS VORHER PASSIERTE, und es war kein Fehler im Code: Der Klick fuehrte
auf die DATEI. Was man dann sah, war die eingebaute Bildanzeige des
Browsers -- schwarzer Grund, Bild oben links in der Ecke, auf seinem
Bildschirmfoto 1200 px Schwarz daneben. Eine Datei hat keine
Gestaltung. Wer Gestaltung will, muss eine SEITE zeigen.
Die Schau liegt jetzt UEBER dem Chat. Escape bringt einen dorthin
zurueck, wo man war, und das Gespraech laeuft im Hintergrund weiter --
ein zweiter Tab braeuchte eine eigene Seite, eine eigene Anmeldung und
einen eigenen Weg zurueck.
DER WEG IN DEN TAB BLEIBT TROTZDEM. Der Verweis hat unveraendert
`href`, `target` und `rel`; mittlere Maustaste, "In neuem Tab oeffnen"
und Herunterladen gehen wie seit jeher. Abgefangen wird nur der
gewoehnliche Klick -- und auch der nur, wenn die Schau geladen ist.
Wer Strg, Umschalt oder Befehl haelt, bekommt den alten Weg; das sind
die Griffe, die Leute seit zwanzig Jahren benutzen.
DIE BEGLEITER STEHEN DA, WO PLATZ IST -- und die Antwort darauf wird
GEMESSEN, nicht geschaetzt: nicht die Fensterbreite, sondern der Rest
neben dem Bild, nachdem es eingepasst ist. Eine Schwelle wie "ab
1100 px" waere fuer ein 3:4-Foto richtig und fuer ein 9:16-Foto auf
demselben Schirm falsch. Unter 170 px bleibt der Husky weg: Eine Figur,
die ein Streifen ist, steht besser nicht da.
Husky und Hase sind eigens verkleinert (2,1 MB und 1,0 MB werden 40 kB
und 32 kB) und bekommen weiche Raender -- ihr Hintergrund ist dunkel,
aber nicht durchsichtig; als Rechteck saehe man zwei Kaesten.
Der erste Anlauf spiegelte den Hasen, damit beide "nach innen" schauen
-- ein alter Reflex aus dem Plakatsatz. Auf dem Probebild stand danach
"Hasi Dog" seitenverkehrt auf seinem Hoodie. Schrift im Bild spiegelt
man nie.
pruef-chat-anhaenge bekommt 14 neue Punkte, darunter beide Formate und
zwei Gegenproben: Strg+Klick oeffnet die Schau NICHT (sonst hiesse "sie
geht auf" nur, dass der alte Weg verloren ist), und im Hochformat liegt
KEINE der Figuren ueber dem Foto.
NEBENBEFUND, den die Pruefung gefunden hat: Die Sprachnachricht war auf
165 px geschrumpft -- zu schmal fuer den Schieber. Ursache war keine
Aenderung an ihr, sondern eine Folge: Die Blase ist so breit wie ihr
breitester Inhalt, und seit die Handgriffe darunter Zeichen statt
Woerter sind (123 statt ueber 400 px), bestimmt das Abspielgeraet die
Breite selbst. Eine Reihe kuerzer zu machen hat einen Schieber schmaler
gemacht, drei Bildschirme weiter.
=== 2. DER FARBKREIS: HELLER UND DUNKLER ===
Filipe: "dieser kreis muss viel perfekter sein. ich will dass die leute
auch heller und dunkler aussuchen koennen ... so dass die leute viel
krassere moeglichkeiten haben."
WARUM DAS BIS HEUTE NICHT GING: Die 360 Toene liegen alle auf DERSELBEN
Leuchtdichte. Das war kein Zufall -- solange die Blase in der gewaehlten
Farbe stand, musste jede dieser Flaechen dieselbe Schrift tragen. Eine
hellere Farbe zuzulassen hiesse damals: irgendwo wird eine Nachricht
unlesbar.
SEIT DEM 25.09.2026 IST DIE BEDINGUNG EINE ANDERE. Die Blase ist fuer
alle dunkles Glas; der Ton ist Kante und NAME. Damit faellt die alte
Regel weg, und an ihre Stelle tritt: der Ton muss als Name auf dem
Blasengrund lesbar bleiben.
DIE ZAHLEN SIND GEMESSEN, NICHT GEWAEHLT. Ueber alle 360 Winkel, jeweils
der schlechteste Fall:
40 % schwarz 4,468 -- unter der Schwelle, faellt raus
34 % schwarz 4,555 -- ginge, aber ohne Reserve
30 % schwarz 4,619 <- die dunkelste Stufe
0 % 5,12 <- die Mitte, der alte Kreis
55 % weiss 9,6 <- die hellste Stufe
Sieben Stufen, 2520 Farben statt 360. pruef-chat-neu rechnet jede
einzelne nach -- die knappste hat 2,6 Prozent Reserve.
DIE ALTEN SCHLUESSEL BLEIBEN GUELTIG. "ton-214" heisst weiterhin genau
dieselbe Farbe; die Stufe steht als Zusatz dahinter ("ton-214-s6"). Wer
seit dem 23.09. eine Farbe traegt, traegt nach diesem Umbau dieselbe.
DIE PROBE IN DER MITTE ZEIGT ENDLICH, WAS MAN BEKOMMT. Dort stand eine
gefuellte Flaeche mit heller Schrift -- so sah die Blase bis heute frueh
aus. Jetzt steht dort derselbe Blasengrund und darauf der Ton als Name,
mit genau der Rechnung aus chat.css. Das ist nicht nur ehrlicher, es
macht die sieben Stufen erst moeglich: Eine gefuellte Flaeche muesste
Schrift tragen, und bei sehr hellen Toenen schafft das keine der beiden
Schriftfarben mehr (4,1 statt noetiger 7). Als Name auf dunklem Grund
ist derselbe helle Ton besonders gut lesbar (8,0).
Der Erklaersatz im Fenster war damit falsch geworden ("Alle Toene
leuchten gleich stark") und sagt jetzt, was stimmt.
ZWEI PRUEFUNGEN WURDEN GENAUER:
pruef-chat-neu mass den HINTERGRUND der Mitte -- eine Darstellung,
die es nicht mehr gibt. Sie misst jetzt die Schriftfarbe und rechnet
die Mischung nach. Dabei stolperte sie ueber eine dritte
Farbschreibweise: Chromium gibt `color-mix`-Ergebnisse als
`color(srgb 0.676 0.645 0.504)` zurueck. Die Zeile war rot, obwohl
die Farbe auf den Bildpunkt genau stimmte -- ein Fehlalarm, der
teurer ist als ein echter Befund, weil man am Aussehen sucht und der
Fehler im Lesegeraet liegt.
Und sie prueft nicht mehr 360, sondern 360 x 7 -- nur den Grundton zu
messen hiesse, sechs Siebtel ungeprueft auszuliefern.
Geprueft: pruef-chat-anhaenge (123), pruef-chat-neu (36),
pruef-chatkachel (40), pruef-chat, pruef-chat-ausbau (69),
pruef-chat-optik, pruef-tippziele (11), pruef-css-klassen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
c64732b16d |
Neuer Stil "Nachtprisma", Gespraeche anheften, und unten wieder Luft
Drei Sachen aus einem Bildschirmfoto-Satz.
=== 1. EIN ANDERER STIL, NICHT DIESELBE SPRACHE MIT NEUEN DETAILS ===
Filipe, zum dritten Mal an derselben Stelle: "du verstehst es wirklich
nicht ... ich will eine komplette aenderung vom aussehen. vom
hintergrund und von der grossen kachel. ich will einen ganz anderen
stil ... die leute sollen morgen nichts mehr wieder erkennen vom
aussehen her."
WARUM MEINE ZWEI ANLAEUFE DAVOR NICHT GEREICHT HABEN -- und das ist
kein Geschmacksstreit, sondern ein Fund:
Der Umriss des Chats kommt gar nicht aus chat.css. Er steht in
module.css, in einer Liste von 50 Klassen, und `.chat` ist eine davon:
Fase oben links, Kantenlicht, Punktraster, drei goldene Eckwinkel.
module.css wird NACH chat.css geladen -- und die Staerke des `:is(...)`
dort ist (0,2,0), weil `.gruppe[data-gruppe]` mit in der Liste steht.
Jede meiner Regeln war gleich stark und kam frueher. Deshalb stimmte
beides: "ich habe den Rand geaendert" und "der Rand ist derselbe". Ich
habe zweimal Details INNERHALB eines Rahmens geaendert, den ich nicht
angefasst hatte -- und den erkennt man zuerst.
Der neue Block steht als eine klar benannte Schicht am Ende von
chat.css, mit `.inhalt.chat-seite` -- eine Klasse mehr als module.css,
kein `!important` (das waere eine Tuer, die man nie wieder zubekommt).
ALT NEU
Fase oben links rundum 26 px weich
drei goldene Eckwinkel keine -- der Koerper traegt sich selbst
Punktraster drei weiche Lichter im Hintergrund
1-px-Rahmen ueberall kein Rahmen, Lichtkante innen
Gold als Leitfarbe Lavendel/Violett, Blasen wie gehabt
Kaesten nebeneinander Koerper mit Tiefe und farbigem Schatten
DIE LEITFARBE WIRD AN EINER STELLE GETAUSCHT, nicht an zwanzig. Im
ersten Anlauf habe ich zehn Regeln einzeln umgefaerbt und danach im
Bild gesehen, dass Suchfeld, "Neu", Zaehler und Fokusrahmen weiter
golden waren -- sie nehmen alle `--akzent` und `--rand`. Jetzt stehen
beide am `<main>` der Chatseite. Uebersicht, Kalender und Aufgaben
behalten ihr Gold; nur der Chat soll nicht wiederzuerkennen sein.
#b9a7ff UND NICHT #7a5cff, und das ist gerechnet, nicht gewaehlt: Die
Akzentfarbe ist hier auch FLAECHE unter dunkler Schrift (die
Ungelesen-Marke). Das satte Violett kommt dort auf 3,7:1 -- zu wenig.
Das helle auf 8,9:1, und als Schrift auf dunklem Grund genauso.
WAS UNANGETASTET BLEIBT: `--blasengrund`, `--blase-text`,
`--blase-leise`, `--namen-anteil`. An ihnen haengen die Messungen von
pruef-chatkachel (12 Kacheln) und pruef-chat-neu (360 Ringtoene). Ein
Stilwechsel darf eine Zusage nicht nebenbei aufheben.
pruef-chat-optik hat sofort einen echten Schaden gemeldet: Der neue
Stil nahm allen Blasen den Rahmen -- und damit auch den, mit dem eine
NICHT ABGESCHICKTE Nachricht markiert ist ("der Unterschied ist auch zu
SEHEN, nicht nur im Merkmal (Rand 0px)"). Genau dafuer steht die Zeile
dort. Der Warnton sitzt jetzt zusaetzlich im inneren Saum.
=== 2. GESPRAECHE ANHEFTEN ===
Filipe: "ich will dass man auch individuel jeder fuer sich auch in der
liste chats fixieren kann. auch mehrere nicht nur eins."
Drei Aussagen, und jede wird einzeln geprueft:
"fixieren" -> `fixiert_am` an der TEILNEHMER-Zeile; Angeheftetes
steht oben, darunter geht die gewohnte Reihenfolge
weiter.
"individuell" -> die Spalte haengt an der Person, nicht am Raum. Eine
Spalte an `chat_raeume` haette alles andere genauso
erfuellt und jedem im Raum das Gespraech oben
hingeklebt -- gemerkt haette man es erst, wenn sich
jemand beschwert. Die Gegenprobe prueft deshalb
ausdruecklich, dass es bei Luna weder markiert ist
noch nach oben rutscht.
"auch mehrere" -> keine Obergrenze. Ein Zeitstempel statt Ja/Nein
kostet dasselbe und beantwortet die Frage mit,
in welcher Reihenfolge mehrere stehen: zuletzt
angeheftet oben.
Die Nadel steht IMMER an der Zeile, nicht erst beim Ueberfahren -- am
Handy gibt es kein Ueberfahren (dieselbe Entscheidung wie am 23.09. bei
den Handgriffen), und eine Spalte, die mal da ist und mal nicht, laesst
die Namen daneben wandern. Sie liegt schraeg, solange nichts
angeheftet ist, und steht aufrecht, wenn doch -- das sieht man auch
ohne Farbe.
Der Zustand wird GESCHICKT, nicht errechnet (`an: true/false`): Ein
Schalter, der den Gegenwert selbst ausrechnet, kippt bei zwei schnellen
Klicks oder zwei offenen Fenstern in den falschen Zustand.
Die Karte ist seit heute die ZEILE und nicht mehr der Knopf darin --
im ersten Anlauf sass die Nadel sichtbar ausserhalb der Flaeche, wie
ein Knopf, der danebengefallen ist.
=== 3. UNTEN WIEDER LUFT ===
"schieb das bisschen hoeher bitte, weil das ist unten zu nah am rand."
14 px Polsterung. Sie geht nach INNEN (`border-box`), macht die Seite
also nicht laenger -- sonst waere das Schreibfeld wieder unter den
Bildrand gerutscht, und genau darum ging es am 09.09. schon einmal.
Geprueft: pruef-chat (neuer Abschnitt Anheften, 14 Punkte, alle gruen),
pruef-chat-optik, pruef-chatkachel (40), pruef-chat-neu (32),
pruef-chat-ausbau (64), pruef-chat-kanaele (81), pruef-chat-aufloesen
(126), pruef-chat-anhaenge (109), pruef-erwaehnung (129),
pruef-css-klassen, pruef-tippziele (11), pruef-lesbarkeit.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
9863645952 |
Die zwei Häuser sind getrennt -- und die Tür geht in beide Richtungen
Filipe: "ich will dass du zuerst die komplette site vn der workspace
seite trennst. da soll nichts verknüpft sein. wenn ich bei der einen
was mache soll nichts bei der anderen passieren. … es soll nur für
dogfather eine kachel geben wo er mit einem einfachen klick von der
einen auf die anderen seite kommt aber sonst garnichts."
Das kehrt die Entscheidung vom 10.09.2026 um ("getrennt wird das
AUSSEHEN, nicht der Bestand"). Wer den alten Kommentar liest, liest
einen überholten Stand -- das steht jetzt an jeder betroffenen Stelle.
WAS GEMESSEN WAR, BEVOR ETWAS GEBAUT WURDE
* Nur drei Module trennten nach Haus (Aufgaben, Bereiche, Dateien).
Chat, Kalender, Wissen, Material, Personenlisten und der Rest nicht.
* Die Trennung war EINSEITIG: nurHaus() griff nur auf crew.
* siehtModis() hebelte sie für DogFather auf der Agenturseite aus --
in seiner Gesprächsliste standen dort beide Häuser nebeneinander.
* Keine haus-Spalte in der Datenbank.
* Der Bestand kreuzte aber kaum: 0 von 86 Terminen gemischt, 0 von 7
Zweier-/Gruppengesprächen, genau EIN Kanal.
WAS JETZT DASTEHT
* Drei Rollenmengen in crew-adresse.js (crew / agentur / beide) und
hausVonRolle(); eine unbekannte Rolle bekommt null, kein Haus.
* Spalte `haus` an acht Wurzeltabellen, nachgetragen aus Belegen:
238 Zeilen eindeutig, die Wissensablage geschlossen der Agentur,
vier Restzeilen namentlich, der gemischte Kanal aufgelöst
(die zwei Scouts gehen heraus, die 7 Nachrichten sind alle vom
Team). Offen bleiben: null.
* nurHaus, hausBedingung und darfAnlegen gelten in BEIDE Richtungen.
* Der siehtModis-Durchgriff ist weg -- aber in DREI Fällen, nicht
zwei: Prüfadressen bekommen gar kein Haus und verhalten sich exakt
wie vorher. Die erste Fassung hatte das übersehen und 19 Prüfungen
umgeworfen, an denen nichts kaputt war.
* Kalender: getrennt, aber "belegt" bleibt (Filipes Entscheidung).
Die Blöcke tragen NUR Beginn und Dauer -- kein Titel, keine Person.
Gebaut als Gegenstück zur Liste (meine Termine MINUS die sichtbaren),
damit beide nicht auseinanderlaufen können.
* Die Wissens-Kachel ist auf der Team-Adresse weg UND die Route
antwortet dort mit 404 -- eine fehlende Kachel ist nur eine Bitte.
* Die Wechsel-Kachel für DogFather geht jetzt in beide Richtungen.
GEPRÜFT: pruef-haus-trennung 97 statt 81, 0 Fehler (vorher 7, alle
haben die alte Regel behauptet). Die neuen Abschnitte sind DORT
eingezogen statt in eine zweite Datei -- `pruef-haustrennung.mjs` hätte
sich von `pruef-haus-trennung.mjs` um einen Bindestrich unterschieden.
Dazu grün: haus-seiten, crew-adresse, chat, chat-kanaele,
kanal-besetzung, kalender, serien, treffchat, wissen-neu,
modi-checkliste, modi-katalog, rechtetafel, personen-liste, sicht,
verborgen, fremde-sicht, alle-wege.
NICHT VON MIR: pruef-treff (3) und pruef-kachel-universum (2) waren
schon vorher rot -- beim Treff auf dem Stand
|
||
|
|
7acd7a7674 |
Das Suchfeld nimmt wieder Eingaben, eigene Kanalnamen, Community in Kanälen
screen1, drei Teile. === 1. „bei suchen kann man nichts reinschreiben" === MEIN FEHLER VOM SELBEN TAG. Beim Popover-Umbau heute frueh hing die Liste am <body>, damit sie nicht hinter dem modalen Dialog verschwindet. Gemessen: Das Suchfeld war da, der Fokus landete nicht darin, ein getipptes Zeichen kam nicht an. DER GRUND IST DER FOKUS-KAEFIG. Ein Dialog aus showModal() sperrt den Fokus auf seinen eigenen DOM-Baum ein. Die Liste lag im Top Layer -- sichtbar und anklickbar, aber ausserhalb des Kaefigs. Klicken braucht keinen Fokus, Tippen schon. Deshalb fiel es niemandem auf: Die Liste stand da, sie filterte auf Knopfdruck, nur eine Eingabe kam nicht an. DIE LOESUNG WAR EINE KOMBINATION, die ich vorher fuer unmoeglich hielt. Im Dialog wurde die Liste vom clip-path der abgeschraegten Ecke abgeschnitten, draussen war sie nicht bedienbar. Ein POPOVER wird aber in die Top Layer gehoben und dort gezeichnet -- der Beschnitt des Elternteils erreicht es nicht mehr, waehrend der DOM-Baum (und damit der Fokus) der des Dialogs bleibt. Jetzt haengt sie wieder im Dialog UND ist ein Popover: bedienbar und unbeschnitten. Gemessen beides gegeneinander: „comm" getippt -> kommt an, filtert auf 1 Treffer; und die LETZTE Zeile der vollen Liste ist wirklich anklickbar (elementFromPoint trifft sie selbst, nicht den Dialog). Daraus ist pruef-suchfeld geworden -- der Fehler war von aussen nicht zu sehen, und gefunden hat ihn Filipe, nicht ich. === 2. „einen neuen namen erstellen den es noch nicht gibt" === `data-frei="ja"` war in wahl.js seit langem gebaut und wurde NIE GESETZT -- dieselbe Sorte Lueue wie `grund_min` heute Morgen. Jetzt gesetzt; der getippte Text erscheint als eigener Eintrag ganz oben. Der Server nahm bisher nur die neun festen Zustaendigkeiten. Jetzt auch einen eigenen Namen: Der SCHLUESSEL wird daraus abgeleitet („Technik & Ton" -> "eigen-technik-ton"), der ANGEZEIGTE Name bleibt wie geschrieben. Das Praefix ist kein Schmuck -- ohne es entstuende aus dem Namen „Community" derselbe Schluessel wie beim festen Thema, und der eindeutige Index lehnte ihn ab, obwohl der Kanal nicht existiert. Gemessen: genau dieser Fall antwortet jetzt mit 201. Der alte Kommentar sprach sich gegen freie Namen aus („der sichere Weg zu Clipping neben Clipping-Team"). Das Risiko bleibt und wird begrenzt: Derselbe Name zweimal ergibt denselben Schluessel und damit 409. === 3. „kanäle mit den leuten mit der community rolle" === Seit dem 19.09. nimmt `ohneAussen()` die Community aus den Listen aller anderen. Die Begruendung dort ist ausdruecklich: „Ein Zweier-Gespraech ist kein Kanal. Es hat keine Nachtruhe, kein Modi liest mit, und niemand koennte moderieren." Genau diese Begruendung laesst den Kanal offen. Die Sperre bleibt fuer GESPRAECHE und faellt fuer KANAELE -- `?fuer=kanal` an der Partnerliste, und nur fuer den, der Kanaele ueberhaupt aufmachen darf. Sonst waere der Parameter ein Weg, an `ohneAussen` vorbei Namen zu erfahren. Gemessen: DogFather sieht im Gespraech VanVan und Miss, im Kanal zusaetzlich Kessi und Tom (beide Community). Ein Modi bekommt die erweiterte Liste auch mit dem Parameter nicht. Gruen: pruef-suchfeld (8, neu), pruef-chat-kanaele (81), pruef-treffchat, pruef-chat-neu, pruef-freie-namen (32), pruef-nachfrage (53), pruef-css-klassen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
9f5dbb42e3 |
Support: melden mit Bild, und für die Leitung ein Eingang
Filipe: „da fehlt auch eine support kachel. die jeder sieht. jeder
benutzen kann. jeder kann da probleme von der seite melden und
hinweisen. fotos mit schicken mit einem text. … so einfach wie
möglich, will nichts kompliziertes oder zu viel. kurz und knapp …
bei dogfather und der rechten hand soll die kachel anders gebaut sein
weil die sind die die sich um die probleme kümmern."
WARUM DAS NICHT DER VORHANDENE MELDEWEG IST. Es gibt ihn schon
(hilfe.html) und er sieht aehnlich aus. Drei Unterschiede machen ihn
zu etwas anderem:
1. Er ist NICHT fuer alle -- in rechte.js steht
`["gast","hand","admin"]`. Modis, Creator, Scouts, Manager und
die linke Hand hatten gar keinen Weg, einen kaputten Knopf zu
melden.
2. Er kann keine Bilder. Bei „der Knopf tut nichts" ist ein
Bildschirmfoto die halbe Antwort.
3. Er ist bewusst schwer: strikter Wechsel, hoechstens drei offene
Faelle, ein Betreff. Richtig bei einem Vorfall zwischen
Menschen, zu viel fuer „das Datum steht falsch da".
Deshalb eigen und sehr kurz: EIN Feld, EIN Bild, fertig. Kein
Betreff, keine Kategorie, keine Dringlichkeitsstufe -- wer ein
Formular mit fuenf Feldern sieht, meldet den kleinen Fehler nicht,
und genau die kleinen erfaehrt sonst niemand.
DIE LEITUNG SIEHT ETWAS ANDERES: einen Eingang mit Zahlenband
(neu / in Arbeit / erledigt), drei Filtern und zwei Handgriffen --
„Ich kuemmere mich" und „Erledigt …". Zwei, nicht fuenf; eine
Zuweisung an eine Person und Prioritaeten waeren ein Ticketsystem
fuer zwei Menschen, die nebeneinander sitzen. Das Melde-Feld bleibt
auch fuer sie da, rutscht aber unter den Eingang.
Wer zumacht, schreibt einen Satz dazu -- der Melder sieht nur diesen
Satz, und ohne ihn weiss er nicht, ob etwas behoben wurde oder ob
niemand Zeit hatte. Beide Seiten bekommen eine Benachrichtigung.
UEBERNOMMEN STATT NEU ERFUNDEN:
* `dateiErkennen` aus workspace-chat.js -- EXPORTIERT, nicht
abgeschrieben. An ihr haengt die ganze Sicherheit der Uploads
(der Typ kommt aus den ersten Bytes, nicht aus Name oder
Content-Type), und eine zweite Fassung waere die, die beim
naechsten Dateiformat vergessen wird.
* Die zweigeteilte Sicht und `meldungFuer()` (gibt den Datensatz
oder null zurueck, nie true/false) aus dem vertraulichen
Meldeweg.
* Der Upload-Weg (express.raw, Text im Kopf, Ordner unter
DATEN_ORDNER, damit die Sicherungspruefung ihn findet).
DIE KACHEL BEKOMMT JEDER -- an EINER Stelle angehaengt: `bereicheFuer`
haengt sie an jede Rollenliste, statt sie in fuenf Listen
einzutragen. Genau so ist heute der Benachrichtigungs-Knopf auf 14
Seiten verschwunden. Dazu der Eintrag in rechte.js (ohne ihn
verschwindet die Kachel lautlos, `nurOffeneKacheln` filtert dagegen)
und in der Browser-Kachelliste fuer die Agentur-Rollen.
TON 44 GERECHNET, NICHT GEWAEHLT -- und dabei zweimal danebengelegen:
* Ich habe erst einen eigenen Modus in kachel-farben.mjs gebaut.
`tools/kachel-farbe-einzeln.mjs` gibt es aber seit dem 22.09. fuer
genau diesen Zweck. Meine Dopplung ist wieder weg.
* Von Hand hatte ich #bcdbff eingetragen. pruef-kachelfarben lehnte
es ab (Buntheit 0,060, verlangt sind 0,12) -- und das vorhandene
Werkzeug verteidigte es trotzdem, weil sein Abstand gut war. Ein
Werkzeug, das einen regelwidrigen Zustand haelt, weil er zufaellig
gut misst, behebt genau den Fehler nicht, fuer den es da ist.
Behoben: Zuerst die Regeln, dann der Abstand. Ergebnis #fd6401,
Abstand 0,0914 (engstes vorhandenes Paar: 0,0154).
DREI MESSFEHLER VON MIR, die wie schwere Befunde aussahen: `fetch`
verwirft den Host-Kopf (die Community kommt nur auf crew. herein),
die Community bestaetigt ihr Alter (`alter_ok`), und die Startroute
heisst /api/ich. Alle drei stehen in pruef-treff.mjs richtig.
Ein ECHTER Fehler kam dazu: support.html lud bereiche.js nicht, und
kopf.js stuerzte mit „Cannot read properties of undefined (reading
'LEITUNG')" ab -- sichtbar nur in der Browserkonsole. Und
pruef-css-klassen fand sofort, dass auch wahl.js fehlte.
Gemessen: pruef-support 45 Pruefungen, 0 Fehler (alle neun Rollen
kommen herein, jede sieht die Kachel, als Bild getarntes HTML wird
abgelehnt, eine fremde Meldung bleibt fremd, erledigt bleibt
erledigt). Dazu 24 Messungen am Bild in drei Groessen. Gruen:
pruef-kachelfarben (22), pruef-css-klassen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
03220b3924 |
Kanaele machen nur zwei auf
Filipe: "kanaele sollen auch nur die rechte hand und dogfather
aufmachen koennen."
Bis heute galt `fuehrtTeamDogi` -- und das schliesst die LINKE Hand
ein (WIE_RECHTE_HAND = {hand, linke}). Genau die zwei Worte im Auftrag
schliessen sie aus.
`fuehrtTeamDogi` SELBST WIRD NICHT ANGEFASST. Es haengt an elf
weiteren Stellen: Bereiche, Bretter, Sichtbarkeiten, wer einen Kanal
ueberhaupt sieht. Wer die Funktion aendert, aendert zehn Dinge, die
niemand verlangt hat. Stattdessen eine eigene Regel fuer genau diese
eine Frage -- dieselbe Bauweise wie `darfJedeNachrichtLoeschen` ein
paar hundert Zeilen weiter unten, die aus demselben Grund entstanden
ist ("zwei Rollen, woertlich die zwei aus dem Auftrag").
Nicht `istLeitung` uebrigens: Das schlösse Spicy Media ein, und
genannt wurden zwei Rollen, nicht drei.
AN EINER STELLE, NICHT AN ZWEIEN. Der Server lehnt ab, und die
Oberflaeche bietet es gar nicht erst an -- beide fragen dieselbe
Funktion. Ein Knopf, den man sieht und der dann mit 404 antwortet,
ist schlimmer als keiner.
WAS ES NICHT BETRIFFT: Wer in einem BESTEHENDEN Kanal die Leute
aendert. "Aufmachen" beantwortet diese Frage nicht, also bleibt es
dort beim Alten. Falls das auch enger werden soll, sagt Filipe es.
Gemessen, alle vier Rollen durchgespielt:
DogFather darf -> 201, Seite bietet es an
rechte Hand darf -> 201, Seite bietet es an
linke Hand darf NICHT -> 404, Seite bietet es nicht an
ein Modi darf NICHT -> 404, Seite bietet es nicht an
Dazu die Gegenprobe, dass die Absage nichts verraet: Eine erfundene
und eine echte Kategorie sehen fuer die linke Hand gleich aus (404 /
404). Sonst waere aus der Fehlermeldung abzulesen, welche Kanaele es
gibt. 9 Messungen, 0 Befunde. pruef-chat-kanaele: 81 geprueft,
0 Fehler.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
7a6749630c |
Das Rudel meint den ganzen Raum -- und die Kachelfarbe wird ein Ring
Zwei Auftraege vom 23.09.2026.
SCREEN 1: "da steht links immer noch der treff anstatt das rudel"
Und er hatte recht, auf eine Art, die niemand sehen konnte:
TREFF_NAME stand schon seit der Umbenennung auf "Das Rudel". Nur
setzt treffRaumId() den Namen ausschliesslich BEIM ANLEGEN -- der
Raum existierte laengst, also blieb die Zeile in der Datenbank auf
"Der Treff" stehen. Im Code das eine, auf dem Bildschirm das andere.
Dieselbe Falle stand direkt nebenan schon beschrieben ("drei Stellen,
von denen die dritte vergessen wird") -- die Vorsorge galt aber nur
fuer die Teilnehmer, nicht fuer den Namen. Eine halbe Selbstheilung
heilt die andere Haelfte nicht. Jetzt gleicht treffAngleichen() auch
den Namen ab; eine kuenftige Umbenennung ist wieder eine Zeile.
(IS NOT statt !=: Bei NULL ergaebe != in SQLite NULL, und die Zeile
bliebe unveraendert liegen.)
"und wenn wir da im chat @rudel machen will ich dass jeder in dem
chat markiert wird. nicht nur team ... und sehr wichtig ich rede nur
von dem chat wo die ganze community auch drin ist."
Bis heute erreichte der Ruf ueberall nur Team Dogi. Die Begruendung
stand im Code und war nicht falsch -- im Rudel-Raum sitzt die
Community. Genau das will Filipe jetzt, und zwar nur dort:
im Rudel-Raum -> alle, die drin sind
ueberall sonst -> Team Dogi, unveraendert
Was die alte Sorge entschaerft: RUFEN darf weiterhin nur Team Dogi --
kein Zuschauer kann alle wecken. Und die Nachtruhe gilt dort ohnehin.
darf_rudel folgt derselben Frage. Sonst entstuende ein stiller
Widerspruch: Ein Modi mit neun Zuschauern und ohne zweites
Teammitglied traefe mit @rudel neun Leute -- der Vorschlag beim
Tippen waere aber ausgeblendet. Die Funktion gaebe es, und niemand
faende sie.
Das Schild sagt jetzt die Wahrheit: "alle in diesem Chat" statt
"alle im Team". Stuende dort weiter das alte, waere es im Rudel-Raum
gelogen -- und zwar nach unten, also in die Richtung, in der man
leichtfertig drueckt.
Gegenprobe in pruef-erwaehnung: In der Testgruppe sitzen DogFather
und zwei Scouts; ein @rudel dort ruft NIEMANDEN. Waere die Regel
versehentlich im ganzen Haus aktiv, waeren die Scouts markiert.
"sonst nichts anfassen" ist damit gemessen, nicht versprochen.
SCREEN 2: "so eine art diagramm, wo man mit einem kreis herum gehen
kann und die farbe ganz genau selber auswaehlen kann"
Der Haken daran ist nicht die Optik. Die zwoelf Kacheln waren
GERECHNET, damit niemand sich unlesbar machen kann -- alle auf
derselben Leuchtdichte. Ein Farbkreis, der einfach den Farbton dreht,
wirft das weg: Ein gesaettigtes Gelb ist um ein Vielfaches heller als
ein gesaettigtes Blau, und helle Schrift ist darauf nicht mehr zu
lesen.
Der Ring ist deshalb KEINE neue Rechnung, sondern dieselbe in 360
Schritten statt in zwoelf. tools/chat-kacheln-rechnen.mjs --kreis
schreibt server/chat-kreis.js; buntest() und die Kontrastpruefung
darin gelten unveraendert. Ergebnis: ein Ring gleicher Helligkeit --
kein blendendes Gelb, kein abgesoffenes Blau. Das sieht ruhiger aus
als der uebliche Farbkreis, und genau das ist der Punkt.
Der Browser rechnet nichts. Er bekommt die 360 fertigen Farben und
legt sie in dieselbe Tabelle wie die Kacheln -- ab da ist "ton-214"
ein Schluessel wie "veilchen", und jede Stelle, die eine Farbe
nachschlaegt, funktioniert unveraendert.
Welche Kacheln neben dem Ring bleiben, wird ABGELEITET statt
aufgezaehlt: Grau hat keinen Farbton, Babyblau ist die eine helle mit
eigener Schrift. Nachgemessen liegen die elf bunten zwischen 0,0 und
2,4 von ihrer Ringfarbe entfernt, Grau bei 75,4 und Babyblau bei
192,9 -- zwischen 2,4 und 75 ist so viel Luft, dass die Schwelle
nicht knapp ist.
Gespeichert wird erst beim Loslassen. Wer einmal um den Ring fuehrt,
erzeugte sonst dreihundert Anfragen.
Gemessen (pruef-chat-neu, jetzt 32 Pruefungen, als Modi auf crew. mit
dem Finger): 265 px gross, aus 361 Farben gemalt, touch-action none
(sonst schiebt das Handy die Seite weg statt zu drehen), Drehen auf
drei Uhr ergibt genau Winkel 90, die Mitte zeigt exakt #675102,
vorgelesen als "Goldbraun, 90 Grad", in der Datenbank steht ton-90,
Pfeiltaste dreht ein Grad weiter. Und das eigentliche Versprechen:
alle 360 Toene tragen die Schrift der Blase, knappster Faktor 1,000.
Dabei zwei eigene Fehler, beide aufgeschrieben: Der erste Anlauf
wartete 30 Sekunden auf den Farbknopf -- am Handy weicht die Spalte
mit den Gespraechen zur Seite, sobald ein Chat offen ist. "Ist im
HTML" und "ist erreichbar" sind zwei Aussagen. Und die Schriftfarben
wurden an der falschen Klasse gemessen, was einen roten Haken an
einer heilen Stelle ergab.
Ausserdem: Das native confirm() beim Herausnehmen eines GIFs ist
weg -- meine eigene Abkuerzung vom Morgen. Gemeldet hat es
pruef-nachfrage, allerdings erst, nachdem der verlorene Backslash in
derselben Datei repariert war.
Zahlen: pruef-erwaehnung 122 (vorher 119), pruef-chat-neu 32
(vorher 19), pruef-nachfrage 46 bestanden.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
5e503463f5 |
Chat: die GIF-Kiste des Rudels -- und eine Luecke in der Sicherung
Filipe: "dan will ich auch dass man im chat auch sprachnachrichten und
gifts reinschicken kann. also nur die modis rechte linke hand und
dogfather."
ICH LESE "gifts" ALS GIFs -- die bewegten Bildchen -- und sage das
ausdruecklich, statt es stillschweigend anzunehmen. Im Zusammenhang
("im chat reinschicken", direkt neben Sprachnachrichten) passt nichts
anderes. Sollte er Geschenke gemeint haben, sagt er es, und dann baue
ich das.
EINE EIGENE KISTE STATT GIPHY ODER TENOR
----------------------------------------
Beide brauchen ein Konto und einen Schluessel und bekommen bei jedem
Tastendruck mit, wonach hier gesucht wird -- an eine fremde Firma, aus
einem Arbeitsplatz heraus, in dem sonst nichts nach aussen geht. Dazu
kosten sie ab einer Menge Geld. Beides steht quer zu dem, wie dieses
Haus gebaut ist.
Die Kiste laeuft auf demselben Server wie alles andere, kostet nichts
und wird mit der Zeit besser statt schlechter: Was darin liegt, hat das
Team ausgesucht. Zehn gute GIFs, die alle kennen, sind im Alltag mehr
wert als zehn Millionen fremde -- ein Katalog mit allem ist nicht mehr
Auswahl, sondern weniger.
HABEN WIR DAS SCHON? WIRD AM INHALT BEANTWORTET
-----------------------------------------------
Der Schluessel ist der SHA-256 der Datei. Ueber den NAMEN zu
vergleichen waere die naheliegende Abkuerzung -- und sie versagt genau
dort, wo Dateien "giphy.gif", "giphy(1).gif" und "download.gif"
heissen, also fast immer. Dasselbe Bild waere dreimal dieselbe Kachel.
Dasselbe GIF zweimal hineinzulegen ist deshalb KEIN Fehler: Es ist
drin, und genau das wollte man. Eine Absage waere formal richtig und im
Erleben falsch.
DAS WICHTIGSTE STUECK: ES WIRD KOPIERT, NICHT VERWIESEN
-------------------------------------------------------
Eine Nachricht zurueckzunehmen entfernt ihre Datei von der Platte. Laege
ein Kachel-GIF in demselben Ordner und mehrere Nachrichten zeigten
darauf, naehme das Zuruecknehmen EINER Nachricht das GIF fuer alle
anderen mit -- und in drei Gespraechen stuende ab da ein kaputtes Bild.
Das ist die Sorte Fehler, die erst Wochen spaeter auffaellt und dann
nicht mehr zu reparieren ist.
Deshalb liegt die Kiste in einem eigenen Ordner (chat-gifs/), und beim
Verschicken wird kopiert. Danach ist es ein ganz normaler Anhang: im
Verlauf, in der Suche, zuruecknehmbar, unter derselben Nachtruhe. Keine
zweite Sorte Nachricht mit eigenen Rechten und eigenem Loeschen.
Geprueft wird genau das: GIF hineinlegen, verschicken, aus der Kiste
nehmen -- und danach steht das verschickte immer noch im Gespraech.
"ALSO NUR" GILT AUCH HIER
-------------------------
Ansehen, hineinlegen, verschicken: alle drei nur fuer Team Dogi und
DogFather (istTeamDogi). Der Satz stand im selben Atemzug wie die
Sprachnachrichten; es gibt keinen Grund, warum er fuer das eine gelten
sollte und fuer das andere nicht. Gemessen auch am Knopf vorbei:
403/403/403.
AUGENSCHONEND -- HIER EINE ECHTE FRAGE, KEINE FORMSACHE
--------------------------------------------------------
Zwoelf gleichzeitig laufende Bildchen sind das Gegenteil von ruhig. Wer
"Bewegung reduzieren" gesetzt hat, bekommt deshalb STEHENDE Bilder: das
erste Einzelbild, im Browser auf eine Zeichenflaeche gemalt (kostet
keine zweite Datei), und es laeuft erst, wenn man es anfasst oder mit
der Tastatur darauf steht.
Fuer alle anderen laufen sie. Eine GIF-Auswahl, in der sich nichts
bewegt, ist eine, in der man nicht sieht, was man verschickt -- deshalb
steht dazu eine Gegenprobe in der Pruefung.
NEBENBEFUND, UND ER WIEGT SCHWERER ALS DIE GIFS
-----------------------------------------------
Weil die Kiste einen neuen Datenordner braucht, lief
tools/wiederherstellung-proben.mjs -- und meldete, dass der Ordner
"material" seit dem 22.09. NICHT gesichert wird. 2,4 MB
Materialbibliothek auf dem Server, nach einem Plattenausfall weg, ohne
dass die taegliche Meldung je etwas gesagt haette. Genau die Luecke,
wegen der diese Probe ueberhaupt gebaut wurde -- und sie hat sie
gefunden, weil sie die Ordner aus dem QUELLTEXT liest statt aus einer
gepflegten Liste.
Eingetragen. Danach frisch geholt und zurueckgespielt: 18 von 18 gruen,
"DIE SICHERUNG LAESST SICH ZURUECKSPIELEN" (vorher 3 Fehler).
Dabei war die Gegenprobe daneben selbst kaputt: Sie prueft, ob ein
erfundener Ordner als fehlend erkannt wird, und verlangte dafuer
`=== 1`. Das setzt voraus, dass sonst nichts fehlt. An dem Tag, an dem
wirklich etwas fehlte, wurde sie rot und zeigte damit auf sich selbst
statt auf den Fund -- zwei Meldungen, eine Ursache, und die zweite
lenkt von der ersten ab. Jetzt zaehlt sie die Differenz.
GEPRUEFT
--------
pruef-chat-anhaenge: 109 Pruefungen, 0 Fehler (vorher 86, davor 60).
pruef-chat, pruef-chat-aufloesen (126), pruef-chat-optik: gruen.
tools/wiederherstellung-proben: 18 von 18.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
2d14907d0d |
Chat: Sprachnachrichten -- und ein stiller Fehler, der jedes Foto betraf
Filipe: "dan will ich auch dass man im chat auch sprachnachrichten und
gifts reinschicken kann. also nur die modis rechte linke hand und
dogfather."
Dieser Commit macht die Sprachnachrichten. Die GIFs kommen als
naechstes -- ich lese "gifts" als GIFs und sage das ausdruecklich,
statt es stillschweigend anzunehmen.
AUFNEHMEN: TIPPEN, NICHT HALTEN
-------------------------------
Gedruecktbleiben ist der bekanntere Weg und der schlechtere: Wer beim
Sprechen verrutscht, verliert die ganze Aufnahme, und mit einer Hand am
Kaffee haelt niemand neunzig Sekunden still. Einmal tippen startet, das
Haekchen schickt, das Kreuz verwirft.
Drei Minuten Hoechstdauer, danach stoppt sie von selbst -- und schickt
NICHT von selbst ab. Wer die Grenze erreicht, hat gerade mitten im Satz
aufgehoert; das ungefragt zu verschicken waere die schlechteste Sekunde
dafuer.
Unter einer Sekunde wird gar nichts geschickt: Das ist ein Versehen,
kein Inhalt.
Die Aufnahmespur wird beim Beenden UND beim Verlassen der Seite
geschlossen. Ein Mikrofon, das offen bleibt, ist ein Vertrauensbruch,
auch wenn niemand zuhoert.
DREI BEHAELTER, WEIL DIE GERAETE DREI LIEFERN
---------------------------------------------
WebM/Opus (Chrome, Android), MP4/AAC (Safari, iPhone), Ogg/Opus
(Firefox). Wer nur einen nimmt, baut eine Funktion, die bei der Haelfte
des Teams stumm bleibt -- und zwar ohne Fehlermeldung.
DER BEHAELTER ALLEIN GENUEGT NICHT: WebM und MP4 tragen genauso gut
Video. Ein Video, das als "Ton" durchginge, landete in einem
Abspielgeraet ohne Bild -- es liefe, man hoerte etwas, und niemand
wuesste, dass die Haelfte fehlt. Die Erkennung sieht deshalb auf die
KENNUNG DER SPUR: Videospur -> abgelehnt, keine Tonspur -> abgelehnt.
Kein MP3: Kein Aufnahmegeraet im Browser erzeugt MP3. Es zuzulassen
hiesse, eine Tuer fuer Musikdateien aufzumachen, nach der niemand
gefragt hat.
"ALSO NUR" IST DER PUNKT
------------------------
Fotos und PDF darf jeder schicken, auch Creator -- das war eine
Entscheidung vom 09.09. und bleibt. Ton nicht. Geprueft wird in der
Route (istTeamDogi), nicht nur im Browser: Ein ausgeblendeter Knopf ist
eine Bitte, abgelehnt wird erst am Server.
Eigene Byte-Grenze fuer Ton (4 MB statt 12). Zwoelf Megabyte sind fuer
ein Foto richtig und fuer eine Sprachnachricht sinnlos -- das waeren
rund fuenfzig Minuten am Stueck.
Die Laenge kommt vom Absender und ist damit eine BEHAUPTUNG, keine
Messung; das steht so an der Spalte. Sie dient nur der Vorschau, bis
das Abspielgeraet die wahre Laenge kennt. Was schuetzt, sind die Bytes.
"FOTO"/"PDF" STAND AN VIER STELLEN
----------------------------------
Dieselbe Aufzaehlung in Gespraechsliste, Zitat, angehefteter Nachricht
und Benachrichtigung -- jede mit ihrem eigenen Fragezeichen-Doppelpunkt.
Mit der Sprachnachricht waeren es vier Aenderungen gewesen, und die
vierte ist die, die man vergisst. Jetzt anhangWort() an einer Stelle.
DER FUND: JEDES FOTO MELDETE "KEINE VERBINDUNG"
-----------------------------------------------
Beim Anfassen derselben Funktion aufgefallen: In `anhangSchicken` stand
seit dem 19.09. `const { nachricht } = e.daten;` -- ein `e`, das es
dort nicht gibt (gemeint war `ergebnis`). Die Zeile wirft, der `catch`
daneben faengt, und der Absender liest:
"Keine Verbindung -- der Anhang wurde nicht geschickt."
Das Foto war aber da. Es kam Sekunden spaeter ueber den Ereignisstrom
in den Verlauf, mit einer roten Meldung darueber, die das Gegenteil
behauptet -- und der getippte Begleitsatz blieb im Feld stehen, also
schickt man es noch einmal.
WARUM DAS VIER TAGE UNBEMERKT BLIEB, und das ist der lehrreiche Teil:
pruef-chat-anhaenge war die ganze Zeit gruen. Sie schickt mit `fetch`
an die Route -- der bequeme Weg, und er prueft den Server gruendlich.
Sie prueft aber nicht den Weg, den ein Mensch geht. Der Fehler lag
hinter der Bueroklammer, und dort hat nie jemand hingesehen. Dazu
fuehlt er sich wie ein Netzproblem an -- und Netzprobleme sucht niemand
im Programm.
Jetzt geht ein Block durch das Dateifeld selbst und sieht auf das, was
der Mensch danach sieht: steht dort eine Meldung, und ist das Feld
leer? Gegenprobe gefahren -- mit dem alten Fehler wieder eingesetzt
werden genau diese zwei Zeilen rot, mit dem Wortlaut von oben.
Uebernommen wird eine frisch geschickte Nachricht jetzt an EINER
Stelle (nachrichtUebernehmen), fuer Anhang und Sprachnachricht. Zwei
Fassungen waeren zwei Gelegenheiten fuer denselben Fehler.
AUGENSCHONEND
-------------
Kein Blinkpunkt waehrend der Aufnahme -- der ist genau das, was die
Hausregel ausschliesst. Der Punkt atmet langsam (1,8 s, 45 bis 100 %)
und steht bei prefers-reduced-motion ganz still; die laufende Zeit
daneben traegt die Auskunft ohnehin.
Die Farben der Sprachnachricht-Blase kommen aus `--blase-leise`, der
fuer DIESE Blase ausgerechneten leisen Schrift. Eine feste Farbe waere
dieselbe Wette, die am 22.09. beim Loeschknopf 1,91:1 auf Babyblau
ergeben hat.
GEPRUEFT
--------
pruef-chat-anhaenge: 86 Pruefungen, 0 Fehler (vorher 60).
Aufgenommen wird mit MediaRecorder im echten Browser ueber den echten
Knopf, mit Chromiums erfundenem Mikrofon. Damit prueft der Abschnitt
nebenbei das, was keine gebastelte Datei pruefen koennte: ob die
Erkennung im Server versteht, was ein Browser wirklich erzeugt
(gemessen: 35 829 Bytes audio/webm, 2743 ms).
* DogFather sieht den Mikrofonknopf, der Scout nicht
* der Scout schickt dieselbe Aufnahme an der Oberflaeche vorbei:
403, und nichts davon ist gespeichert
* ein Video im Ton-Behaelter: 415
* Laenge, Vorlesewort, Bedienbarkeit, preload=metadata, Breite
* "Sprachnachricht" steht in der Gespraechsliste statt einer leeren
Zeile
pruef-chat, pruef-chat-optik: unveraendert gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
28b0143166 |
Chat: "@rudel" ruft das ganze Team -- und nur die vier duerfen es
Filipe: "dan will ich auch dass nur die modis, rechte hand, linke hand
und dogfather, alle auch auf einmal markieren koennen im chat mit
einem, @rudel ,dann sollen alle eine benarichtigung bekommen."
DAS WAR EINE OFFENE FRAGE, UND ER HAT SIE BEANTWORTET
-----------------------------------------------------
In chat-erwaehnung.js stand seit dem 20.09. woertlich: "KEIN @alle. Es
waere in fuenf Minuten gebaut und ist der zuverlaessigste Weg, dass alle
die Benachrichtigungen abschalten -- und dann kommt auch die an, die
wirklich fuer einen bestimmten Menschen gedacht war. Wenn Filipe es
ausdruecklich will, gehoert dazu eine Entscheidung, WER es benutzen
darf; das ist eine Frage an ihn, keine, die ich hier beantworte."
Seine Antwort ist genau diese Entscheidung, und sie ist die Sicherung:
Team Dogi und DogFather duerfen rufen, sonst niemand.
WEN DER RUF ERREICHT: DAS TEAM IM RAUM, NICHT DEN RAUM
------------------------------------------------------
"Rudel" heisst das Team -- dieselben vier Gruppen, die auch rufen
duerfen. In einem Team-Kanal ist das jeder Anwesende, also "alle auf
einmal". Sichtbar wird der Unterschied im TREFF, und dort haette die
andere Lesart wehgetan: Dort sitzt die Community. Ein Ruf, der jeden
Zuschauer weckt, waere etwas anderes als der bestellte -- und beim
zweiten Mal haetten sie die Benachrichtigungen abgeschaltet.
WO WAS ENTSCHIEDEN WIRD
-----------------------
chat-erwaehnung.js bleibt ohne Abhaengigkeiten (die Pruefung soll sie
lesen koennen, ohne einen Server hochzufahren). Sie sagt nur, DASS
gerufen wurde; der Aufrufer sagt ihr, ob der Schreibende darf. Wer zum
Rudel gehoert, entscheidet workspace-chat.js ueber istTeamDogi().
Das Schluesselwort gewinnt gegen einen Menschen, der "Rudel" heisst.
Heute heisst niemand so -- aber das ist eine Tatsache von heute, kein
Gesetz. So herum verliert niemand eine Meldung (wer so heisst, ist im
Rudel dabei); andersherum haette ein einziger Zugang den Ruf ans Team
stillschweigend abgeschaltet.
istTeamDogi() NEU IN workspace.js
---------------------------------
Derselbe Ausdruck ("admin oder TEAM_DOGI_ROLLEN") stand dort dreimal
wortgleich: siehtModis, kanaeleFuer, kategorienFuer. Drei gleiche
Ausdruecke sind drei Gelegenheiten, dass einer beim naechsten
Rollenzuschnitt nicht mitgeht. Jetzt eine Stelle, die drei benutzen.
DIE NACHRICHT MERKT SICH DEN RUF (Spalte chat_nachrichten.rudel)
----------------------------------------------------------------
Beim Lesen muesste der Browser sonst wissen, ob der Absender es DAMALS
durfte. Er kennt nur dessen heutige Rolle -- wechselt jemand die Rolle,
verschwaende die Hervorhebung rueckwirkend aus einem Satz von vorletzter
Woche. Und es waere die zweite Rechnung ueber dieselbe Frage.
Vorgabe 0; alle alten Nachrichten haben kein Rudel gerufen, und das ist
keine Annahme, sondern eine Tatsache: Das Wort gab es noch nicht.
DIE MELDUNG SAGT, WAS LOS IST
-----------------------------
"X hat das Rudel gerufen", nicht "X hat dich erwaehnt" -- letzteres
stimmt beim Rudel nicht, und wer dreimal liest, dass er gemeint sei,
und jedes Mal merkt, dass es alle betraf, glaubt beim vierten Mal auch
dem echten nicht mehr. Auf DEMSELBEN Schalter wie die Erwaehnung: Ein
vierter Schalter waere der, den jemand abschaltet und der dann genau im
wichtigen Moment fehlt. Jeder Ruf steht im Protokoll (chat_rudel) --
"@rudel wird zu oft benutzt" soll eine Zahl sein koennen, kein Gefuehl.
DIE FARBE WIRD ABGELEITET, NICHT GESETZT
----------------------------------------
Eine Nachricht liegt in der Blase, deren Farbe ihr Absender AUSGESUCHT
hat -- siebzehn Moeglichkeiten. Eine feste Farbe darauf ist eine Wette,
und genau die habe ich am 22.09. beim Loeschknopf verloren (1,91:1 auf
Babyblau, gemessen, nachdem es live war). Die Marke nimmt deshalb
`--blase-text` -- die Schrift, die schriftFuer() fuer DIESE Blase mit
mindestens 7:1 ausgerechnet hat. Unterschieden wird ueber Form statt
Farbton: Toenung, Kante, Gewicht 700, ein Zeichen davor. In der
Auswahlliste darf es einen eigenen Ton haben -- sie liegt auf der
Flaeche des Hauses, deren Farbe feststeht.
DER VORSCHLAG ERSCHEINT NUR, WO ER ETWAS BEWIRKT
------------------------------------------------
In einem Zweier-Gespraech mit einem Creator ist ausser mir niemand aus
dem Team. `darf_rudel` fragt deshalb beides: darf ich, und sitzt hier
noch jemand aus dem Team. Dieselbe Ueberlegung wie beim eigenen Namen,
den die Liste auch nicht anbietet. Die Schranke beim Schreiben haengt
nicht daran -- wer es von Hand tippt, ruft eben niemanden.
GEPRUEFT
--------
pruef-erwaehnung: 119 Pruefungen, 0 Fehler (vorher 66).
Neu darin, und die zweite ist die wichtigere:
* der Modi ruft im Treff genau das Team -- die Liste wird aus der
Besetzung ABGELEITET, nicht abgeschrieben
* der Gast im selben Raum ruft NICHTS: kein Eintrag, kein Merkmal,
kein Vorschlag. Ohne diese Pruefung stuende Filipes "nur die
modis, rechte hand, linke hand und dogfather" bloss im Kommentar
* beide Fassungen der Regel (Server und Browser) an 14 zusaetzlichen
Proben nebeneinander, mit beiden Rechten -- samt Gegenprobe, dass
der Vergleich einen Unterschied ueberhaupt sehen kann
* am Bildschirm: der Ruf steht oben in der Liste, sagt daneben, was
er bedeutet, Enter setzt ihn ein, und im Satz ist er an Gewicht
und Rahmen erkennbar -- nicht nur an der Farbe
Beim Bauen gemessen statt vermutet: Ein Scout und ein Modi kommen gar
nicht in denselben Raum (403, Haeusertrennung) -- deshalb prueft der
Verhaltenstest im Treff. Und ein Gast meldet sich nur mit
Altersbestaetigung an (400 ohne).
Die Nachtruhe des Treffs wird in dieser Pruefung abgeschaltet (gleiche
Stunden = keine Nachtruhe). Sonst waere sie zwischen Mitternacht und
sechs rot und danach gruen -- ein Test, der die Wanduhr misst.
pruef-chat, pruef-treffchat (110), pruef-chat-kanaele (81),
pruef-chat-ausbau (64): alle unveraendert gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
60802170a1 |
B4 + B5: Loeschen heisst Loeschen, die Schrift wechselt mit, und Blau wird Babyblau
Die beiden Auftraege gehoeren zusammen, und zwar in dieser Reihenfolge:
Eine babyblaue Kachel ist HELL. Ohne mitwechselnde Schrift waere sie
unlesbar (1,63:1 gemessen). Erst B4 macht B5 moeglich.
B4a -- LOESCHEN HEISST LOESCHEN
"Geloeschte Nachrichten verschwinden vollstaendig - keine Spur, kein
'wurde geloescht'-Hinweis, bei niemandem, auch nicht bei DogFather."
Bis heute blieb die Zeile stehen: Text geleert, weg_am gesetzt, und im
Chat stand "Nachricht zurueckgenommen". Das war ausdruecklich so
begruendet ("ein Loch im Verlauf wirft mehr Fragen auf"). Das Argument
beantwortet aber eine andere Frage: Ein Hinweis "hier stand etwas"
MARKIERT die Stelle. Wer etwas aus Versehen schreibt, will es weg
haben und nicht unterstrichen.
Jetzt ein echtes DELETE. Vier Raender, an denen eine Spur bleiben
koennte, alle gemessen:
1. die Zeile selbst
2. chat_reaktionen (ON DELETE CASCADE - nachgesehen, nicht angenommen)
3. chat_erwaehnungen (ebenso)
4. letzte_am am Raum - wird neu gerechnet, sonst stuende er oben in
der Liste mit einem Zeitpunkt, zu dem es
nichts mehr gibt
Dazu: ein Zitat auf eine geloeschte Nachricht wird weggelassen; in der
Gespraechsliste steht kein Hinweis mehr; der Knopf heisst "loeschen".
Die 5 alten zurueckgenommenen Zeilen (Text bereits leer) raeumt eine
einmalige, wiederholbare Umstellung ab - mit Sicherung davor, und nur
wenn es wirklich etwas zu tun gibt.
B4b -- WER DARF WAS
"jeder nur seine eigenen - ausser DogFather und rechte Hand"
`darfJedeNachrichtLoeschen` = admin oder hand. NICHT fuehrtTeamDogi
(das schloesse die linke Hand ein) und nicht istLeitung (das schloesse
Spicy Media ein, die private Chats nicht einmal sehen darf). Das Recht
kommt vom Server ins Skript, nicht aus einer Rolle im Browser: chat.js
bekommt jeder, der die Seite oeffnet.
B4c -- DIE SCHRIFT WECHSELT MIT
"am besten schwarz auf hellen Kacheln - und weiss, wenn jemand eine
schwarze Kachel waehlt"
`schriftFuer(farbe)` waehlt zwischen zwei Paaren, gerechnet aus der
Leuchtdichte, mit denselben Schwellen wie das Rechenwerkzeug (7:1 fuer
den Text, 4,5:1 fuer die Fusszeile). Keine dritte Spalte in
CHAT_KACHELN, die jemand pflegen muesste. Flaeche und Schrift werden
im Browser in EINEM Griff gesetzt (blaseFaerben) - zwei Stellen waeren
irgendwann eine helle Kachel mit heller Schrift.
B4d -- DIE NAMEN
Der Name ist jetzt ein eigener Streifen mit Kante darunter, .84rem,
und der Rollenpunkt wird ein 3x14-Balken. Vorher stand er als erste
ZEILE in der Blase und las sich wie der Anfang des Satzes.
B5 -- BABYBLAU
"jedes normales blaues herz durch babyblaues herz ersetzen ... jeder
normale blaue farbe, sei es die kachel im chat oder emojis, nur
babyblau bitte."
* Herz: U+1F499 -> U+1FA75. Nicht geglaubt, sondern gemessen: 43,9 px
breit wie die anderen Herzen, ein Ersatzkaestchen waere 20,7. Die
vier vorhandenen blauen Herzen in der Datenbank wandern mit - sonst
waeren es vier Reaktionen, die ERLAUBT nicht mehr kennt: still weg.
* Kachel: neue, HELLE Kachel "Babyblau" mit dem Wert von --akzent.
Gemessen: Text 10,78:1, Fusszeile 4,87:1. Sie steht bewusst nicht in
der Rechnung des Werkzeugs (das rechnet elf Toene auf EINE
Leuchtdichte) - sie hat eine andere Leuchtdichte und dafuer ihre
eigene Schrift. Dasselbe Versprechen, anderer Weg.
PRUEFUNGEN
pruef-loeschen.mjs (NEU, 20/0): alle vier Raender, die vier Faelle
der Rechtegrenze (auch: die linke Hand darf NICHT), das babyblaue
Herz am laufenden Server, und dass der Satz "Nachricht
zurueckgenommen" nur noch in Kommentaren steht - mit Gegenprobe,
dass die Suche diesen Unterschied wirklich macht.
pruef-chatkachel.mjs (33/0): misst jede Kachel mit IHRER Schrift und
fragt dafuer dieselbe Funktion wie der Server. Neu: dass die
Schrift ueberhaupt wechselt. Die Leuchtdichte-Regel gilt jetzt fuer
die gerechneten Toene - das Versprechen dahinter loest die
Kontrastzeile darueber direkt ein.
Vier alte Pruefungen umgedreht, die den alten Zustand festgeschrieben
hatten: pruef-chat, pruef-chat-ausbau, pruef-chat-aufloesen,
pruef-chat-optik. Alle mit scharferer Messung als vorher (Zahl
davor/danach statt "ein Hinweis ist da").
Mitgelaufen und gruen: pruef-alle-sehen-es, pruef-treffchat (110/0).
Gesichert: workspace-vor-loeschumbau-20260922-233313.db
(946 KB, integrity_check ok, 111 Nachrichten, 49 Reaktionen).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
95da1345fc |
B9: In einen Kategorie-Kanal gehoert Team Dogi -- und alle davon
VanVans Befund, von Filipe weitergegeben:
* "Patrick und BananaStift (stifti) aus der Erwaehnen-Liste
entfernen -- sie stehen dort als SCOUT."
* "Die Modis zum Erwaehnen hinzufuegen."
* "Die Modis sehen den Chat Moderation auch gar nicht."
AN DER LIVE-DATENBANK NACHGEMESSEN, bevor etwas gebaut wurde:
Raum 3 kanal Chat-Moderation admin, hand, SCOUT, SCOUT, linke
Raum 7 kanal Der Treff admin, hand, 4x modi, linke, 3x gast
Raum 8 gruppe Dogi und Modis admin, hand, 4x modi, linke
Raum 9 gruppe Abmeldungen admin, hand, 4x modi, linke
Damit waren alle drei Punkte EIN Befund. Die Erwaehnen-Liste im
Browser zeigt genau `offen.teilnehmer`, also die Teilnehmer des Raums
(teilnehmerVon) -- eine zweite Quelle gibt es nicht. Standen dort zwei
Scouts und kein Modi, dann schlug sie Scouts vor, und die Modis sahen
den Kanal gar nicht. An der Erwaehnung selbst war nichts kaputt.
DIE REGEL
Ein Kategorie-Kanal gehoert Team Dogi: admin + TEAM_DOGI_ROLLEN
(hand, linke, modi), abgeleitet aus der einen Liste des Hauses. Der
Abgleich beim Blick in die Gespraechsliste heilt jetzt in BEIDE
Richtungen:
hinein jeder aktive Mensch aus Team Dogi, der im Raum NOCH NIE eine
Zeile hatte
hinaus jeder aktive Teilnehmer, dessen Rolle nicht dazugehoert
(raus_am, kein DELETE -- der Verlauf bleibt lesbar)
"NOCH NIE EINE ZEILE" ist der wichtige Teil: Wer ueber die
Mitglieder-Route bewusst herausgenommen wurde, hat eine Zeile mit
raus_am und wird NICHT zurueckgeholt. Ein Abgleich, der eine
Entscheidung von Hand beim naechsten Seitenaufruf ueberschreibt,
macht die Route wertlos -- dieselbe Ueberlegung wie bei
treffAngleichen(). Der Treff bleibt ausgenommen: Dort gehoert die
Community dazu.
Dazu dieselbe Schranke an beiden Schreibwegen (Kanal anlegen und
umbesetzen). `darfSchreibenMit` beantwortet eine ANDERE Frage -- "darf
ich diesen Menschen ueberhaupt anschreiben" -- und sagt bei einem
Scout zu Recht ja. Genau diese Luecke hat die zwei Scouts in den
Moderations-Kanal gebracht.
WARUM NICHT "NUR DIE ZUSTAENDIGEN"
Weil es die Zuordnung nicht gibt: `kategorienFuer` gibt JEDEM aus Team
Dogi ALLE Kategorien, eine Tabelle Person -> Kategorie existiert
nirgends. Eine Regel "nur die Zustaendigen" waere eine Liste, die
niemand pflegt. Wer einen engeren Kanal will, nimmt jemanden heraus --
und das haelt.
PRUEFUNGEN
pruef-kanal-besetzung.mjs (NEU, 16/0): baut die gemeldete Lage nach
(Scout drin, kein Modi), laesst den Abgleich darueberlaufen und
misst beide Richtungen. Vier Gegenproben: der von Hand Entfernte
bleibt draussen; ein Scout kommt auch ueber die Mitglieder-Route
nicht hinein; der Gast bleibt im Treff; und ein wieder
hereingeschmuggelter Scout fliegt beim naechsten Abgleich erneut
hinaus -- die Regel wirkt dauerhaft, nicht einmalig.
pruef-chat-kanaele.mjs (79 mit 3 Fehlern -> 81/0): Die Zeile "wer
nicht drin ist, sieht ihn nicht" hat den alten Zuschnitt
festgeschrieben -- sie prueft jetzt die schaerfere Grenze: wer
HERAUSGENOMMEN wurde, bleibt draussen, auch nach dem naechsten
Abgleich. Dieser Weg war bis heute ungeprueft.
Mitgelaufen und gruen: pruef-chat, pruef-treffchat (110/0).
Vor dem Ausliefern gesichert: workspace-vor-kanalregel-20260922-231409.db
(946 KB, integrity_check ok, 17 Personen, 37 Teilnehmerzeilen,
111 Nachrichten).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
80dee4d0c8 |
Highlights nach vorn, kraeftige Chatfarben, alle Farben in einer Kachel
screen1 -- HIGHLIGHTS AUF ANSCHLAGBRETTS PLATZ
Kein Tausch, sondern ein Aufruecken: Highlights nimmt die Stelle,
alle anderen wandern eine weiter. Inhaltlich stimmt das auch --
was die Leute selbst gemacht haben, steht vor dem, was ihnen
angesagt wird.
screen2 -- DIE CHATFARBEN SIND GERECHNET, NICHT GEGRIFFEN
Gemessen, was drinstand: Buntheit 0,002 bis 0,048, im Mittel 0,028
-- auf dem Bildschirm zwoelf Grautoene. Das lag nicht an fehlendem
Mut, sondern an der Fusszeile der Blase: Sie stand auf der leisen
Hausschrift, und gegen die darf die Flaeche kaum Farbe haben.
Deshalb ZUERST die Schrift (--blase-text/--blase-leise, eigene
Farben der Blase), DANN die Flaeche. Andersherum waere es der
Fehler vom selben Vormittag gewesen, als 27 von 31 Startkacheln
unlesbar wurden.
tools/chat-kacheln-rechnen.mjs liest beide Schriftfarben aus dem
CSS und rechnet daraus die hellste Flaeche, die sie noch tragen.
Ergebnis: Buntheit 0,072 bis 0,268, alle zwoelf auf DERSELBEN
Leuchtdichte -- also exakt demselben Kontrast (7,02 bis 7,13:1).
Zwei Anlaeufe waren falsch und stehen im Werkzeug begruendet:
- hoechste Buntheit nehmen, dann Kontrast pruefen. Musste
scheitern: gesaettigtes Gelb ist bei gleicher empfundener
Helligkeit viel heller als Blau.
- gleiche OKLab-Helligkeit statt gleicher Leuchtdichte. Das
Versprechen der zwoelf lautet "ueberall gleich gut lesbar",
und Lesbarkeit haengt an der Leuchtdichte, nicht am Eindruck.
WER NICHTS EINSTELLT, BEKOMMT TROTZDEM EINE FARBE. Gemessen an der
Live-Datenbank hatten vier von fuenfzehn eine gewaehlt -- der Chat
war fuer alle anderen einfarbig. Jetzt vergibt der Server einen der
elf bunten Toene aus der Personennummer, stabil. Schrittweite 4:
elf ist prim, also laufen alle Toene durch, und vier Schritte sind
131 Grad im Farbkreis -- aufeinanderfolgende Nummern landen so weit
auseinander wie moeglich. Mit id % 11 sassen zwei Nachbarn im
selben Gespraech magenta und rot nebeneinander.
Niemand verliert seine Wahl: veilchen, ziegel und moos sind die
drei gewaehlten und behalten ihren Farbbereich.
Dazu: Blasen mit 22px runden Kanten (nur die Ecke zur Person bleibt
spitz -- sie sagt, wer spricht), Lichtsaum oben innen, weicher
Schatten. Der Name hell und fett mit Rollenpunkt davor; er stand
auf leisem Grau mit 85 Prozent Deckung und war der schwaechste Text
der Seite, ausgerechnet der, der sagt, wer spricht.
ZWEI REGELBLOECKE FUER DIESELBE BLASE ZUSAMMENGELEGT. Der untere
gewann und hat an einem Tag zweimal Schaden angerichtet: Er stellte
die runden Kanten auf 16px zurueck (die Aenderung waere wirkungslos
ausgeliefert worden), und er mischte 26 Prozent Akzentfarbe in die
eigene Blase -- die hatte damit eine Farbe, die in CHAT_KACHELN
nicht vorkommt und die die Kontrastpruefung nie angesehen hat.
screen3 -- ALLE FARBEN DES HAUSES IN EINER KACHEL
tools/kachel-regenbogen.mjs leitet die 31 benutzten Toene ab
(bereicheFuer/zusatzBereicheFuer ueber alle Rollen und beide
Haeuser) und schreibt daraus einen Streifenverlauf mit harten
Kanten -- "nicht gemischt" war die eigentliche Ansage. Ein Verlauf
ergaebe Zwischentoene, die es im Haus nicht gibt.
Gegen einen deckenden Grund gemischt, nicht gegen --flaeche: Die
ist halbdurchsichtig, und durch 31 schmale Baender schien das
Buehnenbild -- sie verloren genau das, wofuer sie da sind.
Der Lesesaum ist staerker als auf den anderen Kacheln, und zwar
gemessen: Mit deren Werten kam der Text auf 4,45:1, fuenf
Hundertstel unter der Grenze. Gefunden hat das pruef-kachelfarben,
nicht der Blick -- 4,45 gegen 4,50 sieht man nicht.
pruef-buehne -- DIE ZAHL GEHOERT IN DIE BEDINGUNG
Die Abtastung wurde nachsichtiger (fremde Flaechen zaehlen nicht
mehr als Untergrund eines Textes). Das war richtig und hat einen
Fehlalarm beseitigt, der seit Tagen kam. Eine Lockerung kann aber
zu weit gehen, deshalb muss jetzt jeder gefundene Text in genau
einem von drei Toepfen landen: gemessen, ohne freien Untergrund,
oder aussortiert. Geht die Rechnung nicht auf, ist unterwegs etwas
still verschwunden.
Erster Anlauf war "mindestens 5 Stellen" -- und wurde auf
uebersicht.html sofort rot, weil die Seite nur vier Texte hat.
Eine feste Schwelle ist eine Rechnung von gestern; diese war keine
fuenf Minuten alt.
Gemessen: pruef-kachelfarben 22/0 (war 18, neu: die Willkommenskachel
traegt wirklich alle benutzten Farben, in beide Richtungen geprueft),
pruef-buehne 192/0, pruef-chatkachel 32/0, pruef-chat-optik 45/0,
pruef-chat 48/0, pruef-erwaehnung 69/0, pruef-start-ansicht 153/0,
pruef-treff 80/0, pruef-willkommen 67/0, pruef-treffchat 110/0,
pruef-css-klassen 30/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
9d086eccaf |
Chat: das Buehnenbild scheint durch, jeder Account bekommt seine Kachel
Hinter jeder Seite steht ohnehin eine Buehne (neun Szenen, fuer den
Chat die Lounge). Sie lag bisher hinter einer deckenden Flaeche --
vorhanden, geladen, unsichtbar. Sie durchscheinen zu lassen kostet
keine einzige Datei mehr, und auf der Adresse von Team Dogi kommt
damit von selbst deren eigene Fassung.
Das geht aber NUR, wenn der Text auf einer deckenden Kachel steht.
Sonst liegt Schrift auf einem Foto: an der dunklen Stelle lesbar, an
der hellen nicht, und beim Scrollen wechselt es. Filipes zweiter Satz
("die texte sollen immer in einer kachel sein") ist deshalb kein
Zusatzwunsch, sondern die Bedingung fuer den ersten.
Und jeder Account waehlt seinen Ton. Zwoelf Stueck, alle gleich
dunkel und gleich gesaettigt -- sie unterscheiden sich im Farbton und
in sonst nichts. Ein freier Farbwaehler klingt grosszuegiger und ist
die schlechtere Loesung: Mit ihm laesst sich Schwarz auf Schwarz
einstellen oder Neongelb, das allen anderen in die Augen sticht. Die
Kachel gehoert einem selbst, GESEHEN wird sie von allen anderen.
Gemessen: der schlechteste Kontrast liegt bei 13,9:1 (noetig 7).
Drei eigene Fehler beim Bauen, alle von der Pruefung gefunden:
1. Es gibt ZWEI Regeln fuer dieselbe Kachel (Grundform und
Feinschliff). Ich hatte nur die erste umgestellt, die zweite gewann
-- die eigene Kachel waere durchsichtig geblieben.
2. Die Pruefung las backgroundColor und pruefte den Alphawert. Eine
Kachel mit einem VERLAUF hat dort rgba(0,0,0,0); sie meldete
"durchsichtig" bei einer Kachel, die voellig deckt. Jetzt werden
zwei Bildpunkte verglichen, einmal mit und einmal ohne Buehnenbild
-- das misst die Sache selbst, nicht ihren Stellvertreter.
3. Dieselbe Pruefung suchte nur die rgba-Schreibweise. Chrome gibt
das Ergebnis von color-mix als color(srgb r g b / a) zurueck; der
Rueckfall war "Alpha 1", und sie meldete "deckt" bei einer
Flaeche, die durchscheint. Genau das Gegenteil.
pruef-chatkachel.mjs: 27 Pruefungen, mit eingebauter Gegenprobe (auf
der freien Flaeche MUSS sich etwas aendern, sonst misst der Vergleich
nichts). pruef-chat-optik und pruef-erwaehnung unveraendert gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
586eb51504 |
Profilfotos im Chat, rechte Hand zuerst, Karten lesbar
---- SCREEN 9: DIE FOTOS ------------------------------------------- Filipe: "da soll man im chat auch die profilfotos von den leuten sehen wenn die schon eins drin haben." ZWEI Luecken, beide an Stellen, wo ein Feld weggeworfen wurde: 1. Die GESPRAECHSLISTE bekam kein Bild. `teilnehmerVon` liest es aus der Datenbank, die Detailansicht nimmt es mit -- die Zeile fuer die Liste warf es weg. Folge: im offenen Gespraech ein Gesicht, in der Liste daneben ein Buchstabe. Vom selben Menschen. 2. Eine FRISCH GESENDETE Nachricht trug kein Bild. Der Verlauf beim Laden schon. Folge: Wer gerade zusieht, bekommt einen Buchstaben; wer neu laedt, ein Gesicht -- der Unterschied haengt nur daran, wann man geschaut hat. Der Buchstabe bleibt als Unterlage LIEGEN und wird nicht ersetzt: Laedt das Bild nicht, steht dort weiterhin etwas Sinnvolles statt eines kaputten Bildsymbols. Vier Stellen, ein Verhalten. ---- SCREEN 3: REIHENFOLGE UND AUSSEHEN ---------------------------- Filipe: "ich will dass hier wie ueberall die reihenfolge immer rechte hand und dan erst die modis." Die Abfrage sortierte nach `aktiv DESC, name` -- die ROLLE wurde nicht einmal mitgelesen. Die Seite konnte gar nicht wissen, wer rechte Hand ist; sie sortierte alphabetisch, und damit stand Diene vor Funny, weil D vor F kommt. Jetzt mit ROLLEN_SORTIERUNG -- derselben Regel, die auch Personenliste, Chat und Rechtetafel benutzen. "die kiste von rechte hand soll auch noch vieeeeeel krasser und spezieller aussehen ... der hintergrund von den kacheln soll auch viel krasser und geiler sein und so dass man texte und so besser erkennt. weil gerade ist es schwer lesbar." ZUERST DAS LESEN: Der Grund fuer die schlechte Lesbarkeit war der durchscheinende Untergrund -- die Karten lagen auf dem Buehnenbild, und ein Foto wird stellenweise hell. Sie bekommen jetzt eine DECKENDE Unterlage und erst darueber die Verlaeufe. Die Verlaeufe sieht man weiterhin, nur nicht mehr das Bild dahinter. DANN DAS BESONDERE: Die rechte Hand bekommt einen goldenen Ton, eine deutlich hellere Kante und eine schmale Leiste an der linken Seite -- man sieht den Rang aus zwei Metern, ohne ein Wort zu lesen. KEIN zweiter Bauplan: dieselbe Karte, dieselben Felder, nur ein Merkmal am Element. Zwei Karten zu bauen hiesse, jede kuenftige Aenderung zweimal zu machen. ---- EINE PRUEFUNG, DIE EINE POSITION FESTNAGELTE ------------------ `ok(leute[0]?.id === idMarina, "die Aktiven stehen oben")` wurde rot, sobald die rechte Hand nach vorn sortierte. Richtig wurde sie dadurch nicht: Die Aussage "die Aktiven stehen oben" hat mit Marinas Platz nichts zu tun. Jetzt prueft sie die EIGENSCHAFT (keine Pause vor einer Aktiven) -- eine Pruefung, die eine Position festnagelt, verbietet jede Umsortierung, auch die gewollte. GEPRUEFT: pruef-team-stufen 28/0 (zwei Aussagen mehr), pruef-erwaehnung 69/0 (zwei mehr: das Bild kommt in der Liste an, und wer keines hat, bekommt auch keines vorgegaukelt), pruef-css-klassen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
2a26a49f91 |
Mit "@" jemanden im Chat ansprechen
Filipe: "ich will das man die leute mit @ markieren kann im chat."
MARKIEREN IST KEINE FARBE, SONDERN EINE ANSPRACHE. Sie funktioniert
nur, wenn drei Dinge zusammen stimmen: Der Richtige ist gemeint, er
MERKT es, und man sieht es im Satz. Fehlt eines davon, ist es eine
Attrappe -- und zwar eine, die gut aussieht.
WER GEMEINT IST, ENTSCHEIDET DER SERVER. Der Browser schickt nur Text.
Damit wirkt ein von Hand getipptes "@VanVan" genauso wie eines aus der
Auswahlliste, und niemand kann jemanden ansprechen, der gar nicht im
Raum sitzt -- auch nicht ueber die Schnittstelle.
Die Regeln stehen in server/chat-erwaehnung.js, jede mit Begruendung.
Zwei davon sind keine Feinheit, sondern der Unterschied zwischen
brauchbar und laestig:
* Das Zeichen VOR dem "@" darf kein Buchstabe sein. Sonst piepst
jede E-Mail-Adresse im Chat jemanden an
("[email protected]").
* Das Zeichen DANACH auch nicht, und der laengste Name gewinnt.
Sonst spricht "@Tilikum" Tili an.
MAN MERKT ES AUCH OHNE OFFENEN RAUM. Eine Zahl in der Gespraechsliste
sagt "hier ist etwas" -- nicht, ob es an dich war. Wer morgens vier
Raeume mit Zahlen sieht, macht den lautesten zuerst auf, und dort
steht selten das, was auf ihn wartet. Jetzt steht ein "@" daneben.
UND DIE MELDUNG AUFS HANDY SAGT ES: "VanVan hat dich erwaehnt" statt
"Nachricht von VanVan". Als EIGENE Art, die sich getrennt abschalten
laesst -- wer den lauten Chat stumm stellt, will trotzdem wissen, wenn
ihn jemand direkt anspricht. Ohne Ausnahme von der Ruhezeit: Ein Anruf
wartet auf eine Antwort, ein "@Anna" nicht.
DIE AUSWAHL BEIM TIPPEN loest drei Dinge, die man sonst selbst wissen
muesste: wie die Person genau heisst, wer ueberhaupt im Raum ist, und
ob man sich vertippt hat. Tastatur zuerst (Pfeile, Enter, Tab, Escape).
Sie erzwingt nichts -- wer weitertippt, schreibt einfach weiter.
ZWEI RECHNUNGEN, EINE ANTWORT: Der Browser braucht dieselbe Aufloesung,
um sofort hervorzuheben. Genau dort laufen Dinge auseinander, und dann
haette die Seite jemanden hervorgehoben, den niemand benachrichtigt
hat. pruef-erwaehnung LIEST die Browserfassung aus der Datei und fuehrt
sie aus -- ein Nachbau wuerde pruefen, ob ich zweimal dasselbe
schreiben kann.
---- DABEI GEFUNDEN: "gelesen bis 999999" ----------------------------
Der Server nahm fuer den Lesestand JEDE ganze Zahl an. Wer einmal eine
Zahl hinter allem Vorhandenen schickte, sah in diesem Gespraech nie
wieder einen Zaehler und nie wieder ein @-Zeichen: Alles Kuenftige galt
als gelesen, bevor es geschrieben war. Das faellt niemandem als
Zusammenhang auf -- man merkt nur, dass "die Benachrichtigungen nicht
gehen".
Der Browser schickt heute immer die letzte gesehene Nummer, ist also
nicht der Grund. Aber eine Grenze, die nur davon lebt, dass der
Aufrufer sich benimmt, ist keine. Jetzt wird auf die juengste
Nachricht des Raums begrenzt -- abgeleitet, nicht geraten.
Gefunden hat es meine eigene Pruefung: Sie setzte zum Aufraeumen 99999
und wunderte sich danach, warum das frische "@" nicht leuchtete.
WOHER MAN ERFAEHRT, DASS ES DAS GIBT: Im Chat gibt es keinen
Hilfeknopf. Der Hinweis steht deshalb im Leersatz einer neuen Gruppe --
dort, wo man beim ersten Oeffnen ohnehin hinsieht, und nur ab drei
Leuten. In einem Zweiergespraech waere er Ballast.
GEPRUEFT: pruef-erwaehnung 67/0 (neu) -- 13 Regelfaelle ohne Server,
der Weg durch die Schnittstelle, das Zeichen in der Liste samt
Gegenprobe bei jemandem, der dabei aber nicht gemeint war, beide
Aufloesungen nebeneinander, und der ganze Ablauf am echten Bildschirm
bis "Enter waehlt und schickt NICHT ab".
Dazu pruef-chat 48/0, pruef-chat-optik 36/0, pruef-treffchat 110/0,
pruef-chat-kanaele 79/0, pruef-glocke 31/0, pruef-push 24/0,
pruef-anruf-klingelt, pruef-css-klassen, pruef-meldungen,
pruef-nachfrage, pruef-tippziele.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
26937dda16 |
Ein klingelndes Telefon haengt nicht mehr an einem einzigen Kanal
Filipe: "wenn vanvan rangeht und redet klingelt es immer noch bei mir
weiter, der anruf verbindet nicht richtig."
=== WAS DAS PROTOKOLL SAGT ===
17:04:52 anruf_start Person 1 (Filipe)
17:05:25 anruf_ende Person 4 (VanVan) 24 s
17:05:31 anruf_ende Person 1 (Filipe) 39 s
Sie WAR im Gespraech -- der Server hat sie 24 Sekunden als
Teilnehmerin gefuehrt. Das Ereignis "dabei" ist also verschickt
worden. Bei Filipe kam es nicht an: `tonAus()` ist das Erste im
`dabei`-Zweig, noch vor jeder Pruefung, und das Tuten lief weiter.
=== GEPRUEFT UND AUSGESCHLOSSEN ===
Raumzugehoerigkeit beide in Raum 1, bei keinem `raus_am` gesetzt
Verkabelung Server sendet mit `art: "anruf"`, chat.js reicht
an window.anrufEreignis weiter, anruf.js nimmt
entgegen -- alle drei Stellen stimmen
Tonsteuerung ein einziger Taktgeber, `tonAus` raeumt ihn;
kein zweiter Weg, der ihn neu startet
Ereignisstrom Keep-alive vorhanden, Kopfzeilen richtig
(no-transform, X-Accel-Buffering: no)
Service Worker hat gar keinen fetch-Handler, kann also kein
altes Skript ausliefern
teilnehmerVon vs.
teilnehmerFuerAnruf reicht nur durch, dieselbe Abfrage
Es geht unterwegs verloren, auf einem Weg, der von hier aus nicht
messbar ist: Ereignisstrom ueber Cloudflare, ein schlafender Reiter,
ein Neustart im falschen Moment.
=== ALSO NICHT WEITERSUCHEN, SONDERN DIE ABHAENGIGKEIT BESEITIGEN ===
Ein klingelndes Telefon darf nicht an einem einzigen, zerbrechlichen
Kanal haengen. Solange es klingelt, fragt der Anrufer jetzt SELBST
nach: "ist schon jemand dran?" -- alle zwei Sekunden an
`/workspace/api/anruf/:raum`, das es laengst gibt.
Der Ereignisstrom bleibt der erste Weg, er ist schneller. Das hier ist
das Netz darunter. Kommt das Ereignis an, hat die Nachfrage nichts
mehr zu tun und haelt von selbst an (sie prueft `anruf.beginn` und die
bekannten Teilnehmer).
Sie hoert an JEDEM Ende auf: beim Auflegen, wenn die Verbindung steht,
wenn das Ereignis doch ankommt, wenn der Anruf vorbei ist. Eine
Schleife, die weiterlaeuft, fragt sonst auf jedem Geraet, das je
telefoniert hat, alle zwei Sekunden nach einem Anruf, den es nicht
mehr gibt.
Alle zwei Sekunden und nicht jede halbe: Es klingelt hoechstens zwei
Minuten, das sind sechzig Abrufe.
=== ZWEI DINGE, DIE DIESE SUCHE ERST SO MUEHSAM GEMACHT HABEN ===
DAS PROTOKOLL KANNTE ANFANG UND ENDE, ABER NICHT DEN MOMENT DAZWISCHEN.
Die wichtigste Frage -- "ist sie ueberhaupt rangegangen?" -- war nur
ueber einen Umweg zu beantworten (ein `anruf_ende` mit ihrer Nummer).
Das ist eine Schlussfolgerung, keine Auskunft. `anruf_dabei` steht
jetzt drin, mit der Zahl der Beteiligten.
UND EINE PRUEFUNG WAR GRUEN, OHNE ETWAS ZU PRUEFEN. In chatEreignis
stand `(zuschauer.get(personId) || []).length` -- `zuschauer` haelt
aber Mengen, und eine Menge hat kein `length`. Der Ausdruck war IMMER
undefined, also immer falsch, also wurde nie uebersprungen: Wer die
Seite offen hatte, bekam zusaetzlich zur Nachricht auf dem Bildschirm
noch eine Meldung aufs Handy.
Der Kommentar drei Zeilen darueber warnt woertlich davor ("der
schnellste Weg, dass er Benachrichtigungen abschaltet"), und
`siehtZu()` weiter unten macht es mit `.size` richtig. Die Absicht
stand da, die Zeile tat das Gegenteil.
Meine eigene Pruefung hat das mitgetragen: Sie bestaetigte den alten
WORTLAUT statt sein VERHALTEN und war deshalb gruen. Genau die
Hausregel vom 01.09. -- ein gruener Haken sagt nur, dass die Bedingung
erfuellt war, nicht dass sie das Richtige geprueft hat. Jetzt prueft
sie auf `.size`.
GEMESSEN: pruef-anruf-klingelt 24/0 (vorher 17), pruef-anruf 114/0,
pruef-turn-wege 15/0, pruef-meldungen 8/0.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
7be85c265b |
Der Treff bekommt einen Chat -- mit Nachtruhe, ohne Telefon
Filipe, auf die Frage ob die Community einen Chat bekommen soll:
"eine geile mischung von punkt 2 und drei. mach es perfekt so das quasi
nach mitternacht bis morgens 6 uhr keiner schreiben kann damit auch die
privatsphaere beruecksichtig wird ueber nacht ... und die sollen nicht
anrufen koennen. nur schreiben."
Zur Auswahl standen "gar kein Chat", "nur mit Oeffnungszeiten" und
"offen wie im Team". Seine Antwort ist eine vierte, die nicht auf dem
Zettel stand, und sie ist die bessere.
1. WARUM DIE NACHTRUHE MEHR IST ALS EINE EINSTELLUNG
Sein Grund war Privatsphaere -- und zwar die der Leute, die moderieren.
Die Forschung zu ehrenamtlichen Moderatoren sagt genau das: Die beiden
meistgenannten Gruende fuers Aufhoeren sind ZU WENIG ZEIT und STREIT IM
TEAM. Ein Chat, der nachts um drei weiterlaeuft, erzeugt beides.
SIE GILT FUER ALLE, AUCH FUER DIE LEITUNG. Das ist die unbequeme
Entscheidung: Der bequeme Weg waere, DogFather auszunehmen. Aber wenn er
um halb vier schreibt, liest es jemand -- und wer liest, fuehlt sich
zustaendig. Eine Nachtruhe, von der die Leitung ausgenommen ist, ist
keine, sondern eine Bitte.
MODERIEREN GEHT WEITER. Verbergen, loeschen, herausnehmen sind keine
Nachrichten. Wer nachts etwas Schlimmes sieht, kann es wegnehmen -- er
kann nur nicht darueber diskutieren. Und der vertrauliche Meldeweg
bleibt offen: Er ist ein Fall mit einer Zustaendigkeit, kein Raum mit
dreissig Leuten.
GERECHNET IN ORTSZEIT, nicht in UTC. `getHours()` auf einem UTC-Server
haette den Chat im Sommer von 2 bis 8 geschlossen -- zwei Stunden
daneben, und nur denen sichtbar, die um diese Zeit wach sind. Dieses
Haus ist mit der Rechnung schon zweimal hereingefallen.
DER RIEGEL SITZT IM SERVER, nicht im Browser. Ein ausgegrautes Feld ist
eine Hoeflichkeit; wer die Adresse kennt, spricht die Schnittstelle
direkt an. Nachrichten UND Anhaenge werden abgelehnt -- ein offener
Anhangweg waere der Umweg, den jeder findet, der es einmal versucht.
2. KEIN TELEFON -- UND WARUM DAS EINEN EIGENEN RIEGEL BRAUCHT
Ein Anruf haengt in diesem Haus an der RAUMMITGLIEDSCHAFT, nicht an der
Rolle. Solange die Community keinen Raum hatte, war die Frage muessig.
Seit sie einen hat, waere Telefonieren erlaubt -- nicht, weil es jemand
entschieden haette, sondern weil es niemand verboten hat.
Der Riegel steht ganz vorne am Anruf-Router, nicht in den neun Routen
dahinter. Alle sieben Wege sind geprueft, einzeln.
3. DER FUND, DER DIE GANZE NACHTRUHE UMGANGEN HAETTE
Ein Gast konnte ein PRIVATES ZWEIER-GESPRAECH mit DogFather aufmachen.
Die Route antwortete mit 200 und legte den Raum an.
`ohneAussen` nimmt die Community aus den Listen ANDERER heraus -- damit
kein Creator einen Zuschauer anschreibt. Die Gegenrichtung kam nie vor,
weil die Chatseite fuer 'gast' gar nicht offen war. Seit heute ist sie
offen, und damit war die Erlaubnis da.
Ein Zweier-Gespraech ist kein Kanal: keine Nachtruhe, kein Modi liest
mit, niemand koennte moderieren. Aus "die Community bekommt einen Chat"
waere ungewollt "jeder Zuschauer bekommt eine Standleitung zu
DogFather" geworden.
GEFUNDEN HAT ES DIE PRUEFUNG, NICHT DAS LESEN -- und zwar in dem Moment,
in dem ich zwei Dateien weiter selbst vor genau dieser Sorte Erlaubnis
gewarnt hatte.
4. ZWEI TOTE WEGE, EINER DAVON MEINER
pruef-community-sicht sucht nach sichtbaren Wegen, die ins Leere
fuehren. Sie fand zwei:
a) "Bei dir klingelt nichts" -> anruf-probe.html. Der Hinweis von
heute Vormittag, und die Seite steht einem Gast ausdruecklich NICHT
offen. Mein Fehler, und einer, der jedem naechsten Hinweis genauso
passiert waere.
AN DER WURZEL BEHOBEN: Die Hinweise pruefen jetzt auch die ROLLE
(`darfSeite`), nicht nur die Adresse. Das ist der 15.09. noch
einmal, eine Ebene tiefer -- damals die Adresse, diesmal die Rolle,
und dieselbe Lehre: Die Hinweise sind eine DRITTE Stelle neben
Seiten und Schnittstellen.
b) Der Verweis "Kalender" im Tagesblick. Steht fest im HTML, fuehrt
fuer die Community ins Leere -- und zwar SCHON VOR den Aenderungen
dieses Tages. Aufgefallen nur, weil (a) daneben stand. Der Weg
wird jetzt abgeleitet: Wer die Kachel hat, hat den Weg.
5. DIE PRUEFUNG LAEUFT ZWEIMAL
Die Nachtruhe laesst sich nicht in EINEM Lauf in beiden Zustaenden
pruefen -- die Zeiten werden beim Laden gelesen, und ein zweiter Server
braeuchte denselben Port. pruef-treffchat ruft sich deshalb selbst noch
einmal auf, mit einem Fenster, das jetzt gilt. Dieselben Pruefungen,
andere Lage.
DIE UHR WIRD NICHT GEFAELSCHT. Verschoben wird die GRENZE, nicht die
Zeit -- eine Pruefung, die an der Systemzeit dreht, faelscht danach auch
anderes mit und ist nur nachts gruen.
6. WAS SICH NEBENBEI GEAENDERT HAT
- pruef-treff war SCHON VORHER ROT (8 Fehler): Sie erwartete sieben
Kacheln fuer die Community, es waren gestern Nacht schon zehn. Feste
Zahlen, Rechnung von gestern. Jetzt abgeleitet -- 72 Pruefungen statt
66, alle gruen.
- Ein 404 bei jedem Seitenaufruf der Community: `anruf.js` holte die
Verbindungsadressen, bevor es wusste, wer fragt. Der Browser
protokolliert das, BEVOR JavaScript abfangen kann -- also darf die
Anfrage gar nicht erst gestellt werden. `/api/ich` sagt es jetzt
vorher. Ein Fehler, der immer kommt, macht den naechsten echten
unsichtbar.
- Reaktionen (Daumen) bleiben nachts erlaubt. Ausdruecklich, mit
Begruendung im Code: Ein Daumen ist keine Nachricht, er loest keine
Meldung aus und kann keinen Streit anfangen. Eine Luecke ohne
Begruendung wird beim naechsten Durchsehen entweder geschlossen oder
uebersehen -- beides falsch.
GEMESSEN: pruef-treffchat 108/0 (neu, laeuft zweimal), pruef-treff 72/0
(vorher 66 mit 8 Fehlern), pruef-chat gruen, pruef-rechtetafel 19/0,
pruef-community-sicht gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
0137ced9c2 |
Anruf: die Ruhezeit hat ihn verschluckt
Filipe um 23:44 Uhr: „sie bekommt nur eine benarichtigung das eine
neue nachricht ist aber sonst nichts irgendwas laeuft da gewaltig
schief."
Serverseitig war ALLES in Ordnung, und das war das Verwirrende: Der
Anruf kam an, der Raum stimmte (Dogfather + VanVan), sie war
angemeldet, sie hatte ein Geraet, der neue Code lief. Trotzdem klang
nichts.
Die Ursache war eine einzige Zeile in workspace-push.js, die ich beim
Bauen des Anrufs nie gesehen hatte:
if (art !== "test" && istRuhezeit()) return { grund: "ruhezeit" };
RUHE_AB = 22. Es war 23:44. Die Benachrichtigung wurde gar nicht erst
verschickt -- ihr Geraet konnte nicht klingeln, weil es nichts zu
klingeln gab.
Fuer eine Aufgabenerinnerung ist die Regel genau richtig: Die schickt
der Server von sich aus, weil eine Frist naeher rueckt. Ein Anruf ist
das Gegenteil -- ein Mensch drueckt gerade auf den Hoerer und wartet.
Ein Telefon, das nachts stumm bleibt, ist kein Telefon.
ANRUFE SIND JETZT EINE EIGENE ART. Zwei Dinge auf einmal:
* Sie umgehen die Ruhezeit.
* Und sie lassen sich getrennt abschalten. Vorher gingen sie als
„chat_nachricht" hinaus -- wer die Benachrichtigungen fuer den
Chat abstellt, haette damit auch Anrufe abgestellt, ohne es zu
wissen. Das sind zwei verschiedene Entscheidungen.
Wer nachts seine Ruhe will, schaltet „Jemand ruft an" ab. Eine
Entscheidung, die man selbst trifft, statt einer Regel, die man nicht
kennt.
Geprueft: server/pruef-anruf-ruhezeit.mjs, 6 Pruefungen. Sie stellt
die Ruhezeit auf „rund um die Uhr", damit sie nicht tagsueber gruen
und nachts rot ist, und unterscheidet am RUECKGABEGRUND: "ruhezeit"
heisst haengengeblieben, "keine_geraete" heisst durchgekommen. Dazu
die Gegenprobe, dass eine erfundene Art durchfaellt -- sonst waere
„nicht ruhezeit" auch fuer etwas wahr, das nie verschickt wird.
pruef-anruf weiterhin 100, 0 Fehler.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4ea7b37333 |
Anruf: "sie kriegt nur eine Benachrichtigung aber keinen Anruf"
Filipe, gerade gemeldet. Es waren ZWEI Fehler, und beide erklaeren
genau das, was er gesehen hat.
--- 1. Die Benachrichtigung sagte nicht, dass es ein Anruf ist ------
Gemessen kam bei ihr an:
Nachricht von [object Object]
(kein Text)
`nachricht.von` ist beim Klingeln ein OBJEKT (`{id, name}`) und keine
Zeichenkette; einen `text` gibt es bei einem Anruf gar nicht. Moeglich
wurde beides, weil die ART des Ereignisses die Benachrichtigung nie
erreichte: `chatEreignis` nimmt sie als vierten Parameter entgegen,
reichte sie aber nur in den Ereignisstrom weiter. Fuer den Push galt
jedes Ereignis als Chatnachricht -- auch das Klingeln.
Jetzt steht dort "Filipe ruft an" / "Tippen zum Rangehen", und beim
Tippen landet man im richtigen Gespraech.
--- 2. Und dort klingelte es dann trotzdem nicht --------------------
Das Klingeln lief ausschliesslich ueber den offenen Ereignisstrom. Wer
zusieht, hoert es. Wer die Seite NICHT offen hat, bekommt die
Benachrichtigung, tippt darauf, die Seite laedt -- und bleibt still.
Das Ereignis war vorbei, bevor sie da war.
Der Anruf funktionierte damit ausgerechnet fuer die nicht, fuer die
die Benachrichtigung ueberhaupt gebaut wurde.
Neu: `GET /workspace/api/anruf/offen` -- beim Laden fragt die Seite
einmal nach, ob in einem ihrer Raeume jemand wartet. Nur was noch
klingelt (45 s), nur Raeume, in denen die Person drin ist, und nicht
beim Anrufer selbst.
--- Gepruefte Wege -------------------------------------------------
pruef-anruf 80 -> 95. Zwei neue Abschnitte, beide mit Gegenprobe:
Route stillgelegt -> 3 rot; der Text ist jetzt einzeln pruefbar
(`pushTextFuer`), weil er vorher tief in einer Funktion entstand, die
nur der Push-Weg aufruft -- von aussen nicht messbar.
Nebenbei gefunden: `istDrinFuerAnruf` braucht die PERSON, nicht ihre
Nummer, und sagt das mit einem eigenen TypeError. Meine erste Fassung
uebergab die Nummer.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
93c9788782 |
Telefonieren im Chat -- und die Farben nach Nachbarschaft verteilt
ZWEI SACHEN IN EINEM COMMIT, weil beide aus derselben Nacht stammen. === 1. DIE FARBEN: DER RICHTIGE ABSTAND === Filipe: "es gibt noch mehr die aehnlich aussehen von den farben also leg los alle die sich aehnlich sind von den farben wechseln." Er hatte recht, und mein Denkfehler laesst sich benennen: Ich hatte den kleinsten Abstand ueber ALLE 37 Paare maximiert -- und der liegt bei 37 Farben zwangslaeufig bei 0,10. Das ist die Packungsgrenze, kein Versaeumnis. NUR SIEHT NIEMAND ALLE 37 NEBENEINANDER. Man sieht NACHBARN. Im Browser gemessen, an der tatsaechlichen Lage auf dem Schirm -- 125 Paare, die wirklich nebeneinander stehen, 15 davon unter 0,15: Creator-Profile / Zahlen 0,1019 beide rosa-rot LIVE-Analyse / Technik 0,1030 beide orange Wunschliste / Meldungen 0,1032 beide gelbgruen Wer sieht was / Entwicklung 0,1039 beide cyan Regeln & Hilfe / Mitmachen 0,1047 beide gruen Der Treff / Anschlagbrett 0,1070 beide rosa Die Farben bleiben, ihre ZUTEILUNG aendert sich: Nachbarabstand 0,1047 -> 0,2133 (mehr als verdoppelt) Nachbarn unter 0,15 6 -> 0 Die Nachbarschaft steht in server/kachel-nachbarn.json, gemessen im Browser -- nicht aus der Struktur im Quelltext abgeleitet. Die sagt, was zusammengehoert, nicht was zusammen zu sehen ist. === 2. TELEFONIEREN IM CHAT === Filipe: "kann man machen dass die modis, rechte hand und ich auch telefonieren koennen im chat?" ... "was man selbst in die app reinsetzten kann, nicht meinen pc belastet und trotzdem vielleicht in gruppe, mit video oder einzelnd." DER TON GEHT NICHT UEBER DEN SERVER. Direkt von Browser zu Browser (WebRTC); der Server reicht nur die Verbindungsdaten weiter, ein paar Kilobyte je Anruf. Zu zweit kodiert jedes Geraet einen Strom und dekodiert einen -- die Last eines gewoehnlichen Videoanrufs. KEIN NEUER DIENST. Der Chat hatte bereits alles: `chatEreignis()` fuer den Hinweg (SSE), Push fuers Klingeln, Raeume mit mehreren Teilnehmern. Ein eigener WebSocket daneben waere eine zweite Verbindung fuer dieselbe Frage -- und die zweite wird beim naechsten Umbau vergessen. Gebaut: Ton und Video, einzeln und in Gruppe bis GRUPPE_MAX (4), Klingeln mit Annehmen/Ablehnen, Mikro und Kamera schaltbar, Gespraechsdauer, Auflegen. Der Chat bleibt daneben benutzbar -- man schreibt oft, waehrend man spricht. EIN FUND, DER OHNE PRUEFLAUF LIVE GEGANGEN WAERE: Der Server sperrt Mikrofon und Kamera per Permissions-Policy auf ALLEN Seiten. Der erste Lauf meldete "microphone is not allowed in this document" -- der Anruf haette bei JEDEM versagt, mit einer Meldung, die auf die falsche Faehrte fuehrt (man sucht an den Browsereinstellungen). Die Sperre bleibt ueberall und ist an genau EINER Stelle geoeffnet: der Chat-Seite, und nur fuer sie selbst (`self`, nicht `*`). NOCH NICHT GEBAUT -- und ausdruecklich nicht heimlich: coturn. Ohne Vermittlungsserver klappen Anrufe nur im selben Netz. Die Adressen stehen in den Einstellungen statt im Quelltext; sie lassen sich nachtragen, ohne eine Zeile zu aendern. Ein oeffentlicher STUN-Dienst als Standard kam nicht in Frage: Er saehe bei jedem Anruf die IP-Adressen beider Teilnehmer, und fuer ein Team, das ueber Moderation und Vorfaelle spricht, ist das keine Kleinigkeit. server/pruef-anruf.mjs, 40 Pruefungen. Der wichtigste Abschnitt: Wer nicht in den Raum gehoert, kommt an KEINE Route. Ein Anruf hinterlaesst keine Spur -- wer mithoert, faellt nicht auf. Gegenproben, jede zielgenau: Empfaengerpruefung der Signalisierung weg -> 1 rot Raumpruefung weg -> 5 rot (jede Route offen) Kopfzeilen-Ausnahme weg -> 4 rot Gruen: anruf, chat, chat-optik, chat-kanaele, css-klassen, namen, struktur. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
9f277435a5 |
Reaktionen: Vorschlaege, ganzer Katalog, eigene Favoriten
Filipe: "soll viel besser und geiler sein und man soll auch auswaehlen
koennen, also paar als vorschlaege mit der moeglichkeit andere
auszuwaehlen und als favoriten zu speichern."
Aus einem Streifen mit sechs Zeichen ist eine Karte geworden:
Vorschlaege oben, Suchfeld, darunter der Katalog in sechs Gruppen --
82 Zeichen, jedes mit deutschen Suchwoertern. Wer "feuer" tippt, muss
nicht scrollen.
DREI LISTEN, DREI FRAGEN, und sie werden gern verwechselt:
KATALOG Was gibt es? fest, workspace-reaktionen.js
VORSCHLAG Was steht vorn, solange fest -- bis jemand eigene
ich nichts gewaehlt habe? Favoriten hat
FAVORITEN Was hat DIESER Mensch in der Datenbank
sich gemerkt?
Nur der Katalog entscheidet, was ANGENOMMEN wird. Vorschlag und
Favoriten sind Reihenfolge, keine Erlaubnis -- sonst koennte man sich
ueber einen Favoriten etwas erlauben, das im Katalog nicht steht. Die
erlaubte Menge wird aus dem Katalog ABGELEITET; eine zweite Liste
daneben waere die, in der ein Zeichen fehlt, das die Oberflaeche
anbietet.
FAVORITEN HAENGEN AM MENSCHEN, NICHT AM GERAET. Im Browser abgelegt
waeren sie am Handy andere als am Rechner und beim naechsten Loeschen
der Seitendaten weg.
DER STERN SCHALTET EINEN MODUS, statt an jedem Zeichen einen zweiten
Knopf zu haben: Am Handy gibt es kein "daneben zeigen". Im Merk-Modus
faerbt sich die ganze Tafel, damit niemand reagiert, wenn er merken
wollte. Die Tafel bleibt dabei offen -- acht Favoriten waeren sonst
acht Mal Aufmachen -- und die Vorschlagszeile aendert sich sofort mit.
DIE GRENZE SAGT BESCHEID, statt still den aeltesten wegzuwerfen: Wer
einen neunten merken will, bekommt "nimm erst einen weg". Ein Favorit,
der ohne Ansage verschwindet, sieht wie ein Fehler aus.
Eine Selbstpruefung beim Laden meldet doppelte Zeichen im Katalog und
Vorschlaege, die nicht darin stehen -- beides waere in der Tafel still.
pruef-chat-aufloesen 85 -> 115. Gemessen wird, was PASSIERT, nicht dass
es Elemente gibt: dass die Suche wirklich eingrenzt (1 statt 82) und
das Richtige findet, dass ein Fehlgriff "Nichts zu ... gefunden" sagt
statt eine leere Flaeche zu zeigen, und vor allem, dass im Merk-Modus
KEINE Reaktion entsteht -- an der Zahl der Reaktionen gemessen, nicht
an der Absicht.
NEBENBEFUND AUS DER EIGENEN PRUEFUNG: pruef-css-klassen hat meine
Gruppenueberschrift mit 10,56 px abgelehnt (Grenze 11,5). Richtig so --
eine gesperrte Versalzeile ist ohnehin schwerer zu lesen, die darf
nicht auch noch die kleinste sein. Auf .72rem angehoben, statt die
Grundlinie zu verschieben.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
47269bda21 |
Chat: auf eine Nachricht reagieren, ohne zu antworten
Filipe: "ich will dass man auf die nachrichten auch reagieren kann mit einem emoji, die nachricht selbst ohne zu antworten." Neben "antworten" steht jetzt "reagieren". Ein Klick klappt sechs Zeichen auf, ein zweiter Klick setzt es -- und unter der Nachricht steht, wer mit was reagiert hat. EINE FESTE AUSWAHL, KEIN FREIES FELD (👍 ❤️ 😂 😮 🔥 🙏). Drei Gruende, der erste ist der wichtigste: Eine feste Liste laesst sich pruefen -- was dort nicht drinsteht, kommt nicht in die Datenbank, kein beliebiger Text, keine 4-KB-Zeichenketten. Zweitens sehen alle dasselbe. Drittens kann man sechs Zeichen ueberfliegen; eine volle Tafel ist eine Suchaufgabe, und dann tippt man doch wieder "ok". DIE LISTE STEHT AUF DEM SERVER und wird an die Oberflaeche geliefert. Stuende sie im Browser, gaebe es sie zweimal -- und die zweite Fassung waere die, in der ein Zeichen fehlt, das der Server noch annimmt. Faellt der Abruf aus, erscheint KEINE Auswahl statt einer mit erfundenen Zeichen. DER PRIMAERSCHLUESSEL BEANTWORTET "WIE OFT?": (nachricht, person, zeichen). Eine Person darf verschiedene Zeichen geben, jedes aber nur einmal -- und zwar durchgesetzt von der Datenbank, nicht von einer Abfrage davor, die man vergessen kann. Derselbe Klick noch einmal nimmt es zurueck; das erspart einen zweiten Weg, den man auch absichern muesste. KEIN ZAEHLER IN chat_nachrichten. Eine mitgefuehrte Zahl muesste bei jedem Hin und Her stimmen und ist genau die Art Angabe, die irgendwann nicht mehr stimmt und die niemand nachrechnet. Gezaehlt wird beim Lesen -- in EINER Abfrage fuer alle 200 Nachrichten, nicht je Zeile eine. WER ES WAR, STEHT IM TITEL. "Drei Daumen" sagt weniger als "Ayla, Ben und Cem", und es sind Leute aus demselben Raum. KEINE BENACHRICHTIGUNG AUFS HANDY. Wer im Raum ist, sieht es sofort; wer nicht, bekommt nichts. Ein Daumen ist keine Nachricht -- wer dafuer geweckt wird, schaltet Meldungen ab. Was NICHT geht: wer nicht im Raum ist (404), ein erfundenes Zeichen (400), eine zurueckgenommene Nachricht (409). Und mit der Nachricht verschwinden die Reaktionen (CASCADE). pruef-chat-aufloesen 59 -> 85. Gemessen wird der BESTAND, nicht die Antwort -- und im Browser der KNOPF, nicht nur das Recht: dass die Auswahl aufklappt, sich nach dem Klick von selbst schliesst, die Reaktion darunter erscheint, als die eigene erkennbar ist und ein Klick darauf sie wieder wegnimmt. EINE EIGENE PRUEFUNG WAR ZU SCHWACH: "bei Cem ist ueberall selbst=true" war trivial wahr, weil es nur EINE Sorte gab. Jetzt bekommt eine andere Person ein drittes Zeichen, und in derselben Antwort muss eines auf true und eines auf false stehen. Eine Angabe, die nie `false` sein kann, sagt nichts. Im CSS keine vierte Abschrift: "reagieren" haengt an derselben Regel wie "antworten" -- neben anheften und kopieren waere es die vierte fast gleiche gewesen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
f23260dcbb |
Chat: Gruender duerfen ihre Gruppe oder ihren Kanal aufloesen — und der Umschalter erklaert sich
Zwei Wuensche von Filipe, beide am Neu-Fenster. 1) "ich will eine bessere erklaerung dafuer bitte." Neben dem Umschalter "Gespraech | Kanal" stand ein Satz ueber das ANTIPPEN von Personen -- also ueber den naechsten Schritt, nicht ueber die Wahl, die gerade ansteht. Wer die beiden Woerter zum ersten Mal sieht, erfuhr nirgends, was sie bedeuten. Der Unterschied ist nicht "wenige/viele Leute", sondern WONACH der Raum benannt ist: ein Gespraech nach den Menschen darin, ein Kanal nach einem Thema. Daran haengt alles Weitere -- dass es einen Kanal je Zustaendigkeit nur einmal gibt (eindeutiger Index, nachgesehen), dass sein Name festliegt, dass die Teamleitung immer dabei ist (kanaeleAngleichen, nachgesehen) und dass Leute wechseln koennen, ohne dass der Raum ein anderer wird. Genau das steht jetzt da, und nichts davon ist behauptet. 2) "die person die ihn oeffnet soll auch das recht haben das zu loeschen und so dass es dan fuer jeden geloescht ist. aber nur die person die es gruendet." Ein EIGENER Weg (/ganz), kein Zusatzfeld am bestehenden. Es gibt jetzt zwei Loeschknoepfe nebeneinander, und sie tun etwas sehr Verschiedenes: Wegraeumen ist nur bei mir, Aufloesen ist fuer alle und endgueltig. Ein vergessenes Feld waere genau dieser Unterschied gewesen. Aus demselben Grund ein anderes Zeichen und eine eigene Warnfarbe -- zwei gleich aussehende Papierkoerbe waeren eine Falle. Nur der Gruender, woertlich: nicht die Teamleitung, nicht DogFather, nicht wer `leitung` in der Gruppe hat. Nicht bei Zweier-Gespraechen -- dort gibt es keinen Gruender, und "niemand nimmt einem anderen die Unterhaltung weg" gilt weiter. Reihenfolge beim Loeschen ist nicht beliebig: erst das Live-Ereignis (chatEreignis liest die Teilnehmer aus der Tabelle -- danach waere die Liste leer), dann die Zeilen in EINER Transaktion, dann die Anhaenge von der Platte. Umgekehrt haetten wir bei einem Ruecklauf Nachrichten, die auf geloeschte Dateien zeigen. WAS DIE PRUEFUNG GEFUNDEN HAT, BEVOR ES JEMAND GEMERKT HAETTE: Der Knopf blieb unsichtbar, obwohl das Recht stimmte. Die Oberflaeche holt den offenen Raum aus dem Nachrichten-Weg, nicht aus der Raumliste -- zwei Wege, ein Raumobjekt, und nur einer kannte das neue Feld. Die Regel steht jetzt in darfAufloesen() und wird von allen dreien benutzt: Liste, Nachrichten-Weg und der Loeschweg selbst. Gefunden hat das die Pruefung, weil sie den KNOPF misst und nicht das Recht dahinter. Haette sie nur `darf_aufloesen` geprueft, waere sie gruen gewesen und der Knopf nie erschienen. NEU: server/pruef-chat-aufloesen.mjs (59 Pruefungen). Sie misst am BESTAND, nicht an der Antwort: ob der Raum wirklich aus der Datenbank weg ist, ob keine Teilnehmerzeile liegen blieb, ob der Anhang von der Platte verschwand -- und mit Gegenprobe, dass der Anhang-Ordner selbst stehen bleibt. Ohne die waere "Datei ist weg" auch dann gruen, wenn es sie nie gab; genau das ist beim ersten Lauf passiert (der Upload lief ins 415, weil ich ihn als Formular statt roh geschickt hatte). Dazu: Wegraeumen ist NICHT Aufloesen (Ben raeumt weg, Cem hat alles noch), ein Zweier-Gespraech laesst sich gar nicht aufloesen, ein Aussenstehender bekommt 404 statt 403, ein zweiter Versuch findet nichts, und die Zustaendigkeit eines aufgeloesten Kanals wird wieder frei (sonst haette der eindeutige Index sie dauerhaft blockiert). Nebenbei: Die drei Kopfknoepfe schoben sich jeder einzeln mit `margin-left: auto` nach rechts. Bei zwei sichtbaren teilen sich zwei auto-Raender den freien Platz und reissen sie auseinander -- und WELCHE sichtbar sind, entscheidet der Server. Jetzt schiebt ein Behaelter einmal, die Knoepfe stehen beieinander, egal wie viele es sind. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
9b47bd3ca0 |
Entwicklung & Nachwuchs -- zwei Bretter fuer DogFather und die rechte Hand
Filipe: "ich will dass ich genau so eine kategorie habe in der dogfather und rechten hand rollen, wo wir aufgaben oder bewertungen ueber modis eingeben koennen. auch fuer zuschauer die vielleicht modis werden koennten waere auch geil. mach dich schlau informier dich so krass wie es nur geht, hol die besten der besten und krassesten sachen, perfektionnier die dan auch alle und dan erst setzt du alles um." === WAS DIE RECHERCHE ERGEBEN HAT === DREI BEFUNDE HABEN DAS DESIGN BESTIMMT, und der erste hat es fast umgedreht: WARUM MODERATOREN AUFHOEREN (Schoepke-Gonzalez u. a., New Media & Society 2024): zwei Hauptgruende -- zu wenig Zeit, und Konflikte im Team beziehungsweise schaedliches Verhalten der Leitung. Eine Bewertungsfunktion ist damit genau das Werkzeug, mit dem man ein Team verliert, wenn man sie als Ueberwachung baut. Das ist kein Bauchgefuehl und keine Zimperlichkeit -- es ist der haeufigste gemessene Grund. WAS HAELT: Anerkennung. Dank und Rueckmeldung erhoehen die Verweildauer messbar; Rollenklarheit senkt Burnout. WORAN MAN GUTE MODERATOREN ERKENNT (ModSquad, Kitfox Games, Discord-Leitfaeden): nicht an Zahlen. Ruhig bleiben, wenn es hitzig wird; von selbst helfen; die Regeln UND die Leute kennen; regelmaessig da sein. Ausdruecklich NICHT: "schreibt viel" -- angenehm im Chat zu sein ist nachweislich etwas anderes. Und der treffsicherste Weg ueberhaupt ist die Empfehlung aus dem Team, gefolgt von einer Probezeit. === WAS DARAUS GEBAUT WURDE === ENTWICKLUNG. Keine Note, sondern eine Aufzeichnung ueber die Zeit, je Person. Fuenf Arten, und ihre REIHENFOLGE ist Absicht: "Das laeuft gut" und "Danke dafuer" stehen vorn. Wer ein Formular oeffnet, dessen erstes Feld "Problem" heisst, schreibt Probleme auf. "ZU VIEL GERADE" IST DIE WICHTIGSTE ART und die, die es sonst nirgends gibt. Der haeufigste Grund zu gehen ist Zeitmangel, und der zeigt sich frueh -- nur schreibt ihn niemand auf, weil es kein Feld dafuer gibt. TALENTE. Die vier Merkmale sind die aus der Literatur, nicht ausgedacht, dazu die Empfehlung aus dem Team. Der Status IST die Probezeit: `offen` heisst beobachtet, `angenommen` heisst angesprochen -- und was daraus wird, entscheidet sich in "Personen & Zugaenge" mit einem Zugang auf Stufe "Probe". Eine eigene Kandidatentabelle waere ein zweiter Ort fuer dieselbe Frage. DIE BRUECKE. Die Person sieht den Entwicklungs-Bereich NICHT -- eine halb sichtbare Akte ist schlimmer als eine geschlossene, weil niemand mehr weiss, was der andere gerade liest. Damit Anerkennung trotzdem ankommt, laesst sich jeder Eintrag EINMAL als Nachricht in den Chat schicken, mit Art, Titel und dem, was daraus folgen soll. Danach steht im Eintrag, wann es geschehen ist: Die Frage "habe ich ihr das eigentlich schon gesagt?" beantwortet man nach zwei Wochen falsch. ZWEI KACHELN UND NICHT DREI: Aufgaben an das Team gibt es laengst, mit Person, Frist und Status. Eine zweite Stelle dafuer waere ein zweiter Ort, an dem man nachsehen muesste, welche Aufgabe wirklich gilt. DIE GRUPPE HEISST NICHT "TEAM FUEHREN". Das waere der bequeme Name und der falsche: Im Haus gilt, dass DogFather nicht ueber seinem Team steht. "Entwicklung & Nachwuchs" sagt, was drinsteht. === KEIN NEUER BAUKASTEN === Beides sind BEREICHE wie das Ideen-Board: dieselbe Tabelle, dieselbe Seite, dieselben Regeln fuers Anlegen, Aendern und Loeschen. Neu sind eine Spalte (`gesendet_am`) und eine Route. Die Sendefunktion selbst steht im Chat-Modul und nicht daneben: Ein Zweier-Gespraech darf es nur einmal geben, die Leseraender muessen mitwandern, Live-Strom und Benachrichtigung haengen daran -- wer das nachbaut, hat zwei Fassungen, und die zweite ist die, in der jemand eine Nachricht nicht bekommt. === WAS DIE PRUEFUNG GEFUNDEN HAT === "Zugeordneter Creator existiert nicht" -- beim Anlegen eines Eintrags ueber ein Teammitglied. Die Regel verlangte einen Creator; bei Entwicklung geht es um Menschen aus dem Team. Die Meldung war dabei selbst irrefuehrend: Die Person existiert sehr wohl, sie ist nur kein Creator. Beides behoben. Und meine EIGENE Pruefung von vor einer Stunde wurde rot: Sie verlangte, dass jede Zusatzkachel in der Gruppe "Team Dogi" steht. Die naheliegende Reparatur waere gewesen, die Gruppe gar nicht mehr zu pruefen -- das haette die Aussage weggeworfen. Jetzt steht die erlaubte Liste ausgeschrieben da: Eine Kachel fuer zwei Menschen darf nicht in einer Gruppe landen, die alle sehen. Kommt eine dritte Gruppe, wird die Zeile rot, und das ist Absicht. Die zwei neuen Farbtoene trennen ueber Saettigung und Helligkeit statt ueber den Farbwinkel -- bei 25 Toenen ist der Kreis voll, und die groessten Luecken waeren ein drittes Gruen zwischen zwei vorhandenen. Bei einer achtundzwanzigsten Kachel brauchen die Kacheln Gruppenfarben statt Einzelfarben; das steht als Notiz im Quelltext. pruef-entwicklung 33 (neu) · pruef-start-ansicht 27 Kacheln, sechs Gruppen · pruef-rollen 278 -> 282 · pruef-modi-checkliste 70 · pruef-haus-trennung 62 · pruef-rueckmeldung 30 · pruef-modi-ideen 30 · pruef-modi-verborgen 80 · pruef-css-klassen gruen · pruef-modi-wortleck 5. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
d92ba76e33 |
Kategorie-Kanaele und angeheftete Ankuendigungen (Kapitel 7.2)
Die vier Saetze aus dem Anforderungsdokument, der Reihe nach: Team- Gruppenchat, Kategorie-Kanaele mit Zugriff fuer Owner und rechte Hand, private 1:1-Chats OHNE diesen Zugriff, und Pin-Nachrichten an alle. EIN KANAL IST KEINE VIERTE TABELLE, sondern eine dritte Art Raum (`art = 'kanal'` neben 'direkt' und 'gruppe'). Damit gilt fuer ihn ohne eine einzige neue Zeile alles, was schon da ist: Verlauf, Anhaenge, Suche, Ungelesen-Zaehler, Live-Strom, Wegraeumen. Eine eigene Tabelle haette all das ein zweites Mal gebraucht -- und die zweite Fassung waere die gewesen, in der die Zugriffsregel fehlt. Welche Zustaendigkeit, kommt aus MODI_KATEGORIEN -- derselben Liste, aus der auch die Aufgaben ihre Kategorie nehmen. Der NAME kommt aus der Kategorie und ist kein freies Feld: "Clipping" neben "Clipping-Team" waeren zwei halbe Verlaeufe, und man merkt es erst, wenn jemand die Antwort im falschen sucht. Ein eindeutiger Teilindex haelt das auch dann fest, wenn zwei Anfragen im selben Augenblick ankommen. DIE ZUGRIFFSREGEL STEHT IN istDrin() -- der Funktion, durch die alle sieben lesenden und schreibenden Wege gehen. In den Routen stuende sie in sechs davon und in der siebten nicht. Sie gilt AUSDRUECKLICH nur fuer 'kanal': Zweier-Gespraeche bleiben zu, auch fuer DogFather (so steht es im Dokument), und Gruppen ebenfalls -- wer eine Gruppe aufmacht, hat sich fuer einen geschlossenen Kreis entschieden, und den nachtraeglich still zu oeffnen waere das Gegenteil dessen, was er getan hat. Wenn Filipe das anders will, ist es eine Zeile -- aber es waere seine Entscheidung und muesste fuer die Beteiligten SICHTBAR sein. istDrin() nimmt dafuer die PERSON statt ihrer Nummer und wirft bei einer Nummer einen Fehler, statt stillschweigend "nein" zu antworten. HOECHSTENS DREI ANKUENDIGUNGEN je Raum. Nicht eine (Regeln, Live-Plan und Frist muessen gleichzeitig oben stehen koennen) und nicht beliebig viele -- eine Pinnwand, die scrollt, ist ein zweiter Verlauf. Der Aushang hat eine EIGENE Abfrage, weil der Verlauf nur 200 Zeilen liefert: Eine Ansage von vorletzter Woche waere sonst genau dann weg, wenn sie am laengsten oben stehen sollte. Wird die Nachricht zurueckgenommen, faellt sie ab UND gibt den Platz frei. DREI DINGE, DIE ERST DAS HINSEHEN GEZEIGT HAT: Der frisch angelegte Kanal hatte zwei Leute statt vier. Die Personenauswahl zeichnete nach der Rollenfolge aus bereiche.js -- wer dort nicht steht, wurde NICHT GEZEICHNET. Team Dogi steht dort nicht und darf es auch nicht (der Rollenname gehoert in keine Datei, die jeder herunterlaedt). Folge: DogFather konnte ueber die Auswahl niemandem aus seinem Team schreiben. Der Server schickt die Ueberschrift jetzt mit; der Browser braucht dafuer keinen Rollennamen. Der Kommentar, der genau davor warnte, stand die ganze Zeit darueber. Dieser Fehler war nebenbei ein Netz: Was nicht gezeichnet wird, kann auch nicht falsch gezeichnet werden. Deshalb ist jetzt gemessen, dass ein Manager und Spicy Media Team Dogi gar nicht erst geschickt bekommen -- und dabei fiel auf, dass Spicy Media in der EIGENEN Auswahl stand: Sobald es jemanden zu verbergen gibt, schreibt ohneVerborgene() aus "sieht alles" eine echte Liste, und darin steckt man selbst. Am Fuss jeder Nachricht stehen jetzt vier Handgriffe statt drei. Bei 390 px -- der haeufigsten Handybreite -- stand "kopieren" 18 px ueber der Blase, bei 320 px 75. Behoben mit `flex-wrap: wrap` und nicht mit einer Schwelle: Eine Regel, die misst, bleibt beim fuenften Handgriff richtig; eine Zahl nicht. pruef-chat-optik misst es ab jetzt. NACHGEZOGEN, was pruef-css-klassen an MEINEM letzten Commit fand: teamlage.html lud kopf.js ohne wahl.js (der Sicht-Umschalter sah aus wie aus einem anderen Programm -- kaputt war nichts, und genau deshalb faellt es niemandem auf), und .tampel__tag stand auf 11,2 px. Beides war schon gepusht, weil ich die Pruefung nicht laufen liess. pruef-chat-kanaele 73 (neu) · pruef-chat 48 · pruef-chat-ausbau 64 · pruef-chat-anhaenge 60 · pruef-chat-optik 24 -> 26 · pruef-css-klassen gruen · pruef-rollen 274 · pruef-modi-verborgen 78 · pruef-team-ampel 28 · pruef-start-ansicht gruen · pruef-modi-wortleck 5 · pruef-zwischenspeicher 21. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
14e9bbf7a5 |
Chat: Fotos und PDFs schicken, Gespraeche wegraeumen
Filipe, mit Bildschirmfoto: "man muss die chats auch geloescht bekommen!!! am besten waere es auch wenn man da auch im chat pdfs schicken koennte. pdfs und fotos." Zwei Entscheidungen vorher abgestimmt, weil sie den Bau bestimmen: Geloescht wird NUR BEI MIR. Schicken duerfen ALLE im Gespraech, auch Creator -- anders als in der Dateiablage, wo etwas in einem Bereich landet, den mehrere sehen. Hier bekommt es genau der, mit dem man ohnehin gerade spricht. --- ANHAENGE --- Drei Wege zur selben Sache, weil Leute unterschiedlich arbeiten: die Bueroklammer, Hineinziehen und Einfuegen mit Strg+V (der Weg fuer einen Screenshot -- der liegt in der Zwischenablage und nirgends als Datei). Alle drei laufen durch dieselbe Funktion; drei Fassungen waeren drei Gelegenheiten, dass eine die Pruefung vergisst. Ein Foto wird GEZEIGT, ein PDF wird als Karte ANGEBOTEN. Das ist kein Schoenheitsunterschied: Ein Bild erkennt man in einer Zehntelsekunde, ein PDF muss man ohnehin oeffnen -- eine Vorschau davon waere ein grauer Kasten, der so tut, als koennte man etwas lesen. DIE SICHERHEIT STEHT IN dateiErkennen(). Dateiname und Content-Type kommen vom Absender und sind frei erfunden; der Typ wird deshalb aus den ersten Bytes bestimmt (PNG/GIF/WebP/JPEG/PDF, mit Breite und Hoehe im selben Durchgang). SVG steht absichtlich NICHT in der Liste -- das ist XML, das Skripte enthalten darf, ein als Bild getarntes Programm. Ausgeliefert wird spaeter genau der ERKANNTE Typ, nie der eingeschickte, dazu nosniff und "default-src 'none'; sandbox". Auf der Platte bekommt jede Datei einen erzeugten Zufallsnamen, in einem Ordner ausserhalb des Repos. Zuruecknehmen loescht die Datei wirklich -- sonst waere sie im Verlauf weg und ueber die Adresse noch da, also nur der Anschein einer Ruecknahme. --- WEGRAEUMEN --- Zwei Spalten in chat_teilnehmer statt einer, wegen eines Randfalls: Bei einem Gespraech ohne jede Nachricht waere die Grenze 0 -- und 0 heisst sonst "nie geloescht". geloescht_am unterscheidet die beiden. Die Grenze wirkt in der Liste, im Verlauf, in der Vorschau, in der SUCHE, bei den Anhaengen und in der Ungelesen-Zahl. Die Suche ist die Stelle, an der so etwas typischerweise durchrutscht: aus der Liste weg, ueber die Suche noch da. --- DER FUND: 323 PIXEL --- Ein Bild ist spaeter fertig als der Rest der Seite. Beim Oeffnen springt der Verlauf ans Ende, dann kommt das Foto an und schiebt alles darunter weg -- man steht ploetzlich mittendrin, ohne etwas angeklickt zu haben. Das width/height-Attribut am <img>, wie man es ueberall liest, hilft hier NICHT: Es gibt nur das Seitenverhaeltnis. Damit daraus eine Hoehe wird, muss die Breite feststehen -- bei "width: auto" und einem nicht geladenen Bild ist sie 0. Der Platz wird jetzt am KASTEN reserviert (aspect-ratio + max-width aus den gemessenen Massen). Und die Pruefung dazu hatte denselben Fehler wie das Auge: Sie mass in einem Fenster, in dem das Bild laengst im Zwischenspeicher lag, und meldete tadellose 0 px. Sie misst jetzt in einem FRISCHEN Browser -- der Fall, um den es geht, ist der erste. --- SICHERUNG --- chat-anhaenge/ ist im selben Zug in tools/sicherung-holen.sh eingetragen, nicht spaeter, wenn es auffaellt: Genau so ist die Luecke bei den Profilbildern entstanden. tools/wiederherstellung-proben.mjs bestaetigt: "der Server benutzt 4 Datenordner", keiner fehlt. --- Pruefung --- server/pruef-chat-anhaenge.mjs, neu, 60 Pruefungen, alle gruen. Abschnitt 3 versucht ausdruecklich, hereinzukommen: HTML als bild.png, SVG als foto.png, SVG als svg, eine Textdatei, ein PNG-Kopf ohne Inhalt -- alle fuenf mit 415 abgewiesen, ein echtes JPEG danach mit 201 angenommen (sonst bewiese der Block nur, dass gar nichts durchkommt). 13 MB geben 413 mit lesbarem Text, nicht 500. Konsolenfehler werden nach ZEITPUNKT getrennt, nicht nach Statusnummer: Was waehrend eines absichtlichen Versuchs entsteht, ist gewollt. Nach Nummer zu filtern waere bequem und wuerde ab morgen echte 404 mit verschlucken. Ausserdem gruen: pruef-chat, pruef-chat-optik, pruef-chat-ausbau, pruef-css-klassen. Angesehen bei 1440 px und bei 390 px. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
7de32a5ec7 |
Punkt 15: Der Chat bekommt Suche, Antworten mit Zitat und die Ungelesen-Linie
Wunsch Filipe: "ich will dass du diese seite viel krasser und detaillierter machst, ich will dass du dich informierst und alles reinsetzt was wir noch gebrauchen koennten." NICHT ALLES, SONDERN WAS TAEGLICH FEHLT. Der Chat konnte schon Raeume, Verlauf, Gelesen-Stand, Live-Zustellung, Gruppen und Zuruecknehmen. Drei Dinge fehlten, und jedes davon kostet ohne es echte Zeit: 1. SUCHE IN DEN NACHRICHTEN. Ein Chat ohne sie ist ab dem zweiten Monat ein Archiv, in dem man nichts findet. Ein Suchfeld gab es -- es durchsuchte aber nur die NAMEN der Gespraeche, also die kleinere Haelfte. Jetzt durchsucht dasselbe Feld beides und zeigt die Fundstellen UNTER der Gespraechsliste: Wer "Patrick" eingibt, will vielleicht das Gespraech und vielleicht die Nachricht -- ein Umschalter haette ihn zwingen wollen, das vorher zu wissen. 2. ANTWORTEN MIT ZITAT. Zu zweit weiss man meistens, worauf sich etwas bezieht. In einer Gruppe laufen drei Faeden parallel, und "ja, mach das" kann alles heissen. Das Zitat steht IN der Blase (es gehoert zur Antwort, nicht darueber) und fuehrt per Klick zur Stelle. 3. DIE LINIE "AB HIER NEU". Wer nach zwei Tagen zurueckkommt, sucht sonst die Stelle, an der er aufgehoert hat, indem er Uhrzeiten liest. BEWUSST NICHT GEBAUT: Anhaenge (dafuer gibt es den Dateien-Bereich mit Rechten und Ablauf), Reaktionen (eine vierte Sache, bevor die drei sich bewaehrt haben) und Tipp-Anzeigen (dauernder Verkehr fuer eine Auskunft, die man in zwei Sekunden ohnehin sieht). DIE SICHERHEIT DER SUCHE STEHT IM JOIN, nicht in einer nachtraeglichen Pruefung: `chat_teilnehmer` wird mit der eigenen Personenkennung verbunden, und was dort nicht drinsteht, kommt gar nicht erst aus der Datenbank. Ein Filter, der erst hinterher aussortiert, ist eine Zeile davon entfernt, vergessen zu werden. Ebenso beim Zitat: Worauf geantwortet wird, muss im SELBEN Raum liegen -- sonst koennte jemand die Kennung aus einem fremden Gespraech mitschicken, und beim Empfaenger stuende ein Zitat aus einem Raum, den er nie gesehen hat. DREI FEHLER, DIE DER DURCHLAUF GEFUNDEN HAT: 1. `ESCAPE '\'` IN EINEM TEMPLATE-LITERAL. Dort ist `\'` eine Fluchtsequenz fuer das Anfuehrungszeichen -- SQLite bekam ein LEERES Fluchtzeichen und antwortete "ESCAPE expression must be a single character". Die Suche war damit komplett tot. Kein Syntaxfehler, kein Warnhinweis: Erst der Aufruf mit echten Daten hat es gezeigt. 2. DIE MASKIERUNG KANNTE ZWEI VON DREI ZEICHEN. `%` und `_` waren dabei, der Backslash nicht -- ausgerechnet das Fluchtzeichen selbst. Geprueft wird das jetzt an der ZEILE AUS DER DATEI, nicht an einem Nachbau: Mein erster Test hat die Maskierung nachgebaut und dabei die Shell-Maskierung mitgeschleppt -- er meldete einen Fehler, den nur er hatte. 3. DIE UNGELESEN-LINIE SCHIEN NICHT ZU FUNKTIONIEREN. Sie tat es -- mein Testaufbau war falsch: Filipes Seite war noch offen, die neuen Nachrichten kamen ueber den Live-Strom an und wurden sofort als gelesen gemeldet. Es gab schlicht nichts Ungelesenes. Erst als er die Seite verlaesst, bevor Patrick schreibt, steht die Linie da -- und zwar genau vor "Neu von Patrick, eins", und beim zweiten Oeffnen ist sie weg. Der Gelesen-Stand wird deshalb beim OEFFNEN mitgeschickt, bevor er gesetzt wird -- eine Zeile spaeter waere er immer die letzte Nachricht, und die Linie staende nie irgendwo. Ohne Volltextindex, mit Absicht: `LIKE` liest die Tabelle, und bei einem Team dieser Groesse sind das einige tausend Zeilen. Ein FTS5-Index waere eine zweite Tabelle, die synchron gehalten werden muss -- genau daran gehen solche Sachen kaputt. Wenn der Verlauf sechsstellig wird, ist das der Zeitpunkt dafuer, nicht heute. Geprueft: pruef-chat, pruef-chat-optik, pruef-css-klassen, pruef-workspace-seiten, pruef-handy -- alle in Ordnung. Dazu im Browser durchgespielt: Zitat gesetzt und gelesen, Suche nach "Bitrate" (1 Treffer), nach "100 %" (1 Treffer -- die Maskierung haelt), nach Unsinn (0), einbuchstabige Suche (zu kurz), Antwortleiste mit dem richtigen Namen, Ungelesen-Linie an der richtigen Stelle und beim zweiten Oeffnen weg. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
e8478c9cae |
Spicy sieht DogFathers Sachen nicht mehr -- und sechs Fehler dazu
VIER DINGE AUS DEN BILDSCHIRMFOTOS, jedes ein echter Fehler:
1. SPICY MEDIA SAH DOGFATHERS DATEN. Beim ersten Anlauf bekam die Rolle
dieselbe Regel wie DogFather (`1=1`) -- damit stimmte der Ueberblick
ueber Manager, Scouts und Creator, und nebenbei standen seine eigenen
Termine, Aufgaben, Dateien und Eintraege mit drin. Jetzt gibt es
ohneDogFather() als EINE Stelle dafuer: Zwei Spalten werden geprueft,
`creator_id` (um wen geht es) und `erstellt_von` (wer hat es
geschrieben) -- ein Termin, den er sich selbst anlegt, haengt nur an
der zweiten. `IS NULL OR NOT IN` und nicht bloss `NOT IN`: In SQL ist
`NULL NOT IN (...)` weder wahr noch falsch, die Zeile fiele
stillschweigend heraus.
2. "PERSOENLICHER ZUGANGSCODE · undefined" auf der Anmeldeseite. Eine
zweite Namensliste im Browser, die beim Hinzufuegen der Rolle
niemand gepflegt hat. Ein unbekannter Schluessel faellt jetzt auf
sich selbst zurueck statt auf `undefined` -- haesslich, aber
sichtbar.
3. SPICY KAM NICHT IN DIE PERSONENVERWALTUNG. Der Server liess sie
herein, das Skript warf sie wieder hinaus: zwei Listen fuer dieselbe
Frage, gepflegt wurde nur die erste.
4. DIE ANMELDEKARTE WAR ZU KLEIN FUER FUENF ROLLEN. Der Kommentar an
genau dieser Stelle warnt woertlich davor -- und ich habe getan,
wovor er warnt: eine Rolle eingefuegt und die Zahl daneben nicht
angefasst. Gemessen: Inhalt 573 px in einer 526 px hohen Tafel, die
Fusszeile stand unter dem Rahmen. Schrift kleiner half nicht (sie lag
schon auf dem Anschlag), also sind die Abstaende an neun Stellen
enger. Nachgemessen auf fuenf Groessen: passt ueberall.
DIE ZEIT WAR WIRKLICH FALSCH. Nicht nur in meinem Satz: `datum()` in
personen.js schnitt die ISO-Zeichenkette ab -- und die ist UTC. Im
Protokoll stand 03:00, wo 05:00 war. Das Tueckische daran ist, dass es
nie kaputt aussieht: Eine Uhrzeit ist immer plausibel.
PROFILBILDER WERDEN JETZT GEZEICHNET. Der Server lieferte sie seit
gestern mit, gezeichnet wurden sie nirgends -- deshalb aenderte sich
nichts. Jetzt in der Personenauswahl (Aufgaben, Termine, Dateien,
Bereiche), in der Gespraechsliste und an jeder Nachricht. Der
Anfangsbuchstabe bleibt als Unterlage LIEGEN: Faellt das Bild aus, steht
dort weiter etwas Sinnvolles.
DER CHAT: Gesichter mit Rollenfarbe, Blasen mit Richtung (die erste
einer Folge eckig, die naechsten rund -- so sieht man, wo ein Gedanke
anfaengt), das offene Gespraech mit Schiene, Ungelesenes hervorgehoben,
und das Eingabefeld in einer eigenen Leiste, die sich beim Schreiben
hebt.
ZWEI EIGENE PATZER, beide von Pruefungen gefunden:
- `o is not defined`: Mein Suchmuster hat die zwei Zeilen fuer das
Bild ans DATEIENDE gesetzt statt in die Schleife -- und in
kalender.js an einen <span> statt ans <option>. Gemeldet von
pruef-sicht, das die Browserkonsole mitliest.
- Ein Kommentar mit `bild` in schraegen Anfuehrungszeichen stand INNEN
in einer Vorlagenzeichenkette und hat sie geschlossen. Die halbe SQL
wurde zu Programmtext.
Dazu: `.chat-neu` gibt es nicht (heisst `.chat__eingabe`), und der
Rollenknopf hatte fuer den Manager keinen sichtbaren Fokus -- ein
box-shadow wird von `overflow: hidden` abgeschnitten, ein outline nicht.
Gruen: spicy (43), creator-anlegen (29), personen-liste (33), sicht (48),
chat (48), chat-optik (24), buehne (38), struktur (32), css-klassen (15),
handy (59), breiten (23), formulare (19), start-ansicht (136),
lesbarkeit (14), barrierefrei (18), tempo (8), kopf-messen (3),
glocke (26), haerte (20), manager-sicht (43), alle-wege (19),
aufgabenbrett (44), kalender (84).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4637aa24e7 |
Chat zwischen Creator, Scouts und Managern
Wunsch Filipe, 06.09.2026: *"eine kategorie chat, wo die creator mit
ihren manager nachrichten austauschen koennen, wie erinnerungen, fragen
und noch vieles mehr."* Auf Nachfrage entschieden: Zweier-Gespraeche UND
Gruppen; Manager und Scouts duerfen sich auch ohne gemeinsamen Creator
schreiben.
WER MIT WEM steht an EINER Stelle: schreibbareIds() in workspace.js.
Bewusst getrennt von einladbareIds() (Terminwahl): Dort geht es darum,
wen man zu einem Kalendereintrag dazustellen darf -- harmlos. Ein Chat
legt ein dauerhaftes Gespraech an, schickt eine Benachrichtigung und
macht den eigenen Namen sichtbar. Zwei Fragen, zwei Funktionen.
Ein Creator erreicht seine Betreuer und DogFather, KEINEN fremden
Creator. Eine Gruppe ist kein Schlupfloch: Jede Nummer wird einzeln
gegen dieselbe Regel geprueft.
SOFORT STATT NACHFRAGEN IM TAKT (SSE). Ein Chat, der alle fuenf
Sekunden fragt, ist fuenf Sekunden langsam und stellt bei zehn
Angemeldeten 7200 Anfragen in der Stunde fuer Nachrichten, die es
meistens nicht gibt. Kein WebSocket: Hier fliesst alles in eine
Richtung, und SSE uebersteht einen Verbindungsabriss von selbst.
DIE ZAHL STEHT AUF JEDER SEITE, nicht nur im Chat. Eine Nachricht, die
man erst sieht, wenn man den Chat aufmacht, ist keine Nachricht --
sie ist ein Fundstueck.
Push aufs Handy nur an die, die NICHT gerade zusehen. Wer die Seite
offen hat, sieht es ohnehin; ihm zusaetzlich etwas aufs Handy zu
schicken ist der schnellste Weg, dass er Benachrichtigungen abschaltet.
WAS BEWUSST NICHT GEHT:
* Niemand liest fremde Gespraeche mit -- auch DogFather nicht. Ein
Chat, in dem der Chef stillschweigend mitliest, ist kein Chat.
Er kann jederzeit jedem schreiben, aber sichtbar.
* Eine abgeschickte Nachricht laesst sich nicht aendern, nur
zuruecknehmen. Wer Absprachen nachtraeglich umschreiben kann, macht
den Verlauf wertlos. Zurueckgenommenes hinterlaesst einen Hinweis
statt eines Lochs.
DAZU: CALL-LISTE NACH ZEIT GEGLIEDERT
Wunsch mit Bild von "STEHT AN 27": *"die liste soll kategorisiert sein
und werden mit einem button zum auf und zu machen."* Jetzt Heute /
Diese Woche / Naechste Woche / Spaeter, offen nur der erste gefuellte
Block. Nach ZEIT und nicht nach Titel: Auf dem Bild waren fast alle
"Community-Talk" -- nach Titel gruppiert haette man zwei Ueberschriften
und darunter dieselbe lange Liste.
DER FUND, DER DIE FUNKTION GERETTET HAT: Ein zugeklappter Block zeigte
seinen Inhalt trotzdem -- 367 Pixel Hoehe bei open=false. <details>
versteckt seinen Inhalt naemlich nur, solange niemand dem Inhalt eine
eigene display-Angabe gibt, und .gruppe__karten traegt display:grid.
Der Knopf haette sich bewegt und sonst nichts getan. Im Bildschirmfoto
fiel es nicht auf, weil der Ausschnitt genau darueber endete.
Ausserdem gefunden und behoben:
* Ein Wettlauf beim Abschicken: War der Ereignisstrom schneller als
die Antwort auf das POST, stand die eigene Nachricht zweimal im
Verlauf.
* Die Chatseite war zu hoch -- die Kopfleistenhoehe stand als fester
Wert (62 px) im CSS, am Handy ist sie doppelt so hoch. Das
Eingabefeld stand halb unter dem Bildschirmrand. Jetzt gemessen.
* Der Platzhalter "Enter schickt ..." brach am Handy um UND stimmte
dort nicht: Ohne Tastatur schickt Enter absichtlich nicht.
* Der Dialog benutzte Klassen aus aufgaben.css, das chat.html nicht
lud -- gemeldet von pruef-css-klassen, bevor jemand einen
ungestylten Dialog zu sehen bekam.
Pruefungen: pruef-chat (44 Punkte, Rechte und Sichtbarkeit),
pruef-chat-optik (24, zwei echte Browser schreiben sich),
pruef-call-kategorien (16).
Co-Authored-By: Claude Opus 5 <[email protected]>
|