diff --git a/server/pruef-anruf.mjs b/server/pruef-anruf.mjs index fdcb385f..cf802d49 100644 --- a/server/pruef-anruf.mjs +++ b/server/pruef-anruf.mjs @@ -628,6 +628,58 @@ melde("=== 8. Zu dritt ==="); `${wer} hoert BEIDE anderen (${z.stroeme} Stroeme, „${z.lage}")`); } + /* ---- DER LAUTSPRECHER (18.09.2026) ------------------------- + Filipe: „die funktion lautsprecher fehlt." + + Gegenstueck zum Mikrofon: „Mikro aus" heisst, die anderen + hoeren mich nicht; „Lautsprecher aus" heisst, ich hoere sie + nicht. + + DIE PRUEFUNG, AUF DIE ES ANKOMMT, ist die dritte: Kommt + jemand dazu oder geht jemand, werden die Toenelemente NEU + GEBAUT -- und neue Elemente wissen nichts von einem Schalter, + der vorher umgelegt wurde. Genau daran scheitern solche + Knoepfe sonst: Sie wirken, bis sich die Runde aendert, und + dann hoert man ploetzlich wieder mit. */ + const stumm = (x) => x.se.evaluate(() => + [...document.querySelectorAll("#anruf-leute audio, #anruf-leute video")] + .filter((m) => !m.classList.contains("anruf__bild--ich")) + .map((m) => m.muted)); + + { + const vorher = await stumm(a); + /* Die ANZAHL gehoert in die Bedingung: `every` ist auf einer + leeren Liste wahr, und dann waere diese Pruefung gruen, + ohne ein einziges Element gesehen zu haben. */ + ok(vorher.length >= 2 && vorher.every((m) => m === false), + `vorher hoert DogFather beide (${vorher.length} Stroeme, keiner stumm)`); + + const knopf = await a.se.evaluate(() => { + const k = document.getElementById("anruf-hoeren"); + return k ? { text: k.textContent.trim(), an: k.getAttribute("aria-pressed") } : null; + }); + ok(knopf?.text === "Lautsprecher an" && knopf?.an === "true", + `der Lautsprecher-Knopf ist da und steht auf an („${knopf?.text}")`); + + await a.se.click("#anruf-hoeren"); + await a.se.waitForTimeout(300); + const nachher = await stumm(a); + ok(nachher.length >= 2 && nachher.every((m) => m === true), + `nach dem Druecken ist ALLES stumm (${nachher.length} Stroeme)`); + const knopf2 = await a.se.evaluate(() => { + const k = document.getElementById("anruf-hoeren"); + return { text: k.textContent.trim(), an: k.getAttribute("aria-pressed") }; + }); + ok(knopf2.text === "Lautsprecher aus" && knopf2.an === "false", + `und der Knopf sagt es auch („${knopf2.text}")`); + + /* NUR BEI IHM. Ein Schalter, der bei den anderen mitwirkt, + waere kein Lautsprecher, sondern eine Fernbedienung. */ + const beiB = await stumm(b); + ok(beiB.length >= 2 && beiB.every((m) => m === false), + `bei der rechten Hand aendert sich nichts (${beiB.length} Stroeme, keiner stumm)`); + } + /* Einer legt auf -- fuer die anderen laeuft es weiter. */ await c.se.click("#anruf-auflegen"); await c.se.waitForTimeout(2000); @@ -638,6 +690,17 @@ melde("=== 8. Zu dritt ==="); ok(zA.stroeme === 1, `und bei DogFather ist genau ein Strom weniger (${zA.stroeme})`); + /* DIE FALLE: Die Runde hat sich geaendert, die Elemente wurden + neu gebaut. Bliebe der Schalter dabei auf der Strecke, wuerde + DogFather ploetzlich wieder mithoeren -- ohne dass irgendwo + etwas anders aussieht. */ + const nachWechsel = await stumm(a); + ok(nachWechsel.length === 1 && nachWechsel[0] === true, + `und der Lautsprecher bleibt aus, obwohl neu gezeichnet wurde (${nachWechsel.length} Strom)`); + const knopfNoch = await a.se.evaluate(() => + document.getElementById("anruf-hoeren")?.getAttribute("aria-pressed")); + ok(knopfNoch === "false", "auch der Knopf steht noch richtig"); + await a.se.click("#anruf-auflegen"); await b.se.click("#anruf-auflegen"); await a.se.waitForTimeout(1200); diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 272e8a3d..1300784c 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609181700", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609181708", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609181700", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609181708", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609181700", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609181708", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609181700", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609181708", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/css/chat.css b/workspace/assets/css/chat.css index 34a94278..310d0a49 100644 --- a/workspace/assets/css/chat.css +++ b/workspace/assets/css/chat.css @@ -1598,6 +1598,22 @@ } .anruf__knopf--auf:hover { border-color: var(--warn, #ff9aa2); } +/* Wohin der Ton geht -- nur auf Rechnern, wo der Browser das wirklich + umstellen kann. Schmal gehalten: Geraetenamen wie „Kopfhoerer + (RODECaster Duo Main)" wuerden die Knopfreihe sonst sprengen. */ +.anruf__ausgabe { + max-width: 11rem; + min-height: 40px; + padding: 6px 10px; + border: 1px solid var(--rand-hell); + border-radius: 999px; + background: color-mix(in srgb, var(--tinte) 88%, #ffffff 12%); + color: var(--text); + font: inherit; font-size: .8rem; + text-overflow: ellipsis; +} +.anruf__ausgabe:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; } + /* --------------------------------------------------------------------- ES KLINGELT diff --git a/workspace/assets/js/anruf.js b/workspace/assets/js/anruf.js index 05c47cc1..ed5a6e77 100644 --- a/workspace/assets/js/anruf.js +++ b/workspace/assets/js/anruf.js @@ -118,12 +118,15 @@