rmaps-online/public/sw.js

115 lines
2.9 KiB
JavaScript

// rMaps Service Worker for Push Notifications
const CACHE_NAME = 'rmaps-v1';
// Install event - cache essential assets
self.addEventListener('install', (event) => {
console.log('[SW] Installing service worker...');
self.skipWaiting();
});
// Activate event - clean up old caches
self.addEventListener('activate', (event) => {
console.log('[SW] Activating service worker...');
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((name) => name !== CACHE_NAME)
.map((name) => caches.delete(name))
);
})
);
self.clients.claim();
});
// Push event - handle incoming push notifications
self.addEventListener('push', (event) => {
console.log('[SW] Push received:', event);
let data = {
title: 'rMaps',
body: 'You have a new notification',
icon: '/icon-192.png',
badge: '/icon-192.png',
tag: 'rmaps-notification',
data: {},
};
if (event.data) {
try {
const payload = event.data.json();
data = { ...data, ...payload };
} catch (e) {
data.body = event.data.text();
}
}
const options = {
body: data.body,
icon: data.icon || '/icon-192.png',
badge: data.badge || '/icon-192.png',
tag: data.tag || 'rmaps-notification',
data: data.data || {},
vibrate: [100, 50, 100],
actions: data.actions || [],
requireInteraction: data.requireInteraction || false,
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
// Notification click event - handle user interaction
self.addEventListener('notificationclick', (event) => {
console.log('[SW] Notification clicked:', event);
event.notification.close();
const data = event.notification.data || {};
let targetUrl = '/';
// Determine URL based on notification type
if (data.roomSlug) {
targetUrl = `/${data.roomSlug}`;
} else if (data.url) {
targetUrl = data.url;
}
// Handle action buttons
if (event.action === 'view') {
targetUrl = data.url || targetUrl;
} else if (event.action === 'dismiss') {
return;
}
event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => {
// Try to focus an existing window
for (const client of clientList) {
if (client.url.includes(targetUrl) && 'focus' in client) {
return client.focus();
}
}
// Open a new window if none exists
if (clients.openWindow) {
return clients.openWindow(targetUrl);
}
})
);
});
// Handle notification close
self.addEventListener('notificationclose', (event) => {
console.log('[SW] Notification closed:', event);
});
// Handle messages from the main thread
self.addEventListener('message', (event) => {
console.log('[SW] Message received:', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});