const CACHE_NAME = 'domili-v1' + new Date().getTime(); const urlsToCache = [ '/', //'/index.php', //'/login.php', '/offline.html', '/css/style.css', '/img/icon-192.png', '/img/icon-512.png' ]; // Installation - immer neue Version self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => { return cache.addAll(urlsToCache); }) ); self.skipWaiting(); // Sofort aktivieren }); // Aktivierung - alte Caches automatisch löschen self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames .filter(name => name !== CACHE_NAME) .map(name => caches.delete(name)) ); }) ); return self.clients.claim(); // Sofort Kontrolle übernehmen }); // Fetch mit Network First für PHP, Cache First für statische Dateien self.addEventListener('fetch', function(event) { if (!event.request.url.startsWith('http')) return; const url = new URL(event.request.url); // Statische Ressourcen - Cache First if (url.pathname.endsWith('.css') || url.pathname.endsWith('.png') || url.pathname.endsWith('.jpg') || url.pathname.endsWith('.js')) { event.respondWith( caches.match(event.request) .then(response => response || fetch(event.request)) ); } // Dynamische Seiten - Network First mit Offline-Fallback else { event.respondWith( fetch(event.request) .then(response => { // Nur bei GET-Anfragen und erfolgreicher Antwort cachen if (response && response.status === 200 && event.request.method === 'GET') { const responseToCache = response.clone(); caches.open(CACHE_NAME).then(cache => { cache.put(event.request, responseToCache); }); } return response; }) .catch(() => caches.match('/offline.html')) ); } }); // Nachrichten vom Client empfangen self.addEventListener('message', event => { if (event.data.action === 'skipWaiting') { self.skipWaiting(); } }); // >>> NEU: Push-Benachrichtigungen <<< self.addEventListener('push', function(event) { let data = {}; if (event.data) { data = event.data.json(); } const title = data.title || 'DoMiLi'; const options = { body: data.body || 'Du hast eine neue Benachrichtigung.', icon: '/domili/favicon.ico', badge: '/domili/favicon.ico', vibrate: [200, 100, 200], data: { url: data.url || '/domili/' } }; event.waitUntil( self.registration.showNotification(title, options) ); }); self.addEventListener('notificationclick', function(event) { event.notification.close(); event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) { for (let i = 0; i < clientList.length; i++) { let client = clientList[i]; if (client.url === event.notification.data.url && 'focus' in client) { return client.focus(); } } if (clients.openWindow) { return clients.openWindow(event.notification.data.url); } }) ); });