93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
/// <reference lib="webworker" />
|
|
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
|
|
|
|
declare let self: ServiceWorkerGlobalScope;
|
|
|
|
// Clean up old caches
|
|
cleanupOutdatedCaches();
|
|
|
|
// Precache all assets generated by the build
|
|
precacheAndRoute(self.__WB_MANIFEST);
|
|
|
|
// Push notification payload type
|
|
interface PushPayload {
|
|
title: string;
|
|
body: string;
|
|
sessionId: string;
|
|
sessionTitle: string;
|
|
tools: string[];
|
|
}
|
|
|
|
// Handle push events
|
|
self.addEventListener('push', (event) => {
|
|
if (!event.data) {
|
|
console.log('[SW] Push event with no data');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const payload: PushPayload = event.data.json();
|
|
console.log('[SW] Push received:', payload);
|
|
|
|
const options = {
|
|
body: payload.body,
|
|
icon: '/pwa-192x192.png',
|
|
badge: '/pwa-192x192.png',
|
|
tag: `permission-${payload.sessionId}`,
|
|
renotify: true,
|
|
requireInteraction: true,
|
|
data: {
|
|
sessionId: payload.sessionId,
|
|
url: `/session/${payload.sessionId}`
|
|
},
|
|
actions: [
|
|
{
|
|
action: 'open',
|
|
title: 'Open Session'
|
|
}
|
|
]
|
|
} satisfies NotificationOptions & { renotify?: boolean; requireInteraction?: boolean; actions?: { action: string; title: string }[] };
|
|
|
|
event.waitUntil(self.registration.showNotification(payload.title, options));
|
|
} catch (err) {
|
|
console.error('[SW] Error processing push:', err);
|
|
}
|
|
});
|
|
|
|
// Handle notification click
|
|
self.addEventListener('notificationclick', (event) => {
|
|
console.log('[SW] Notification clicked:', event.action);
|
|
event.notification.close();
|
|
|
|
const url = event.notification.data?.url || '/';
|
|
|
|
// Focus existing window or open new one
|
|
event.waitUntil(
|
|
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
|
|
// Try to find an existing window with the app
|
|
for (const client of clientList) {
|
|
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
|
client.focus();
|
|
// Navigate to the session
|
|
client.postMessage({
|
|
type: 'NAVIGATE',
|
|
url: url
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
// No existing window, open a new one
|
|
if (self.clients.openWindow) {
|
|
return self.clients.openWindow(url);
|
|
}
|
|
})
|
|
);
|
|
});
|
|
|
|
// Handle messages from the main app
|
|
self.addEventListener('message', (event) => {
|
|
if (event.data?.type === 'SKIP_WAITING') {
|
|
self.skipWaiting();
|
|
}
|
|
});
|