Files
michaelschiemer/public/js/sw-push.js
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

124 lines
3.8 KiB
JavaScript

/**
* Service Worker for Web Push Notifications
*
* Handles incoming push notifications and displays them to the user.
*/
// Listen for push events
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push received', event);
if (!event.data) {
console.log('[Service Worker] Push event but no data');
return;
}
let notificationData;
try {
notificationData = event.data.json();
} catch (e) {
console.error('[Service Worker] Failed to parse push data', e);
notificationData = {
title: 'Notification',
body: event.data.text()
};
}
const title = notificationData.title || 'Notification';
const options = {
body: notificationData.body || '',
icon: notificationData.icon || '/assets/icons/notification-icon.png',
badge: notificationData.badge || '/assets/icons/notification-badge.png',
image: notificationData.image,
tag: notificationData.tag || 'default-tag',
requireInteraction: notificationData.requireInteraction || false,
silent: notificationData.silent || false,
actions: notificationData.actions || [],
data: notificationData.data || {}
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Listen for notification clicks
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification clicked', event);
event.notification.close();
// Handle action button clicks
if (event.action) {
console.log('[Service Worker] Action clicked:', event.action);
// You can handle different actions here
switch (event.action) {
case 'open':
event.waitUntil(clients.openWindow('/'));
break;
case 'dismiss':
// Just close, no action
break;
default:
event.waitUntil(clients.openWindow('/'));
}
} else {
// Regular notification click (not action button)
const urlToOpen = event.notification.data?.url || '/';
event.waitUntil(
clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then(function(windowClients) {
// Check if there is already a window/tab open
for (let i = 0; i < windowClients.length; i++) {
const client = windowClients[i];
if (client.url === urlToOpen && 'focus' in client) {
return client.focus();
}
}
// If not, open new window/tab
if (clients.openWindow) {
return clients.openWindow(urlToOpen);
}
})
);
}
});
// Listen for notification close
self.addEventListener('notificationclose', function(event) {
console.log('[Service Worker] Notification closed', event);
// You can track notification dismissals here
// e.g., send analytics event
});
// Service Worker Installation
self.addEventListener('install', function(event) {
console.log('[Service Worker] Installing');
self.skipWaiting(); // Activate immediately
});
// Service Worker Activation
self.addEventListener('activate', function(event) {
console.log('[Service Worker] Activating');
event.waitUntil(clients.claim()); // Take control of all pages
});
// Optional: Handle background sync for failed pushes
self.addEventListener('sync', function(event) {
console.log('[Service Worker] Background sync', event);
if (event.tag === 'push-sync') {
event.waitUntil(
// Retry failed push operations
Promise.resolve()
);
}
});