/* * NIS2 Agile — PWA bootstrap * Registra il service worker e gestisce l'UI di installazione (Android + iOS). * Vanilla JS, nessuna dipendenza. Localizzato IT/EN (chiave i18n: 'nis2_lang'). */ (function () { 'use strict'; // --- i18n minimale, allineato a i18n.js (localStorage 'nis2_lang') --- function lang() { try { return (localStorage.getItem('nis2_lang') || 'it').slice(0, 2); } catch (e) { return 'it'; } } var STR = { it: { install: 'Installa app', banner: 'Installa NIS2 Agile sul dispositivo per un accesso più rapido.', ios: 'Per installare: tocca Condividi e poi "Aggiungi a Home".', close: 'Chiudi' }, en: { install: 'Install app', banner: 'Install NIS2 Agile on your device for faster access.', ios: 'To install: tap Share, then "Add to Home Screen".', close: 'Close' } }; function t(k) { var l = lang(); return (STR[l] && STR[l][k]) || STR.it[k]; } function isStandalone() { return (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches) || window.navigator.standalone === true; } // --- 1. Registrazione service worker --- if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/sw.js', { scope: '/' }) .catch(function (err) { console.warn('[pwa] SW registration failed', err); }); }); } // Gia' installata (standalone): niente banner di installazione. if (isStandalone()) return; // --- UI banner sobrio, indipendente dal CSS dell'app --- function makeBanner(message, withInstallBtn) { var bar = document.createElement('div'); bar.setAttribute('role', 'region'); bar.setAttribute('aria-label', t('install')); bar.style.cssText = 'position:fixed;left:12px;right:12px;bottom:12px;z-index:9999;' + 'background:#0066CC;color:#fff;border-radius:10px;padding:12px 14px;' + 'box-shadow:0 6px 24px rgba(0,0,0,.25);display:flex;align-items:center;gap:10px;' + 'font-family:system-ui,Arial,sans-serif;font-size:.95rem;max-width:560px;margin:0 auto;'; var txt = document.createElement('span'); txt.style.cssText = 'flex:1;line-height:1.35;'; txt.textContent = message; bar.appendChild(txt); var btnInstall = null; if (withInstallBtn) { btnInstall = document.createElement('button'); btnInstall.type = 'button'; btnInstall.textContent = t('install'); btnInstall.style.cssText = 'background:#fff;color:#0066CC;border:0;border-radius:8px;' + 'padding:10px 16px;font-weight:600;min-height:44px;cursor:pointer;white-space:nowrap;'; bar.appendChild(btnInstall); } var btnClose = document.createElement('button'); btnClose.type = 'button'; btnClose.setAttribute('aria-label', t('close')); btnClose.textContent = '✕'; btnClose.style.cssText = 'background:transparent;color:#fff;border:0;font-size:1.1rem;' + 'line-height:1;min-width:44px;min-height:44px;cursor:pointer;'; bar.appendChild(btnClose); document.body.appendChild(bar); return { bar: bar, btnInstall: btnInstall, btnClose: btnClose }; } // --- 2. Android / Chrome: beforeinstallprompt --- var deferred = null; var DISMISS_KEY = 'pwa-install-dismissed'; function dismissed() { try { return localStorage.getItem(DISMISS_KEY) === '1'; } catch (e) { return false; } } function setDismissed() { try { localStorage.setItem(DISMISS_KEY, '1'); } catch (e) {} } window.addEventListener('beforeinstallprompt', function (e) { e.preventDefault(); deferred = e; if (dismissed()) return; try { var ui = makeBanner(t('banner'), true); ui.btnInstall.addEventListener('click', function () { ui.bar.remove(); if (!deferred) return; deferred.prompt(); if (deferred.userChoice && deferred.userChoice.finally) { deferred.userChoice.finally(function () { deferred = null; }); } else { deferred = null; } }); ui.btnClose.addEventListener('click', function () { ui.bar.remove(); setDismissed(); }); } catch (err) { console.warn('[pwa] banner error', err); } }); window.addEventListener('appinstalled', function () { deferred = null; setDismissed(); }); // --- 3. iOS Safari: nessun beforeinstallprompt -> hint manuale (una volta) --- try { var ua = navigator.userAgent || ''; var isIOS = /iphone|ipad|ipod/i.test(ua) || (/Macintosh/.test(ua) && 'ontouchend' in document); // iPad iPadOS desktop-mode var isSafari = /safari/i.test(ua) && !/crios|fxios|edgios|android/i.test(ua); var IOS_KEY = 'pwa-ios-hint-dismissed'; var iosDismissed = (function () { try { return localStorage.getItem(IOS_KEY) === '1'; } catch (e) { return false; } })(); if (isIOS && isSafari && !iosDismissed) { window.addEventListener('load', function () { var ui = makeBanner(t('ios'), false); ui.btnClose.addEventListener('click', function () { ui.bar.remove(); try { localStorage.setItem(IOS_KEY, '1'); } catch (e) {} }); }); } } catch (err) { console.warn('[pwa] ios hint error', err); } })();