/* ============================================================ BAN YARO — Boot-Phase Offline-Banner + Service Worker Registration + Update-Flow Extrahiert aus index.html für CSP-Härtung (kein unsafe-inline) ============================================================ */ // ---------------------------------------------------------- // Offline-Banner // ---------------------------------------------------------- (function() { function _updateBanner() { var banner = document.getElementById('offline-banner'); if (!banner) return; banner.style.display = navigator.onLine ? 'none' : 'flex'; } window.addEventListener('offline', function() { _updateBanner(); // Einmaliger Hinweis pro Session: App im Vordergrund lassen if (!sessionStorage.getItem('by_offline_hint_shown')) { sessionStorage.setItem('by_offline_hint_shown', '1'); setTimeout(function() { window.UI?.toast?.info( 'App im Vordergrund lassen — so bleiben Offline-Funktionen wie GPS und Datenspeicherung aktiv.', 8000 ); }, 800); } // Queue-Count abfragen if (navigator.serviceWorker) { navigator.serviceWorker.ready.then(function(reg) { if (reg.active) reg.active.postMessage({ type: 'QUEUE_COUNT' }); }); } }); window.addEventListener('online', function() { _updateBanner(); var badge = document.getElementById('offline-queue-badge'); if (badge) badge.style.display = 'none'; // Queue abarbeiten if (navigator.serviceWorker) { navigator.serviceWorker.ready.then(function(reg) { if (reg.active) reg.active.postMessage({ type: 'PROCESS_QUEUE' }); }); } }); _updateBanner(); })(); // ---------------------------------------------------------- // Service Worker Registration + Update-Flow // ---------------------------------------------------------- if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/sw.js', { updateViaCache: 'none' }) .then(function(reg) { function _watchSW(sw) { if (!sw) return; sw.addEventListener('statechange', function() { if (sw.state === 'activated') { if (sessionStorage.getItem('by_skip_sw_reload')) { sessionStorage.removeItem('by_skip_sw_reload'); // einmalig konsumieren return; } window.location.replace('/?_t=' + Date.now()); } }); } reg.addEventListener('updatefound', function() { _watchSW(reg.installing); }); if (reg.installing) _watchSW(reg.installing); reg.update(); }) .catch(function(err) { console.warn('SW Registration failed:', err); }); }); // App aus dem Hintergrund: erneut prüfen document.addEventListener('visibilitychange', function() { if (document.visibilityState === 'visible') { navigator.serviceWorker.getRegistration().then(function(reg) { if (reg) reg.update(); }); } }); // Backup: controllerchange falls updatefound nicht feuert // NICHT registrieren wenn diese Seite selbst durch SW-Reload entstand if (!window._BY_SW_RELOAD) { navigator.serviceWorker.addEventListener('controllerchange', function() { if (sessionStorage.getItem('by_skip_sw_reload')) { sessionStorage.removeItem('by_skip_sw_reload'); return; } window.location.replace('/?_t=' + Date.now()); }); } navigator.serviceWorker.addEventListener('message', function(e) { if (e.data && e.data.type === 'QUEUE_PROCESSED') { var synced = e.data.synced, failed = e.data.failed, total = e.data.total; if (total === 0) return; if (synced > 0 && window.UI && window.UI.toast) { window.UI.toast.success( synced === 1 ? '1 offline gespeicherter Eintrag synchronisiert' : synced + ' offline gespeicherte Einträge synchronisiert' ); if (window.App && window.App.state && window.pages) { var p = window.pages[window.App.state.page]; if (p && p.module && p.module.refresh) p.module.refresh(); } } if (failed > 0 && window.UI && window.UI.toast) { window.UI.toast.warning(failed + ' Eintrag' + (failed > 1 ? 'e' : '') + ' noch nicht synchronisiert — kein Netz'); } return; } if (e.data && e.data.type === 'QUEUE_COUNT') { var badge = document.getElementById('offline-queue-badge'); if (badge) { if (e.data.count > 0) { badge.textContent = e.data.count; badge.style.display = ''; } else { badge.style.display = 'none'; } } return; } if (e.data && e.data.type === 'CHECK_NEARBY_ALERTS') { if (window.App && window.App._checkNearbyAlerts) window.App._checkNearbyAlerts(); } }); }