Eine Nachricht, die nicht ankommt, sieht man jetzt -- und schickt sie neu
DER KOMMENTAR STAND DA, DIE SACHE NICHT. Im Chat stand woertlich: "NICHT STILL VERSCHWINDEN LASSEN. Wer etwas schreibt und es sieht, glaubt, es sei angekommen." Gemessen: `markiereAlsGescheitert` setzte `n.gescheitert = true` -- und gelesen hat das Merkmal NIEMAND, weder das Skript noch das CSS. Eine gescheiterte Nachricht sah exakt aus wie eine zugestellte. Im CSS stand an der Stelle eine leere Regel mit dem Kommentar "Platzhalter, damit :has unterstuetzt bleibt". Ein Kommentar, der eine Absicht beschreibt, erfuellt sie nicht. Jetzt: sichtbare Kante an der Blase, blasse Darstellung solange sie unterwegs ist, und ein Knopf "Nochmal senden" daneben. Der Satz in der Meldezeile bat vorher ums Kopieren -- fuenf Handgriffe fuer etwas, das die Seite in einem tun kann; den Text hat sie ja noch. KEIN ZWEITER SENDEWEG: Der Knopf legt den Text zurueck ins Feld, stellt das Antwortziel wieder her und ruft `abschicken`. Ein eigener Weg waere morgen anders als dieser, und der Unterschied fiele erst auf, wenn er zaehlt. "ZUM NEUESTEN" STAND AUF EINER RECHNUNG VON GESTERN: `bottom: 96px` -- die Hoehe der Schreibleiste an dem Tag, an dem der Knopf gebaut wurde. Das Textfeld waechst aber bis 160. Wer lange tippt und gleichzeitig oben liest, hatte den Knopf HINTER der Leiste. Und darueber koennen noch das Nachtruhe-Band und der Hochlade-Balken stehen. Jetzt misst die Seite den ganzen Unterbau selbst -- ueber einen Beobachter statt einer Liste von Ausloesern, denn das Band erscheint um Mitternacht von selbst. Kommt morgen ein viertes Bauteil dazu, rechnet es von allein mit. NEUE PRUEFUNG FUER EINEN WEG, DEN NIE ETWAS GEPRUEFT HAT: pruef-chat-optik faengt die Sendeanfrage jetzt einmal ab und geht den ganzen Fehlerweg durch -- 10 Aussagen, darunter: der Unterschied ist auch zu SEHEN, nicht nur im Merkmal (Rand 1px) die Nachricht steht danach GENAU EINMAL da, nicht doppelt und sie ist beim Gegenueber angekommen Der letzte ist der eigentliche: Alles davor koennte gut aussehen und trotzdem nichts zugestellt haben. pruef-treffchat war seit gestern rot -- 8 Fehler ueber "undefined". Sie suchte die Kachel mit `ziel === "chat.html"`, seit dem 19.09. heisst es `chat.html?raum=treff` (sie fuehrt direkt in den Raum). Kein Befund ueber das Haus, sondern einer ueber sich selbst. Sie sucht jetzt nach der SEITE und prueft statt des Wortlauts das, worauf es ankommt: Man erkennt den Chat, und der Name kommt genau einmal vor. 110/0 statt 108 mit 8 Fehlern. pruef-chat, -anhaenge, -kanaele, -optik, -ausbau gruen, pruef-start-ansicht 151/0, pruef-tippziele 11/0, pruef-nachfrage 33/0, pruef-leerzustand 13/0, pruef-meldungen 8/0, pruef-css-klassen gruen.
This commit is contained in:
@@ -386,8 +386,12 @@
|
||||
.chat-nachricht__weg-knopf:focus-visible { opacity: 1; }
|
||||
.chat-nachricht__weg-knopf:hover { color: var(--warn); }
|
||||
|
||||
/* Unterwegs und gescheitert -- der Unterschied muss sichtbar sein. */
|
||||
.chat-nachricht__blase:has(+ *) { /* Platzhalter, damit :has unterstützt bleibt */ }
|
||||
/* Unterwegs und gescheitert: siehe ganz unten in dieser Datei.
|
||||
Hier stand bis zum 20.09.2026 eine Regel ohne Inhalt --
|
||||
`.chat-nachricht__blase:has(+ *) { }` mit dem Kommentar
|
||||
„Platzhalter, damit :has unterstützt bleibt". Sie hat nie etwas
|
||||
getan, und darunter fehlte genau das, was der Kommentar darüber
|
||||
versprach. */
|
||||
|
||||
/* ---------- Das Eingabefeld ---------------------------------------------- */
|
||||
|
||||
@@ -946,8 +950,18 @@
|
||||
.chat__zeichen[data-eng="ja"] { color: var(--warn, #ff9aa2); }
|
||||
|
||||
/* ---- Zum neuesten ---------------------------------------------------- */
|
||||
/* DIE 96 WAR EINE RECHNUNG VON GESTERN (20.09.2026).
|
||||
Hier stand `bottom: 96px` -- die Höhe der Schreibleiste, gemessen
|
||||
an dem Tag, an dem sie gebaut wurde. Das Textfeld wächst aber mit
|
||||
dem Text, bis auf 160 Pixel. Wer einen langen Text tippt und
|
||||
gleichzeitig weiter oben liest, hatte den Knopf HINTER der Leiste.
|
||||
|
||||
Jetzt sagt die Leiste selbst, wie hoch sie ist: `chat.js` schreibt
|
||||
`--leiste` bei jeder Höhenänderung. Der Rückfallwert gilt nur, bis
|
||||
das Skript einmal gerechnet hat. */
|
||||
.chat__zum-neuesten {
|
||||
position: absolute; left: 50%; bottom: 96px;
|
||||
position: absolute; left: 50%;
|
||||
bottom: calc(var(--leiste, 96px) + 12px);
|
||||
transform: translateX(-50%);
|
||||
z-index: 4;
|
||||
padding: 9px 18px;
|
||||
@@ -1935,3 +1949,46 @@
|
||||
.anruf__schalter[aria-pressed="false"] { border-style: dashed; border-width: 2px; }
|
||||
.anruf__auf { border-width: 2px; }
|
||||
}
|
||||
|
||||
/* ---- Unterwegs und gescheitert -------------------------------------
|
||||
Gemessen am 20.09.2026: BEIDE Zustände waren unsichtbar.
|
||||
`markiereAlsGescheitert` setzte das Merkmal und zeichnete neu --
|
||||
gelesen hat es niemand, weder Skript noch CSS. Eine gescheiterte
|
||||
Nachricht sah genauso aus wie eine zugestellte.
|
||||
|
||||
Daneben stand im Code: „NICHT STILL VERSCHWINDEN LASSEN. Wer etwas
|
||||
schreibt und es sieht, glaubt, es sei angekommen." Genau das ist
|
||||
trotzdem passiert. Ein Kommentar, der eine Absicht beschreibt,
|
||||
erfüllt sie nicht.
|
||||
|
||||
Unterwegs = blass, es passiert noch etwas.
|
||||
Gescheitert = eine sichtbare Kante und ein Knopf daneben. Nicht
|
||||
knallrot: Es ist ein Zustand, kein Alarm -- und meistens ist nur
|
||||
das Netz kurz weg. */
|
||||
.chat-nachricht[data-unterwegs="ja"] .chat-nachricht__blase { opacity: .62; }
|
||||
|
||||
.chat-nachricht[data-gescheitert="ja"] .chat-nachricht__blase {
|
||||
border: 1px solid color-mix(in srgb, var(--warn) 52%, transparent);
|
||||
background: color-mix(in srgb, var(--warn) 9%, transparent);
|
||||
}
|
||||
.chat-nachricht__nochmal {
|
||||
display: block;
|
||||
margin: 8px 0 0;
|
||||
/* 44, weil man das hier mit dem Daumen trifft -- und zwar in dem
|
||||
Moment, in dem man ohnehin schon genervt ist. */
|
||||
min-height: 44px; padding: 0 14px;
|
||||
font: inherit; font-size: .82rem; font-weight: 650;
|
||||
color: var(--text);
|
||||
background: transparent;
|
||||
border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--rand));
|
||||
border-radius: var(--radius, 10px);
|
||||
cursor: pointer;
|
||||
}
|
||||
.chat-nachricht__nochmal:hover:not(:disabled) { border-color: var(--warn); }
|
||||
.chat-nachricht__nochmal:disabled { opacity: .6; cursor: default; }
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.chat-nachricht[data-gescheitert="ja"] .chat-nachricht__blase {
|
||||
border: 2px solid CanvasText;
|
||||
}
|
||||
}
|
||||
|
||||
+119
-1
@@ -990,6 +990,24 @@
|
||||
zeile.dataset.id = String(n.id);
|
||||
if (n.selbst) zeile.dataset.selbst = 'ja';
|
||||
if (n.zurueckgenommen) zeile.dataset.weg = 'ja';
|
||||
/* UNTERWEGS UND GESCHEITERT SIND ZWEI ZUSTÄNDE -- UND BEIDE
|
||||
WAREN UNSICHTBAR (20.09.2026).
|
||||
------------------------------------------------------------
|
||||
`markiereAlsGescheitert` setzte `n.gescheitert = true` und
|
||||
zeichnete neu. Gelesen hat das Merkmal NIEMAND: weder das
|
||||
Skript noch das CSS. Eine gescheiterte Nachricht sah exakt
|
||||
aus wie eine zugestellte.
|
||||
|
||||
Daneben stand der Kommentar „NICHT STILL VERSCHWINDEN LASSEN.
|
||||
Wer etwas schreibt und es sieht, glaubt, es sei angekommen."
|
||||
Genau das ist trotzdem passiert -- der Satz in der Meldezeile
|
||||
verschwindet nach kurzer Zeit, die Nachricht bleibt stehen
|
||||
und sieht gesendet aus.
|
||||
|
||||
Ein Kommentar, der eine Absicht beschreibt, erfüllt sie
|
||||
nicht. */
|
||||
if (n.unterwegs) zeile.dataset.unterwegs = 'ja';
|
||||
if (n.gescheitert) zeile.dataset.gescheitert = 'ja';
|
||||
/* Mehrere Nachrichten derselben Person hintereinander rücken
|
||||
zusammen und wiederholen den Namen nicht -- sonst liest man
|
||||
fünfmal "Patrick" und dreimal dasselbe Gesicht. */
|
||||
@@ -1138,6 +1156,33 @@
|
||||
if (Array.isArray(n.reaktionen) && n.reaktionen.length) {
|
||||
blase.append(reaktionenBauen(n));
|
||||
}
|
||||
/* NOCHMAL SENDEN, STATT „kopiere sie und versuch es erneut".
|
||||
------------------------------------------------------------
|
||||
Dort stand die Seite bat den Nutzer, ihre Arbeit zu machen:
|
||||
Text markieren, kopieren, Feld leeren, einfügen, senden. Fünf
|
||||
Handgriffe für etwas, das die Seite in einem tun kann -- sie
|
||||
hat den Text ja noch. */
|
||||
if (n.gescheitert) {
|
||||
const nochmal = el('button', 'chat-nachricht__nochmal', 'Nochmal senden');
|
||||
nochmal.type = 'button';
|
||||
nochmal.addEventListener('click', async () => {
|
||||
nochmal.disabled = true;
|
||||
nochmal.textContent = 'wird gesendet …';
|
||||
/* DENSELBEN WEG GEHEN WIE VON HAND -- nur ohne die fünf
|
||||
Handgriffe. Text zurück ins Feld, Antwortziel wieder
|
||||
setzen, `abschicken` aufrufen. Kein zweiter Sendeweg:
|
||||
Ein eigener wäre morgen anders als dieser, und der
|
||||
Unterschied fiele erst auf, wenn er zählt. */
|
||||
const weg = nachrichten.findIndex((x) => x.id === n.id);
|
||||
if (weg >= 0) nachrichten.splice(weg, 1);
|
||||
$('text').value = n.text;
|
||||
if (n.antwort) antwortSetzen(n.antwort);
|
||||
melde('');
|
||||
await abschicken({ preventDefault() {} });
|
||||
});
|
||||
blase.append(nochmal);
|
||||
}
|
||||
|
||||
zeile.append(blase);
|
||||
ziel.append(zeile);
|
||||
}
|
||||
@@ -1414,7 +1459,10 @@
|
||||
const i = nachrichten.findIndex((n) => n.id === id);
|
||||
if (i >= 0) { nachrichten[i].gescheitert = true; delete nachrichten[i].unterwegs; }
|
||||
verlaufZeichnen();
|
||||
melde(`${grund} Die Nachricht steht noch da – kopiere sie und versuch es erneut.`);
|
||||
/* Kein „kopiere sie" mehr -- an der Nachricht steht jetzt ein
|
||||
Knopf, der es in einem Griff wiederholt. */
|
||||
melde(`${grund} Die Nachricht ist nicht angekommen – `
|
||||
+ `mit „Nochmal senden" kannst du es gleich wiederholen.`);
|
||||
}
|
||||
|
||||
async function zuruecknehmen(id) {
|
||||
@@ -1440,6 +1488,74 @@
|
||||
const f = $('text');
|
||||
f.style.height = 'auto';
|
||||
f.style.height = Math.min(f.scrollHeight, 160) + 'px';
|
||||
/* DIE LEISTE SAGT, WIE HOCH SIE IST (20.09.2026).
|
||||
Der Knopf „Zum neuesten" schwebte auf festen 96 Pixeln -- der
|
||||
Höhe der Leiste an dem Tag, an dem er gebaut wurde. Wächst das
|
||||
Textfeld (bis 160), verschwindet er dahinter, und zwar genau
|
||||
dann, wenn man lange tippt und gleichzeitig oben liest.
|
||||
Gemessen statt gerechnet: Eine Zahl, die das Element selbst
|
||||
kennt, kann nicht veralten. */
|
||||
unterbauMessen();
|
||||
}
|
||||
|
||||
/** Wie hoch ist alles, was UNTEN am Verlauf klebt?
|
||||
*
|
||||
* Nicht nur die Schreibleiste: Darüber können das Nachtruhe-Band
|
||||
* und der Hochlade-Balken stehen. Wer nur die Leiste misst, legt
|
||||
* den Knopf „Zum neuesten" nachts hinter das Band.
|
||||
*
|
||||
* Gemessen wird vom unteren Rand des Kastens bis zur obersten
|
||||
* Kante des sichtbaren Unterbaus -- egal, aus wie vielen Teilen er
|
||||
* gerade besteht. Kommt morgen ein viertes dazu, rechnet es von
|
||||
* selbst mit. */
|
||||
function unterbauMessen() {
|
||||
const leiste = $('schreiben');
|
||||
const kasten = leiste?.parentElement;
|
||||
if (!kasten) return;
|
||||
const unten = kasten.getBoundingClientRect().bottom;
|
||||
let oberste = unten;
|
||||
for (const id of ['nachtruhe', 'anhang-fortschritt', 'schreiben']) {
|
||||
const e = $(id);
|
||||
if (!e || e.hidden) continue;
|
||||
const r = e.getBoundingClientRect();
|
||||
if (r.height > 0 && r.top < oberste) oberste = r.top;
|
||||
}
|
||||
const hoch = Math.max(0, Math.round(unten - oberste));
|
||||
/* NUR SETZEN, WENN SICH ETWAS AENDERT. Sonst beisst sich der
|
||||
Beobachter unten in den eigenen Schwanz: Eine Stil-Aenderung am
|
||||
Kasten ist selbst wieder eine Aenderung. */
|
||||
if (hoch === letzteLeiste) return;
|
||||
letzteLeiste = hoch;
|
||||
kasten.style.setProperty('--leiste', hoch + 'px');
|
||||
}
|
||||
let letzteLeiste = -1;
|
||||
|
||||
/** DER UNTERBAU AENDERT SICH AUCH OHNE TIPPEN.
|
||||
*
|
||||
* Das Nachtruhe-Band erscheint um Mitternacht von selbst, der
|
||||
* Hochlade-Balken beim Anhaengen einer Datei. `hoeheAnpassen`
|
||||
* laeuft dabei nicht -- der Knopf „Zum neuesten" staende dann
|
||||
* wieder hinter etwas.
|
||||
*
|
||||
* Ein Beobachter statt einer Liste von Ausloesern: Was sich am
|
||||
* unteren Rand tut, wird bemerkt, auch wenn es morgen ein viertes
|
||||
* Bauteil ist. Gerechnet wird hoechstens einmal je Bild -- sonst
|
||||
* waere jede getippte Zeile eine Messung. */
|
||||
function unterbauBeobachten() {
|
||||
const kasten = $('schreiben')?.parentElement;
|
||||
if (!kasten || !window.MutationObserver) return;
|
||||
let geplant = false;
|
||||
new MutationObserver(() => {
|
||||
if (geplant) return;
|
||||
geplant = true;
|
||||
requestAnimationFrame(() => { geplant = false; unterbauMessen(); });
|
||||
}).observe(kasten, {
|
||||
childList: true, subtree: true,
|
||||
attributes: true, attributeFilter: ['hidden', 'class'],
|
||||
});
|
||||
/* Und beim Drehen des Geräts: Dort ändert sich nichts am Aufbau,
|
||||
aber alles an der Breite -- und damit an der Zeilenzahl. */
|
||||
window.addEventListener('resize', () => unterbauMessen());
|
||||
}
|
||||
|
||||
/* ---------- Gelesen ------------------------------------------------------ */
|
||||
@@ -2327,6 +2443,8 @@
|
||||
|
||||
await raeumeLaden();
|
||||
stromOeffnen();
|
||||
unterbauBeobachten();
|
||||
unterbauMessen();
|
||||
|
||||
/* Kommt man aus einer Benachrichtigung, steht das Gespräch in der
|
||||
Adresse -- dann direkt hinein. */
|
||||
|
||||
Reference in New Issue
Block a user