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]>
This commit is contained in:
@@ -340,8 +340,27 @@
|
||||
Die Kinder erben sie (color: inherit). Vier eigene Farbangaben wären
|
||||
vier Stellen, die beim nächsten Mal auseinanderlaufen -- der Fehler,
|
||||
der in diesem Haus am häufigsten vorkommt. */
|
||||
/* VIER HANDGRIFFE PASSEN NICHT IN EINE ZEILE (10.09.2026).
|
||||
|
||||
Hier stand `display: flex` ohne Umbruch. Mit drei Eintraegen (Zeit,
|
||||
antworten, kopieren) ging die Rechnung auf. Seit "anheften"
|
||||
danebensteht, geht sie nicht mehr: Gemessen an echten Bildpunkten
|
||||
stand "kopieren" bei 390 px -- der haeufigsten Handybreite -- 18 px
|
||||
ueber der Blase, bei 320 px waren es 75. Die Zeile lief einfach
|
||||
weiter, ueber ihren eigenen Rand hinaus.
|
||||
|
||||
DIE LEHRE IST NICHT "eine Schwelle einbauen". Das waere derselbe
|
||||
Fehler wie in der Kopfleiste am 06.09., nur mit einer anderen Zahl
|
||||
-- und beim fuenften Eintrag stuende sie wieder falsch da.
|
||||
`flex-wrap: wrap` ist eine REGEL statt einer Rechnung: Sie bricht
|
||||
genau dann um, wenn der Platz nicht reicht, und zwar unabhaengig
|
||||
davon, wie viele Handgriffe es einmal sein werden.
|
||||
|
||||
`row-gap` kleiner als `column-gap`: Zwei Zeilen Fusstext sollen wie
|
||||
ein Block wirken, nicht wie zwei Absaetze. */
|
||||
.chat-nachricht__fuss {
|
||||
display: flex; align-items: center; gap: 9px;
|
||||
display: flex; align-items: center; flex-wrap: wrap;
|
||||
column-gap: 9px; row-gap: 2px;
|
||||
margin-top: 4px;
|
||||
color: var(--text-leise);
|
||||
}
|
||||
@@ -1080,3 +1099,159 @@
|
||||
@media (forced-colors: active) {
|
||||
.chat-datei, .chat__ablage { border: 1px solid CanvasText; }
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
KATEGORIE-KANÄLE UND ANGEHEFTETE ANKÜNDIGUNGEN (10.09.2026)
|
||||
|
||||
Kapitel 7.2 des Anforderungsdokuments: "Kategorie-Kanäle" und
|
||||
"Ankündigungs-Funktion: Pin-Nachrichten von Owner/rechte Hand an
|
||||
alle."
|
||||
|
||||
DER TON IST GEDÄMPFTES BERNSTEIN, nicht Signalgelb. Eine Ankündigung
|
||||
steht dauerhaft oben im Bild – sie ist das Element, das am längsten
|
||||
im Blick liegt, und genau deshalb darf es nicht das lauteste sein.
|
||||
Auffallen soll sie durch ihre POSITION, nicht durch ihre Farbe.
|
||||
===================================================================== */
|
||||
|
||||
.chat {
|
||||
/* Bernstein, entsättigt. Auf dem dunklen Grund der Seite kommt es
|
||||
als warmes Signal an, ohne zu blenden. */
|
||||
--pin: #d9ae62;
|
||||
}
|
||||
|
||||
/* ---- Ein Kanal in der Gesprächsliste -------------------------------- */
|
||||
/* Die Raute statt einer Zahl oder Initiale: Ein Kanal hat keine feste
|
||||
Größe (es kommen Leute dazu) und keinen Menschen dahinter. Eckiger
|
||||
als ein Kreis, runder als eine Gruppe -- so sind die drei Arten auch
|
||||
ohne Farbe auseinanderzuhalten. */
|
||||
.chat-raum__zeichen[data-kanal="ja"] {
|
||||
--r: var(--pin);
|
||||
border-radius: 10px;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* ---- Die Pinnwand über dem Verlauf ---------------------------------- */
|
||||
.chat-pins {
|
||||
flex: none;
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--rand);
|
||||
background: color-mix(in srgb, var(--pin) 6%, transparent);
|
||||
}
|
||||
/* Drei Aushänge sind das Höchste (PIN_MAX im Server). Selbst dann
|
||||
bleibt die Wand niedrig genug, dass der Verlauf die Seite behält --
|
||||
mehr als ein Drittel der Höhe darf sie nie nehmen. */
|
||||
.chat-pin {
|
||||
display: flex; align-items: stretch; gap: 8px;
|
||||
border: 1px solid color-mix(in srgb, var(--pin) 26%, transparent);
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, .025);
|
||||
}
|
||||
.chat-pin__auf {
|
||||
flex: 1; min-width: 0;
|
||||
display: block; text-align: left;
|
||||
appearance: none; border: 0; background: none;
|
||||
padding: 7px 10px;
|
||||
font: inherit; color: inherit; cursor: pointer;
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
.chat-pin__auf:hover { background: rgba(255, 255, 255, .03); }
|
||||
.chat-pin__auf:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
|
||||
|
||||
.chat-pin__kopf {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
font-size: .72rem; line-height: 1.2;
|
||||
}
|
||||
.chat-pin__nadel { flex: none; width: 13px; height: 13px; color: var(--pin); }
|
||||
.chat-pin__von { font-weight: 700; color: var(--pin); }
|
||||
/* Wer angeheftet hat, steht daneben und nicht darunter: Es ist eine
|
||||
Randnotiz, keine zweite Zeile. Am Handy fällt sie weg -- dort zählt
|
||||
der Text der Ankündigung, nicht ihre Herkunft. */
|
||||
/* .72rem und nicht .68 (10.09.2026, gefunden von pruef-css-klassen).
|
||||
Unter 11,5 px wird Text auf einem Handy zur Zumutung -- und diese
|
||||
Zeile steht dauerhaft im Bild. Sie soll leiser sein als der Text
|
||||
daneben; das macht die FARBE, nicht die Groesse. */
|
||||
.chat-pin__wer { color: var(--text-still); font-size: .72rem; }
|
||||
.chat-pin__text {
|
||||
display: block; margin-top: 2px;
|
||||
font-size: .8rem; color: var(--text-leise);
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
.chat-pin__los {
|
||||
flex: none;
|
||||
appearance: none; border: 0; border-left: 1px solid color-mix(in srgb, var(--pin) 20%, transparent);
|
||||
background: none; padding: 0 10px;
|
||||
font: inherit; font-size: .72rem;
|
||||
color: var(--text-still); cursor: pointer;
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
.chat-pin__los:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
|
||||
.chat-pin__los:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.chat-pin__wer { display: none; }
|
||||
}
|
||||
|
||||
/* ---- Die angeheftete Nachricht im Verlauf --------------------------- */
|
||||
/* Ein schmaler Streifen an der Blase, mehr nicht. Wer im Verlauf
|
||||
zurückrollt, soll erkennen, dass genau DIESE Zeile oben hängt --
|
||||
ohne dass sie sich wie eine andere Sorte Nachricht liest. */
|
||||
.chat-nachricht[data-angeheftet="ja"] .chat-nachricht__blase {
|
||||
box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pin) 70%, transparent);
|
||||
}
|
||||
|
||||
/* Der Anheften-Knopf sieht aus wie "antworten" daneben -- dieselbe
|
||||
Sorte Handgriff, dieselbe Zeile, dieselbe Lautstärke. */
|
||||
.chat-nachricht__pin-knopf {
|
||||
appearance: none; border: 0; background: none; padding: 0;
|
||||
font: inherit; font-size: .72rem; font-weight: 600;
|
||||
color: inherit; cursor: pointer;
|
||||
text-decoration: underline; text-underline-offset: 2px;
|
||||
}
|
||||
.chat-nachricht__pin-knopf:hover { color: var(--pin); }
|
||||
.chat-nachricht__pin-knopf:focus-visible {
|
||||
outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ---- Wer ist im Kanal ----------------------------------------------- */
|
||||
/* Derselbe Knopf wie das Wegräumen, nur wird er beim Darüberfahren
|
||||
nicht rot: Leute hinzuzunehmen ist keine gefährliche Handlung. */
|
||||
.chat__leute { margin-left: auto; }
|
||||
.chat__leute + .chat__weg { margin-left: 6px; }
|
||||
.chat__leute:hover {
|
||||
color: var(--pin);
|
||||
border-color: color-mix(in srgb, var(--pin) 45%, transparent);
|
||||
}
|
||||
|
||||
/* ---- Die zwei Arten im Neu-Dialog ----------------------------------- */
|
||||
.neu__art {
|
||||
display: flex; gap: 6px;
|
||||
margin: 0 0 14px;
|
||||
padding: 4px;
|
||||
border: 1px solid var(--rand); border-radius: 12px;
|
||||
background: rgba(255, 255, 255, .02);
|
||||
}
|
||||
.neu__art button {
|
||||
flex: 1;
|
||||
appearance: none; border: 0; border-radius: 9px;
|
||||
padding: 8px 10px;
|
||||
background: none;
|
||||
font: inherit; font-size: .82rem; font-weight: 600;
|
||||
color: var(--text-still); cursor: pointer;
|
||||
transition: color var(--tempo), background var(--tempo);
|
||||
}
|
||||
.neu__art button[data-an="ja"] {
|
||||
background: color-mix(in srgb, var(--akzent) 14%, transparent);
|
||||
color: var(--text);
|
||||
}
|
||||
.neu__art button:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
|
||||
|
||||
.neu__hinweis {
|
||||
margin: 6px 0 0;
|
||||
font-size: .78rem; color: var(--text-still);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.chat-pin__auf, .chat-pin__los, .neu__art button { transition: none; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user