// Service Worker for HandyBarcodeScanner PWA const CACHE_NAME = 'scanner-v6.0'; const ASSETS = [ 'pwa.php', 'css/scanner.css', 'js/scanner.js', 'img/icon-192.png', 'img/icon-512.png', 'https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.8.4/dist/quagga.min.js', 'https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/dist/JsBarcode.all.min.js' ]; // Install - cache assets self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME).then(cache => { return cache.addAll(ASSETS); }) ); self.skipWaiting(); }); // Activate - clean old caches self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(keys => { return Promise.all( keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key)) ); }) ); self.clients.claim(); }); // Fetch - network first, fallback to cache self.addEventListener('fetch', event => { const url = new URL(event.request.url); // Always fetch AJAX requests from network if (url.pathname.includes('/ajax/')) { event.respondWith( fetch(event.request).catch(err => { console.error('Network error for AJAX:', err); return new Response(JSON.stringify({ success: false, error: 'Offline - Keine Netzwerkverbindung' }), { headers: {'Content-Type': 'application/json'} }); }) ); return; } // Network first for PHP pages (to get fresh token) if (url.pathname.endsWith('.php')) { event.respondWith( fetch(event.request).catch(() => caches.match(event.request)) ); return; } // Cache first for static assets event.respondWith( caches.match(event.request).then(cached => { return cached || fetch(event.request).then(response => { if (response.ok) { const clone = response.clone(); caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone)); } return response; }); }) ); }); // Listen for messages from main app self.addEventListener('message', event => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting(); } });