File size: 2,787 Bytes
0815e01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | // Notifications for photo requests, on a phone only: a switch on home. The service worker shows the notification when the app is closed and, on a
// tap, tells the open app to look for requests. Without a push key on the server the switch is not offered.
import { api } from "./api.js";
import { isTouch } from "./media.js";
const bytes = base64 => Uint8Array.from(atob(base64.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - base64.length % 4) % 4)), c => c.charCodeAt(0));
/** Draw the switch into `box` (nothing at all on a computer, without notification support, or when the server has no key). */
export async function setup(box) {
if (!isTouch() || !("serviceWorker" in navigator) || !("PushManager" in window) || !("Notification" in window)) return;
let server;
try { server = await api("/api/push/key"); } catch { return; }
if (!server.enabled) return;
let registration;
try { registration = await navigator.serviceWorker.register("/service-worker.js", { scope: "/" }); } catch { return; }
let subscription = await registration.pushManager.getSubscription();
const draw = (note = "") => {
box.hidden = false;
box.innerHTML = `<h3>ืืชืจืืืช</h3><p class="muted">ืืฉืืืืฉื ืืืงืฉ ืชืืื ื ืฉื ืชืฉืืื, ืืืืคืื ืืงืื ืืชืจืื ืื ืืฉืืืคืืืงืฆืื ืกืืืจื. ืืืืืคืื ืื ืขืืื ืจืง ืืืืคืืืงืฆืื ืฉืืืกืคืชื ืืืกื ืืืืช.</p>
<p>${subscription ? `<span class="tag" id="notif-state"><span aria-hidden="true">โ</span> ืืชืจืืืช ืคืืขืืืช</span> <button type="button" id="notif-off">ืืืืื</button>`
: `<button type="button" class="primary" id="notif-on">ืืคืขืืช ืืชืจืืืช</button>`}</p><p class="muted" id="notif-note" role="status">${note}</p>`;
box.querySelector("#notif-on")?.addEventListener("click", enable);
box.querySelector("#notif-off")?.addEventListener("click", disable);
};
async function enable() {
try {
if (await Notification.requestPermission() !== "granted") return draw("ืืืชืจืืืช ืืกืืืืช ืืืคืืคื. ืืคืฉืจ ืืืฉืจ ืืืชื ืืืืืจืืช.");
subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: bytes(server.key) });
await api("/api/push/subscribe", { method: "POST", body: subscription.toJSON() });
draw();
} catch (error) { subscription = null; draw(error.message || "ืื ืืฆืืื ื ืืืคืขืื ืืชืจืืืช."); }
}
async function disable() {
const endpoint = subscription?.endpoint;
try { await subscription?.unsubscribe(); if (endpoint) await api("/api/push/unsubscribe", { method: "POST", body: { endpoint } }); } catch { /* it is off here either way */ }
subscription = null;
draw();
}
draw();
}
|