Diff -- /var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/sw.js
Diff

/var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/sw.js

added on local at 2026-07-01 12:34:43

Added
+75
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to fd0830c7f4cf
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1// PTMatrix service worker — minimal push handler.
2// Receives empty (no-payload) pushes from PTMatrix's WebPush module, then
3// fetches the latest unread notification from /notifications.cgi to decide
4// what to show. Empty-payload push avoids RFC 8291 payload encryption
5// entirely so the server-side stays a thin curl+openssl shim.
6//
7// Versioned in the URL (?v=20260618) so wrapper template can bust this.
8
9self.addEventListener('install', (e) => {
10 self.skipWaiting();
11});
12self.addEventListener('activate', (e) => {
13 e.waitUntil(self.clients.claim());
14});
15
16async function buildNotification(event) {
17 let data = {};
18 if (event.data) {
19 try { data = event.data.json(); } catch(_) {
20 try { data = { body: event.data.text() }; } catch(_) {}
21 }
22 }
23 // Empty-payload push: ask the server what to show.
24 if (!data || (!data.title && !data.body)) {
25 try {
26 const r = await fetch('/notifications.cgi?act=latest_unread', { credentials: 'include' });
27 if (r.ok) {
28 const j = await r.json();
29 if (j && j.ok && j.item) {
30 data.title = j.item.title || 'PTMatrix';
31 data.body = j.item.body || '';
32 data.url = j.item.url || '/notifications.cgi';
33 data.tag = 'ptm-' + (j.item.id || Date.now());
34 data.unread_count = j.unread_count;
35 }
36 }
37 } catch(_) {}
38 }
39 const title = data.title || 'PTMatrix';
40 const opts = {
41 body: data.body || 'You have a new notification.',
42 data: { url: data.url || '/notifications.cgi' },
43 icon: '/assets/images/icon-192.png',
44 badge: '/assets/images/badge-72.png',
45 tag: data.tag || 'ptmatrix',
46 renotify: true,
47 };
48 // Badge API: keep the unread count visible on the home-screen icon (iOS PWA).
49 if (typeof data.unread_count === 'number' && 'setAppBadge' in self) {
50 try { self.setAppBadge(data.unread_count); } catch(_) {}
51 }
52 return self.registration.showNotification(title, opts);
53}
54
55self.addEventListener('push', (event) => {
56 event.waitUntil(buildNotification(event));
57});
58
59self.addEventListener('notificationclick', (event) => {
60 event.notification.close();
61 const target = (event.notification.data && event.notification.data.url) || '/notifications.cgi';
62 event.waitUntil((async () => {
63 const wins = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
64 for (const w of wins) {
65 try {
66 if (w.url && w.url.indexOf(self.location.origin) === 0) {
67 await w.focus();
68 if (w.navigate) { try { await w.navigate(target); } catch(_) {} }
69 return;
70 }
71 } catch(_) {}
72 }
73 await self.clients.openWindow(target);
74 })());
75});
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help