diff --git a/server/pruef-anruf.mjs b/server/pruef-anruf.mjs index 692b7fe9..2782cbac 100644 --- a/server/pruef-anruf.mjs +++ b/server/pruef-anruf.mjs @@ -631,6 +631,30 @@ melde("=== 7. Im Browser ==="); viewport: { width: 1280, height: 900 }, permissions: ["microphone", "camera"], }); + + /* TOENE MITZAEHLEN -- vor allem anderen. + + Filipe: „ist das normal dass es nicht mal klingelt wenn man + anruft?" Nein: Es gab gar keinen Ton. Der Anruf zeigte einen + Kasten, sonst nichts. + + Gemessen wird am Oszillator, nicht am Lautsprecher. Ob wirklich + etwas zu hoeren ist, haengt an Geraet, Lautstaerke und daran, + ob der Browser Ton schon erlaubt -- das kann keine Pruefung + beantworten. Dass die Seite Toene ERZEUGT, kann sie sehr wohl. + + `addInitScript` laeuft vor jedem Skript der Seite; danach + waere der Zaehler zu spaet. */ + await sicht.addInitScript(() => { + window.__toene = 0; + const K = window.AudioContext || window.webkitAudioContext; + if (!K) return; + const alt = K.prototype.createOscillator; + K.prototype.createOscillator = function (...w) { + window.__toene = (window.__toene || 0) + 1; + return alt.apply(this, w); + }; + }); await sicht.addCookies(kDogi.split("; ").map((c) => { const [name, ...rest] = c.split("="); return { name, value: rest.join("="), domain: "127.0.0.1", path: "/" }; @@ -676,6 +700,11 @@ melde("=== 7. Im Browser ==="); `und sagt, was gerade passiert ("${kasten.lage}")`); ok(/^\d\d:\d\d$/.test(kasten.zeit), `die Uhr laeuft (${kasten.zeit})`); + /* Und es klingelt hoerbar. Waere der Ton wieder ausgebaut, + stuende hier 0. */ + const toene = await seite.evaluate(() => window.__toene ?? -1); + ok(toene > 0, `es klingelt hoerbar -- ${toene} Toene erzeugt`); + /* Und der Server weiss davon. */ const l = json(await roh(`/workspace/api/anruf/${raumId}`, HAUS, { cookie: kDogi })); ok(l.laeuft === true, "der Server kennt den Anruf"); diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 020af340..19706be4 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609182330", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609182358", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609182330", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609182358", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609182330", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609182358", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609182330", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609182358", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/js/anruf.js b/workspace/assets/js/anruf.js index 5230f1ed..ff225590 100644 --- a/workspace/assets/js/anruf.js +++ b/workspace/assets/js/anruf.js @@ -159,7 +159,12 @@ }; v.onconnectionstatechange = () => { - if (v.connectionState === 'connected') lage('Verbunden'); + if (v.connectionState === 'connected') { + /* Ab hier redet man miteinander -- ein Freizeichen daneben + waere das, was man an einer Telefonanlage hasst. */ + tonAus(); + lage('Verbunden'); + } /* `failed` heisst: Es kommt nichts mehr. Das gehoert gesagt -- ein Kasten, der ewig „Verbindung …" zeigt, laesst einen warten, wo nichts mehr kommt. */ @@ -268,6 +273,9 @@ $('anruf-video').hidden = !mitVideo; if (mitVideo) $('anruf-video').setAttribute('aria-pressed', 'true'); lage('Es klingelt …'); + /* DAS FREIZEICHEN. Ein stiller Kasten mit laufender Uhr sagt nur, + dass etwas passiert -- nicht, was. */ + freiTon(); uhrLaufen(); const a = await fetch(`/workspace/api/anruf/${raumId}/start`, { @@ -334,6 +342,7 @@ } async function auflegen(melden) { + tonAus(); klingelnAus(); if (!anruf) { const k = $('anruf'); if (k) k.hidden = true; return; } const raumId = anruf.raumId; @@ -525,6 +534,9 @@ function klingelnZeigen(raumId, von, mitVideo) { klingelnAus(); + /* UND ES KLINGELT WIRKLICH. Vorher stand hier nur ein Kasten -- + wer nicht zufaellig hinsah, merkte nichts. */ + klingelTon(); const k = el('div', 'anruf-klingelt'); k.id = 'anruf-klingelt'; k.setAttribute('role', 'alertdialog'); @@ -548,7 +560,87 @@ zu einem Gespräch da, an dem längst niemand mehr teilnimmt. */ setTimeout(klingelnAus, 46000); } - function klingelnAus() { $('anruf-klingelt')?.remove(); } + /* ---------- DER KLINGELTON (18.09.2026) -------------------------- + + Filipe: „ist das normal dass es nicht mal klingelt wenn man + anruft?" + + Nein. Es gab gar keinen Ton -- weder beim Anrufer noch beim + Angerufenen. Ein Anruf zeigte einen Kasten auf dem Bildschirm, + sonst nichts. Wer nicht zufaellig hinsah, merkte nichts; und wer + anrief, wusste nie, ob ueberhaupt etwas passiert. Genau das + fuehlt sich an wie „geht nicht". + + OHNE TONDATEI. Ein Klingelton als .mp3 waere eine Datei mehr im + Netz, eine Lizenzfrage und ein Ladefehler, der genau dann + auffaellt, wenn man ihn braucht. Zwei Sinustoene aus dem Browser + reichen -- das ist, was ein Telefon auch tut. + + LEISE UND KURZ. Kein durchdringendes Schrillen: zwei weiche + Toene, dann Pause. Das traegt durch einen Raum, ohne jemanden zu + erschrecken -- dieselbe Ueberlegung wie bei allem Sichtbaren hier. + + WARUM ES TROTZDEM STUMM BLEIBEN KANN: Browser lassen Ton erst zu, + wenn jemand auf der Seite etwas angeklickt hat. Wer die Seite + gerade erst geoeffnet hat, hoert deshalb unter Umstaenden nichts + -- dann bleibt die Benachrichtigung des Geraets der Weg. Das ist + eine Regel des Browsers, keine Entscheidung von uns. */ + + let tonWerk = null; /* der Taktgeber, solange es klingelt */ + let tonRaum = null; /* AudioContext -- erst bei Bedarf */ + + function tonAn(hoehe, laenge, lautstaerke) { + try { + if (!tonRaum) { + const K = window.AudioContext || window.webkitAudioContext; + if (!K) return; + tonRaum = new K(); + } + if (tonRaum.state === 'suspended') tonRaum.resume().catch(() => {}); + const o = tonRaum.createOscillator(); + const v = tonRaum.createGain(); + o.type = 'sine'; + o.frequency.value = hoehe; + /* Sanft ein und aus: Ein hart geschalteter Sinus knackt, und + genau das Knacken ist das Unangenehme daran. */ + const t = tonRaum.currentTime; + v.gain.setValueAtTime(0, t); + v.gain.linearRampToValueAtTime(lautstaerke, t + 0.03); + v.gain.linearRampToValueAtTime(0, t + laenge); + o.connect(v).connect(tonRaum.destination); + o.start(t); + o.stop(t + laenge + 0.05); + } catch { /* kein Ton -- die Benachrichtigung bleibt der Weg */ } + } + + /** Es klingelt bei dem, der angerufen wird: zwei Toene, dann Pause. */ + function klingelTon() { + tonAus(); + const takt = () => { tonAn(880, 0.22, 0.16); setTimeout(() => tonAn(660, 0.26, 0.16), 300); }; + takt(); + tonWerk = setInterval(takt, 2400); + /* Und das Geraet darf mitvibrieren, wo es das kann. */ + try { navigator.vibrate?.([250, 200, 250]); } catch { /* egal */ } + } + + /** Das Freizeichen bei dem, der anruft -- leiser und langsamer. + * + * Damit er weiss, DASS es laeuft. Ein stiller Kasten mit einer + * laufenden Uhr sagt nur, dass etwas passiert; ein Freizeichen + * sagt, WAS. */ + function freiTon() { + tonAus(); + const takt = () => tonAn(440, 0.5, 0.07); + takt(); + tonWerk = setInterval(takt, 3000); + } + + function tonAus() { + if (tonWerk) { clearInterval(tonWerk); tonWerk = null; } + try { navigator.vibrate?.(0); } catch { /* egal */ } + } + + function klingelnAus() { tonAus(); $('anruf-klingelt')?.remove(); } /* ---------- Was vom Server kommt --------------------------------------- */ @@ -561,6 +653,9 @@ return; } if (d.art === 'dabei') { + /* Jemand ist rangegangen -- auch wenn die Verbindung noch ein + paar Sekunden braucht, klingelt hier nichts mehr. */ + tonAus(); if (!anruf || d.raum_id !== anruf.raumId) return; if (d.person?.id === ichId) return; /* NICHT „Verbunden" MELDEN, SOLANGE NICHTS VERBUNDEN IST. diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 087df9b7..710efe72 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - + @@ -291,10 +291,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index b5db26bb..b49d57c1 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -168,10 +168,10 @@ - - - - - + + + + + diff --git a/workspace/befinden.html b/workspace/befinden.html index b5d1face..5f2ab9eb 100644 --- a/workspace/befinden.html +++ b/workspace/befinden.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -105,9 +105,9 @@ - - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 3339637e..55c96ed5 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -12,24 +12,24 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - - + + - + @@ -251,14 +251,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/bewerben.html b/workspace/bewerben.html index 055c96da..89721cf0 100644 --- a/workspace/bewerben.html +++ b/workspace/bewerben.html @@ -7,17 +7,17 @@ - - - - - - - - - + + + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/bewerbungen.html b/workspace/bewerbungen.html index 4cda9dc2..9da537f3 100644 --- a/workspace/bewerbungen.html +++ b/workspace/bewerbungen.html @@ -7,16 +7,16 @@ - - - - - - - - + + + + + + + + - + @@ -80,10 +80,10 @@ - - - - - + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 599554be..889e6bc2 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -89,11 +89,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index d124a10d..d70168ab 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -12,26 +12,26 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -341,15 +341,15 @@ - - - - + + + + - - + + diff --git a/workspace/content.html b/workspace/content.html index e60a0a26..77962c49 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -179,12 +179,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/crew-index.html b/workspace/crew-index.html index 07efdc27..9878b47a 100644 --- a/workspace/crew-index.html +++ b/workspace/crew-index.html @@ -36,15 +36,15 @@ - - - + + + - + @@ -339,6 +339,6 @@ - + diff --git a/workspace/crew.webmanifest b/workspace/crew.webmanifest index 7026f8cc..5a3f6b3c 100644 --- a/workspace/crew.webmanifest +++ b/workspace/crew.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/crew-192.png?v=202609182330", + "src": "/assets/img/app-symbole/crew-192.png?v=202609182358", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-512.png?v=202609182330", + "src": "/assets/img/app-symbole/crew-512.png?v=202609182358", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609182330", + "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609182358", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609182330", + "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609182358", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/dateien.html b/workspace/dateien.html index 5f894ba1..accc68e8 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/entwicklung.html b/workspace/entwicklung.html index f5008544..713ce4e6 100644 --- a/workspace/entwicklung.html +++ b/workspace/entwicklung.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -102,9 +102,9 @@ - - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index 0c6b8b4a..180bb126 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -30,9 +30,9 @@ - - - + + + @@ -401,6 +401,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index 858b62b1..4a18d0c7 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -377,11 +377,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index 9f804f11..eefe24b8 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -444,10 +444,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index c0e5a27d..e282cde9 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -423,10 +423,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 27ff14c8..4b2229f7 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -214,11 +214,11 @@ - - - - - - + + + + + + diff --git a/workspace/rechte.html b/workspace/rechte.html index 86e097b3..95dbcc0c 100644 --- a/workspace/rechte.html +++ b/workspace/rechte.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -134,9 +134,9 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - + + + + diff --git a/workspace/report.html b/workspace/report.html index 28c770ed..9d6ef9e9 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -106,11 +106,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index f805334c..a684c9d4 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -173,10 +173,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index 45feb20e..a8e62324 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -12,21 +12,21 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - + + - + @@ -678,10 +678,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index b8c51663..3244b47c 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -85,11 +85,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index cf58b649..ff1cd957 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -146,11 +146,11 @@ - - - - - - + + + + + + diff --git a/workspace/talente.html b/workspace/talente.html index f0087459..d37f76a6 100644 --- a/workspace/talente.html +++ b/workspace/talente.html @@ -7,18 +7,18 @@ - - - - - - + + + + + + - - - + + + @@ -111,9 +111,9 @@ - - - - + + + + diff --git a/workspace/team.html b/workspace/team.html index 7b58c60c..2f3c81ee 100644 --- a/workspace/team.html +++ b/workspace/team.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + @@ -110,10 +110,10 @@ - - - - - + + + + + diff --git a/workspace/teamlage.html b/workspace/teamlage.html index 0c2b4d46..f18ddd98 100644 --- a/workspace/teamlage.html +++ b/workspace/teamlage.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + - - - - + + + + diff --git a/workspace/teilen.html b/workspace/teilen.html index 7106e0e2..5e25087d 100644 --- a/workspace/teilen.html +++ b/workspace/teilen.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -112,9 +112,9 @@ - - - - + + + + diff --git a/workspace/treff-moderation.html b/workspace/treff-moderation.html index aee03b66..47876f91 100644 --- a/workspace/treff-moderation.html +++ b/workspace/treff-moderation.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -126,9 +126,9 @@ - - - - + + + + diff --git a/workspace/treff-regeln.html b/workspace/treff-regeln.html index f0f99e57..a970d51a 100644 --- a/workspace/treff-regeln.html +++ b/workspace/treff-regeln.html @@ -7,18 +7,18 @@ - - - - - - - + + + + + + + - + @@ -221,10 +221,10 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index acd62aab..f237ae52 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -12,22 +12,22 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -149,11 +149,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index f4872919..faa249ee 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -190,10 +190,10 @@ - - - - - + + + + +