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]>
204 lines
8.0 KiB
JavaScript
204 lines
8.0 KiB
JavaScript
/* =====================================================================
|
||
DIE ZEICHEN ZUM REAGIEREN — Katalog, Vorschläge, Favoriten
|
||
(14.09.2026)
|
||
|
||
Filipe: "soll viel besser und geiler sein und man soll auch auswählen
|
||
können, also paar als vorschläge mit der möglichkeit andere
|
||
auszuwählen und als favoriten zu speichern."
|
||
|
||
---------------------------------------------------------------------
|
||
DREI LISTEN, DREI FRAGEN — und sie werden gern verwechselt:
|
||
|
||
KATALOG Was gibt es zur Auswahl? (fest, hier)
|
||
VORSCHLAG Was steht vorn, wenn ich (fest, hier — bis jemand
|
||
noch nichts gewählt habe? eigene Favoriten hat)
|
||
FAVORITEN Was hat DIESER Mensch (in der Datenbank)
|
||
sich gemerkt?
|
||
|
||
Nur der Katalog entscheidet, was angenommen wird. Vorschläge und
|
||
Favoriten sind Reihenfolge, keine Erlaubnis — sonst könnte man sich
|
||
über einen Favoriten etwas erlauben, das im Katalog nicht steht.
|
||
|
||
---------------------------------------------------------------------
|
||
WARUM EIN KATALOG UND NICHT "JEDES EMOJI"
|
||
|
||
Ein freies Feld nähme alles: 4-KB-Zeichenketten, unsichtbare
|
||
Steuerzeichen, Flaggen aus zwei zusammengesetzten Zeichen, die auf
|
||
dem einen Gerät eine Flagge sind und auf dem anderen zwei Buchstaben.
|
||
Was hier nicht drinsteht, kommt nicht in die Datenbank — und was
|
||
drinsteht, sieht überall gleich aus.
|
||
|
||
Der Katalog ist trotzdem groß genug, dass niemand etwas vermisst:
|
||
über hundert Zeichen in sechs Gruppen, jedes mit deutschen
|
||
Suchwörtern. Die Suche ist der eigentliche Unterschied zu einer
|
||
Tafel: Wer "feuer" tippt, muss nicht scrollen.
|
||
===================================================================== */
|
||
|
||
/** Jede Zeile: [Zeichen, Suchwörter (deutsch, durch Leerzeichen)].
|
||
* Die Suchwörter sind das, wonach jemand WIRKLICH sucht — nicht der
|
||
* offizielle Unicode-Name ("grinsendes Gesicht mit lachenden Augen"). */
|
||
export const KATALOG = [
|
||
{
|
||
name: "Zustimmung",
|
||
zeichen: [
|
||
["\u{1F44D}", "daumen hoch gut ok super ja"],
|
||
["\u{1F44E}", "daumen runter schlecht nein"],
|
||
["\u{1F44C}", "ok perfekt passt"],
|
||
["\u{1F64C}", "hurra jubel super geschafft"],
|
||
["\u{1F44F}", "klatschen applaus respekt bravo"],
|
||
["\u{1F91D}", "handschlag deal abgemacht"],
|
||
["✊", "faust power stark"],
|
||
["\u{1F4AA}", "muskel stark kraft"],
|
||
["\u{1F64F}", "danke bitte gebet respekt"],
|
||
["✅", "haken erledigt fertig"],
|
||
["\u{1F195}", "neu new"],
|
||
["\u{1F3AF}", "treffer ziel genau"],
|
||
],
|
||
},
|
||
{
|
||
name: "Gefühl",
|
||
zeichen: [
|
||
["❤️", "herz liebe lieb"],
|
||
["\u{1F9E1}", "herz orange"],
|
||
["\u{1F49B}", "herz gelb"],
|
||
["\u{1F49A}", "herz gruen"],
|
||
/* BABYBLAU STATT BLAU (22.09.2026). Filipe: "jedes normales
|
||
blaues herz durch babyblaues herz ersetzen ... jeder
|
||
normale blaue farbe, sei es die kachel im chat oder
|
||
emojis, nur babyblau bitte."
|
||
|
||
U+1FA75 gibt es seit Emoji 15.0 (2022). Nicht geglaubt,
|
||
sondern gemessen: In Chromium auf diesem Rechner ist es
|
||
43,9 px breit -- genauso breit wie die anderen Herzen und
|
||
deutlich breiter als ein Ersatzkaestchen (20,7 px). Waere
|
||
es nicht da, stuende im Chat ein leeres Viereck, und das
|
||
waere schlimmer als ein blaues Herz.
|
||
|
||
Die vier vorhandenen blauen Herzen in der Datenbank
|
||
wandern mit -- die Umstellung steht in workspace.js.
|
||
Ohne sie waeren es vier Reaktionen, die ERLAUBT nicht
|
||
mehr kennt: still weg, ohne dass jemand etwas bemerkt. */
|
||
["\u{1FA75}", "herz babyblau hellblau blau"],
|
||
["\u{1F49C}", "herz lila"],
|
||
["\u{1F5A4}", "herz schwarz"],
|
||
["\u{1F60D}", "verliebt herzaugen toll"],
|
||
["\u{1F970}", "suess niedlich lieb"],
|
||
["\u{1F618}", "kuss bussi"],
|
||
["\u{1F917}", "umarmung knuddel"],
|
||
["✨", "funkeln glanz besonders"],
|
||
],
|
||
},
|
||
{
|
||
name: "Lachen",
|
||
zeichen: [
|
||
["\u{1F602}", "lachen traenen lustig"],
|
||
["\u{1F923}", "totlachen rollen lustig"],
|
||
["\u{1F604}", "lachen froh"],
|
||
["\u{1F609}", "zwinkern augenzwinkern"],
|
||
["\u{1F60E}", "sonnenbrille cool"],
|
||
["\u{1F973}", "party feiern geburtstag"],
|
||
["\u{1F92A}", "quatsch albern zunge"],
|
||
["\u{1F643}", "umgedreht ironie"],
|
||
["\u{1F60F}", "schmunzeln frech"],
|
||
["\u{1F642}", "leicht laecheln"],
|
||
["\u{1F60A}", "froh zufrieden"],
|
||
["\u{1F92D}", "ups kichern hand vor mund"],
|
||
],
|
||
},
|
||
{
|
||
name: "Staunen",
|
||
zeichen: [
|
||
["\u{1F62E}", "oh staunen ueberrascht"],
|
||
["\u{1F631}", "schock erschrocken"],
|
||
["\u{1F92F}", "wow kopf explodiert krass"],
|
||
["\u{1F440}", "augen schauen hinsehen"],
|
||
["\u{1F914}", "nachdenken ueberlegen hm"],
|
||
["\u{1F928}", "skeptisch zweifel augenbraue"],
|
||
["\u{1F644}", "augenrollen genervt"],
|
||
["\u{1F925}", "luege pinocchio"],
|
||
["\u{1F633}", "peinlich rot"],
|
||
["\u{1F971}", "muede gaehnen"],
|
||
["\u{1F634}", "schlafen muede"],
|
||
["❓", "frage unklar"],
|
||
],
|
||
},
|
||
{
|
||
name: "Arbeit",
|
||
zeichen: [
|
||
["\u{1F525}", "feuer krass stark lit"],
|
||
["\u{1F680}", "rakete start schnell wachstum"],
|
||
["\u{1F4C8}", "diagramm hoch wachstum zahlen"],
|
||
["\u{1F4C9}", "diagramm runter weniger"],
|
||
["\u{1F4A1}", "idee gluehbirne einfall"],
|
||
["\u{1F4CC}", "pinnadel wichtig merken"],
|
||
["⚠️", "achtung warnung vorsicht"],
|
||
["\u{1F6A8}", "alarm dringend wichtig"],
|
||
["⏰", "wecker zeit termin"],
|
||
["\u{1F4C5}", "kalender termin datum"],
|
||
["\u{1F4B0}", "geld diamanten umsatz"],
|
||
["\u{1F48E}", "diamant edelstein wert"],
|
||
["\u{1F3C6}", "pokal sieg bester"],
|
||
["⭐", "stern gut bewertung"],
|
||
["\u{1F4DD}", "notiz schreiben aufgabe"],
|
||
["\u{1F50D}", "lupe suchen pruefen"],
|
||
["\u{1F4CE}", "anhang datei bueroklammer"],
|
||
["⚙️", "zahnrad technik einstellung"],
|
||
],
|
||
},
|
||
{
|
||
name: "Sonst",
|
||
zeichen: [
|
||
["\u{1F44B}", "winken hallo tschuess"],
|
||
["\u{1F3B5}", "musik ton sound"],
|
||
["\u{1F3A5}", "kamera video dreh"],
|
||
["\u{1F4F1}", "handy telefon app"],
|
||
["\u{1F4AC}", "sprechblase chat reden"],
|
||
["\u{1F37B}", "prost feiern bier"],
|
||
["☕", "kaffee pause"],
|
||
["\u{1F355}", "pizza essen"],
|
||
["\u{1F382}", "geburtstag torte"],
|
||
["\u{1F381}", "geschenk ueberraschung"],
|
||
["\u{1F340}", "kleeblatt glueck"],
|
||
["\u{1F308}", "regenbogen bunt"],
|
||
["☀️", "sonne schoen wetter"],
|
||
["\u{1F319}", "mond nacht spaet"],
|
||
["\u{1F415}", "hund dog dogi"],
|
||
["\u{1F336}️", "chili scharf spicy"],
|
||
],
|
||
},
|
||
];
|
||
|
||
/** Alles, was angenommen wird -- aus dem Katalog ABGELEITET.
|
||
* Eine zweite Liste daneben wäre die, in der ein Zeichen fehlt, das
|
||
* die Oberfläche anbietet. */
|
||
export const ERLAUBT = new Set(
|
||
KATALOG.flatMap((g) => g.zeichen.map(([z]) => z)));
|
||
|
||
/** Was vorn steht, solange jemand nichts Eigenes gewählt hat.
|
||
* Bewusst dieselben sechs wie am 14.09. früh: Wer sich daran gewöhnt
|
||
* hat, findet sie an derselben Stelle wieder. */
|
||
export const VORSCHLAG = ["\u{1F44D}", "❤️", "\u{1F602}",
|
||
"\u{1F62E}", "\u{1F525}", "\u{1F64F}"];
|
||
|
||
/** Wie viele Favoriten jemand ablegen darf.
|
||
*
|
||
* EINE OBERE GRENZE MUSS SEIN, sonst ist die Vorschlagszeile
|
||
* irgendwann die ganze Tafel -- und der Sinn der Vorschläge ist, dass
|
||
* man sie nicht lesen muss. Acht passt in eine Zeile, auch am Handy. */
|
||
export const FAVORITEN_MAX = 8;
|
||
|
||
/* Eine Selbstprüfung beim Laden: Doppelte im Katalog wären still --
|
||
sie erschienen zweimal in der Tafel, und niemand sucht danach.
|
||
Lieber beim Start laut als im Betrieb leise. */
|
||
{
|
||
const alle = KATALOG.flatMap((g) => g.zeichen.map(([z]) => z));
|
||
const doppelt = alle.filter((z, i) => alle.indexOf(z) !== i);
|
||
if (doppelt.length) {
|
||
console.error("[reaktionen] Doppelte Zeichen im Katalog:", doppelt.join(" "));
|
||
}
|
||
const fehlt = VORSCHLAG.filter((z) => !ERLAUBT.has(z));
|
||
if (fehlt.length) {
|
||
console.error("[reaktionen] Vorschlag steht nicht im Katalog:", fehlt.join(" "));
|
||
}
|
||
}
|