| index 03271fd..9f96200 100644 |
| --- a/web/static/chat.js |
| +++ b/web/static/chat.js |
| @@ -133,6 +133,18 @@ function setupMenu(session) { |
| } |
| if (!pushAvailable()) return; |
| const item = document.getElementById("menu-notif"); |
| + // Request permission FIRST, still inside the click gesture — Safari rejects |
| + // requestPermission() if it's called after an await (e.g. an IndexedDB read). |
| + if (Notification.permission === "default") { |
| + let perm; |
| + try { |
| + perm = await Notification.requestPermission(); |
| + } catch {} |
| + if (perm !== "granted") { |
| + refreshNotifItem(); |
| + return; |
| + } |
| + } |
| item.textContent = "…"; |
| if ((await isSubscribed()) && pushEnabled()) { |
| await unsubscribePush(); |
| @@ -204,8 +216,9 @@ function showBlockedInstructions() { |
| `<h1>Notifications are blocked</h1>` + |
| `<p>Your browser is blocking notifications for this site. To turn them on:</p>` + |
| `<ol class="steps">` + |
| - `<li>Click the lock / site-info icon in the address bar.</li>` + |
| - `<li>Set <strong>Notifications</strong> to <strong>Allow</strong>.</li>` + |
| + `<li><strong>Chrome / Edge:</strong> click the site-info icon left of the address bar → Notifications → Allow.</li>` + |
| + `<li><strong>Safari:</strong> Safari → Settings → Websites → Notifications → set this site to Allow.</li>` + |
| + `<li><strong>Firefox:</strong> click the lock icon → clear the blocked Notifications permission.</li>` + |
| `<li>Reload, then choose <strong>Turn on notifications</strong>.</li>` + |
| `</ol>` |
| ); |
| @@ -368,15 +381,7 @@ async function start(session) { |
| input.style.height = "auto"; |
| input.style.height = Math.min(input.scrollHeight, 140) + "px"; |
| }; |
| - input.addEventListener("input", autosize); |
| - input.addEventListener("keydown", (e) => { |
| - if (e.key === "Enter" && !e.shiftKey) { |
| - e.preventDefault(); |
| - form.requestSubmit(); |
| - } |
| - }); |
| - form.onsubmit = async (e) => { |
| - e.preventDefault(); |
| + const send = async () => { |
| const text = input.value.trim(); |
| if (!text || !ws || ws.readyState !== WebSocket.OPEN) return; |
| input.value = ""; |
| @@ -384,6 +389,17 @@ async function start(session) { |
| const blob = await encrypt(key, { name: session.name, text, ts: Date.now() }); |
| ws.send(JSON.stringify({ type: "msg", blob })); |
| }; |
| + input.addEventListener("input", autosize); |
| + input.addEventListener("keydown", (e) => { |
| + if (e.key === "Enter" && !e.shiftKey) { |
| + e.preventDefault(); |
| + send(); |
| + } |
| + }); |
| + form.addEventListener("submit", (e) => { |
| + e.preventDefault(); |
| + send(); |
| + }); |
| input.focus(); |
| } |
| |