Add guest push notifications and queue alerts
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
// Minimal service worker for Guest PWA queue sync
|
||||
self.addEventListener('install', (event) => {
|
||||
self.addEventListener('install', () => {
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
@@ -7,63 +6,61 @@ self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(self.clients.claim());
|
||||
});
|
||||
|
||||
const ASSETS_CACHE = 'guest-assets-v1';
|
||||
const IMAGES_CACHE = 'guest-images-v1';
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const req = event.request;
|
||||
if (req.method !== 'GET') return;
|
||||
|
||||
const url = new URL(req.url);
|
||||
// Only handle same-origin requests
|
||||
if (url.origin !== self.location.origin) return;
|
||||
|
||||
// Never cache API calls; let them hit network directly
|
||||
if (url.pathname.startsWith('/api/')) return;
|
||||
|
||||
// Cache-first for images
|
||||
if (req.destination === 'image' || /\.(png|jpg|jpeg|webp|avif|gif|svg)(\?.*)?$/i.test(url.pathname)) {
|
||||
event.respondWith((async () => {
|
||||
const cache = await caches.open(IMAGES_CACHE);
|
||||
const cached = await cache.match(req);
|
||||
if (cached) return cached;
|
||||
try {
|
||||
const res = await fetch(req, { credentials: 'same-origin' });
|
||||
if (res.ok) cache.put(req, res.clone());
|
||||
return res;
|
||||
} catch (e) {
|
||||
return cached || Response.error();
|
||||
}
|
||||
})());
|
||||
return;
|
||||
}
|
||||
|
||||
// Stale-while-revalidate for CSS/JS assets
|
||||
if (req.destination === 'style' || req.destination === 'script') {
|
||||
event.respondWith((async () => {
|
||||
const cache = await caches.open(ASSETS_CACHE);
|
||||
const cached = await cache.match(req);
|
||||
const networkPromise = fetch(req, { credentials: 'same-origin' })
|
||||
.then((res) => {
|
||||
if (res.ok) cache.put(req, res.clone());
|
||||
return res;
|
||||
})
|
||||
.catch(() => null);
|
||||
return cached || (await networkPromise) || Response.error();
|
||||
})());
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('sync', (event) => {
|
||||
if (event.tag === 'upload-queue') {
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const clients = await self.clients.matchAll({ includeUncontrolled: true, type: 'window' });
|
||||
for (const client of clients) {
|
||||
client.postMessage({ type: 'sync-queue' });
|
||||
}
|
||||
clients.forEach((client) => client.postMessage({ type: 'sync-queue' }));
|
||||
})()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('push', (event) => {
|
||||
const payload = event.data?.json?.() ?? {};
|
||||
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const title = payload.title ?? 'Neue Nachricht';
|
||||
const options = {
|
||||
body: payload.body ?? '',
|
||||
icon: '/icons/icon-192.png',
|
||||
badge: '/icons/badge.png',
|
||||
data: payload.data ?? {},
|
||||
};
|
||||
|
||||
await self.registration.showNotification(title, options);
|
||||
|
||||
const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
||||
clients.forEach((client) => client.postMessage({ type: 'guest-notification-refresh' }));
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
event.notification.close();
|
||||
const targetUrl = event.notification.data?.url || '/';
|
||||
|
||||
event.waitUntil(
|
||||
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
|
||||
for (const client of clientList) {
|
||||
if ('focus' in client) {
|
||||
client.navigate(targetUrl);
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
if (self.clients.openWindow) {
|
||||
return self.clients.openWindow(targetUrl);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('pushsubscriptionchange', (event) => {
|
||||
event.waitUntil(
|
||||
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
|
||||
clientList.forEach((client) => client.postMessage({ type: 'push-subscription-change' }));
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user