Migración desde workspace-v2/projects/template-saas/apps/frontend Este repositorio es parte del estándar multi-repo v2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
157 lines
4.0 KiB
JavaScript
157 lines
4.0 KiB
JavaScript
// Service Worker for Push Notifications
|
|
// Template SaaS v2.0
|
|
|
|
const CACHE_NAME = 'template-saas-v1';
|
|
|
|
// Install event
|
|
self.addEventListener('install', (event) => {
|
|
console.log('[SW] Installing service worker...');
|
|
self.skipWaiting();
|
|
});
|
|
|
|
// Activate event
|
|
self.addEventListener('activate', (event) => {
|
|
console.log('[SW] Service worker activated');
|
|
event.waitUntil(self.clients.claim());
|
|
});
|
|
|
|
// Push notification received
|
|
self.addEventListener('push', (event) => {
|
|
console.log('[SW] Push notification received');
|
|
|
|
let data = {
|
|
title: 'Nueva notificacion',
|
|
body: 'Tienes una nueva notificacion',
|
|
icon: '/icon-192.png',
|
|
badge: '/badge-72.png',
|
|
url: '/',
|
|
data: {},
|
|
};
|
|
|
|
if (event.data) {
|
|
try {
|
|
data = { ...data, ...event.data.json() };
|
|
} catch (e) {
|
|
console.error('[SW] Error parsing push data:', e);
|
|
}
|
|
}
|
|
|
|
const options = {
|
|
body: data.body,
|
|
icon: data.icon || '/icon-192.png',
|
|
badge: data.badge || '/badge-72.png',
|
|
vibrate: [100, 50, 100],
|
|
tag: data.notificationId || 'default',
|
|
renotify: true,
|
|
requireInteraction: data.requireInteraction || false,
|
|
data: {
|
|
url: data.url || '/',
|
|
notificationId: data.notificationId,
|
|
...data.data,
|
|
},
|
|
actions: data.actions || [
|
|
{ action: 'view', title: 'Ver' },
|
|
{ action: 'dismiss', title: 'Descartar' },
|
|
],
|
|
};
|
|
|
|
event.waitUntil(
|
|
self.registration.showNotification(data.title, options)
|
|
);
|
|
});
|
|
|
|
// Notification click handler
|
|
self.addEventListener('notificationclick', (event) => {
|
|
console.log('[SW] Notification clicked:', event.action);
|
|
|
|
event.notification.close();
|
|
|
|
if (event.action === 'dismiss') {
|
|
return;
|
|
}
|
|
|
|
const url = event.notification.data?.url || '/';
|
|
|
|
event.waitUntil(
|
|
self.clients
|
|
.matchAll({ type: 'window', includeUncontrolled: true })
|
|
.then((clientList) => {
|
|
// Try to find an existing window and navigate
|
|
for (const client of clientList) {
|
|
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
|
return client.focus().then((focusedClient) => {
|
|
if (focusedClient && 'navigate' in focusedClient) {
|
|
return focusedClient.navigate(url);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// If no window found, open a new one
|
|
if (self.clients.openWindow) {
|
|
return self.clients.openWindow(url);
|
|
}
|
|
})
|
|
);
|
|
});
|
|
|
|
// Notification close handler
|
|
self.addEventListener('notificationclose', (event) => {
|
|
console.log('[SW] Notification closed');
|
|
|
|
// Optionally track notification dismissals
|
|
const notificationId = event.notification.data?.notificationId;
|
|
if (notificationId) {
|
|
// Could send analytics here
|
|
}
|
|
});
|
|
|
|
// Push subscription change handler
|
|
self.addEventListener('pushsubscriptionchange', (event) => {
|
|
console.log('[SW] Push subscription changed');
|
|
|
|
event.waitUntil(
|
|
self.registration.pushManager
|
|
.subscribe({
|
|
userVisibleOnly: true,
|
|
applicationServerKey: event.oldSubscription?.options?.applicationServerKey,
|
|
})
|
|
.then((subscription) => {
|
|
// Notify the app about the new subscription
|
|
return self.clients.matchAll().then((clients) => {
|
|
clients.forEach((client) => {
|
|
client.postMessage({
|
|
type: 'PUSH_SUBSCRIPTION_CHANGED',
|
|
subscription: JSON.stringify(subscription),
|
|
});
|
|
});
|
|
});
|
|
})
|
|
);
|
|
});
|
|
|
|
// Message handler (for app communication)
|
|
self.addEventListener('message', (event) => {
|
|
console.log('[SW] Message received:', event.data);
|
|
|
|
if (event.data?.type === 'SKIP_WAITING') {
|
|
self.skipWaiting();
|
|
}
|
|
});
|
|
|
|
// Background sync (for offline notifications)
|
|
self.addEventListener('sync', (event) => {
|
|
console.log('[SW] Background sync:', event.tag);
|
|
|
|
if (event.tag === 'sync-notifications') {
|
|
event.waitUntil(syncNotifications());
|
|
}
|
|
});
|
|
|
|
async function syncNotifications() {
|
|
// This would sync any pending notification actions
|
|
console.log('[SW] Syncing notifications...');
|
|
}
|
|
|
|
console.log('[SW] Service worker loaded');
|