UNPKG

progresspulse-pwa

Version:

A modern PWA for tracking progress and achieving goals with iPhone-style design

140 lines (126 loc) 3.5 kB
const CACHE_NAME = 'progresspulse-v1'; const urlsToCache = [ '/', '/static/js/bundle.js', '/static/css/main.css', '/manifest.json' ]; // FCM Push Notification Handler self.addEventListener('push', (event) => { console.log('Push received:', event); let notificationData = { title: 'ProgressPulse', body: 'You have a new notification', icon: '/pwa-192x192.png', badge: '/pwa-64x64.png', tag: 'default', requireInteraction: true, data: {} }; if (event.data) { try { const data = event.data.json(); notificationData = { ...notificationData, title: data.title || notificationData.title, body: data.body || data.message || notificationData.body, icon: data.icon || notificationData.icon, tag: data.tag || notificationData.tag, data: data.data || data }; } catch (e) { notificationData.body = event.data.text() || notificationData.body; } } event.waitUntil( self.registration.showNotification(notificationData.title, { body: notificationData.body, icon: notificationData.icon, badge: notificationData.badge, tag: notificationData.tag, requireInteraction: notificationData.requireInteraction, data: notificationData.data, actions: [ { action: 'open', title: 'Open App' }, { action: 'close', title: 'Dismiss' } ] }) ); }); // Notification Click Handler self.addEventListener('notificationclick', (event) => { console.log('Notification clicked:', event); event.notification.close(); if (event.action === 'close') { return; } // Open app or focus existing window event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }) .then((clientList) => { // If app is already open, focus it for (const client of clientList) { if (client.url.includes(self.location.origin) && 'focus' in client) { return client.focus(); } } // Otherwise open new window if (clients.openWindow) { const targetUrl = event.notification.data?.url || '/'; return clients.openWindow(targetUrl); } }) ); }); // Background Sync for offline notifications self.addEventListener('sync', (event) => { if (event.tag === 'background-sync') { event.waitUntil(doBackgroundSync()); } }); async function doBackgroundSync() { // Handle offline notification queue try { const cache = await caches.open('notifications-cache'); const requests = await cache.keys(); for (const request of requests) { try { await fetch(request); await cache.delete(request); } catch (error) { console.log('Background sync failed for:', request.url); } } } catch (error) { console.error('Background sync error:', error); } } self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME) .then((cache) => cache.addAll(urlsToCache)) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) .then((response) => { if (response) { return response; } return fetch(event.request); } ) ); }); self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting(); } });