Benachrichtigungen: Geraet, Abos und der Reiter Meldungen
Der Geraetesuchlauf legt "Benachrichtigungen" an (benachrichtigung_module.py), ein Kommando je Kanal. Damit kann jede Automatik melden, ohne dass Editor, Zeitleiste oder Datenbank etwas davon wissen muessten. Fuer die Meldung aufs Handy braucht es keine App: Der Browser meldet sich unter Einstellungen -> Meldungen selbst an (sw.js, ajax/push.php), das Abo steht in homeMesh.push_abos, verschickt wird vom Runner. Auf dem iPhone geht es erst ab der Ablage auf dem Home-Bildschirm - der Reiter sagt das auch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Service Worker - nur für Benachrichtigungen.
|
||||
*
|
||||
* Er liegt bewusst im Wurzelverzeichnis der Anwendung: Ein Service Worker
|
||||
* gilt nur für Adressen unterhalb seines eigenen Ortes, und die Abos sollen
|
||||
* für die ganze Seite gelten, nicht nur für /js/.
|
||||
*
|
||||
* Was er NICHT tut: Seiten zwischenspeichern. Das Dashboard lebt von
|
||||
* aktuellen Werten, und ein Cache, der eine alte Fassung ausliefert, wäre
|
||||
* hier kein Vorteil, sondern eine Fehlerquelle. Deshalb gibt es kein
|
||||
* fetch-Ereignis - der Browser holt alles wie ohne Service Worker.
|
||||
*
|
||||
* Geschickt wird vom Runner (BenachrichtigungTransport in
|
||||
* SolarManager/autoActions/transports.py), verschlüsselt und mit dem
|
||||
* VAPID-Schlüssel unterschrieben.
|
||||
*/
|
||||
|
||||
self.addEventListener("install", () => self.skipWaiting());
|
||||
self.addEventListener("activate", (e) => e.waitUntil(self.clients.claim()));
|
||||
|
||||
self.addEventListener("push", (ereignis) => {
|
||||
let daten = { titel: "Smart controller", text: "", url: "index.php" };
|
||||
try {
|
||||
if (ereignis.data) Object.assign(daten, ereignis.data.json());
|
||||
} catch (fehler) {
|
||||
// Kein JSON: dann ist die Nutzlast der Text.
|
||||
if (ereignis.data) daten.text = ereignis.data.text();
|
||||
}
|
||||
ereignis.waitUntil(self.registration.showNotification(daten.titel, {
|
||||
body: daten.text,
|
||||
icon: "assets/img/favicon.png",
|
||||
badge: "assets/img/favicon.png",
|
||||
// Gleiche Kennung ersetzt die vorherige Meldung, statt sie zu stapeln -
|
||||
// eine Automatik, die dreimal meldet, soll nicht dreimal im Schirm stehen.
|
||||
tag: daten.kennung || undefined,
|
||||
timestamp: Date.now(),
|
||||
data: { url: daten.url },
|
||||
}));
|
||||
});
|
||||
|
||||
self.addEventListener("notificationclick", (ereignis) => {
|
||||
ereignis.notification.close();
|
||||
const ziel = new URL((ereignis.notification.data && ereignis.notification.data.url) || "index.php",
|
||||
self.registration.scope).href;
|
||||
ereignis.waitUntil(self.clients.matchAll({ type: "window", includeUncontrolled: true })
|
||||
.then((fenster) => {
|
||||
// Ist die Seite schon offen, wird sie nach vorn geholt statt ein
|
||||
// zweites Mal geöffnet.
|
||||
for (const f of fenster) {
|
||||
if (f.url.startsWith(self.registration.scope) && "focus" in f) return f.focus();
|
||||
}
|
||||
return self.clients.openWindow(ziel);
|
||||
}));
|
||||
});
|
||||
Reference in New Issue
Block a user