Mercurial
view mrjunejune/src/public/pwa-register.js @ 264:04fee26ecce0
add authenticated JRPG conversation platform
Add reusable auth/session storage, owned conversation recovery, guest quotas, admin workflows, URL-routed conversation UI, mobile frame support, and parallel browser acceptance.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 07:34:12 -0700 |
| parents | 60a876c4587a |
| children | e02e2036ef84 |
line wrap: on
line source
// PWA Service Worker Registration if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker .register('/sw.js', { scope: '/' }) .then((registration) => { // console.log('[PWA] Service Worker registered:', registration.scope); // Check for updates periodically setInterval(() => { registration.update(); }, 60000); // Check every minute // Handle updates registration.addEventListener('updatefound', () => { const newWorker = registration.installing; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { // New content available, show update notification if (confirm('New version available! Reload to update?')) { newWorker.postMessage({ type: 'SKIP_WAITING' }); window.location.reload(); } } }); }); }) .catch((error) => { console.error('[PWA] Service Worker registration failed:', error); }); // Handle service worker updates let refreshing = false; navigator.serviceWorker.addEventListener('controllerchange', () => { if (!refreshing) { refreshing = true; window.location.reload(); } }); }); } // Add install prompt handler let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; showInstallPromotion(); }); function showInstallPromotion() { // Create an install button if it doesn't exist if (document.getElementById('pwa-install-btn')) return; const installBtn = document.createElement('button'); installBtn.classList.add('with-icon'); installBtn.id = 'pwa-install-btn'; const installIcon = document.createElement('zen-icon'); installIcon.setAttribute('name', 'download'); const installLabel = document.createElement('span'); installLabel.textContent = 'Install as App'; installBtn.append(installIcon, installLabel); installBtn.addEventListener('click', async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; console.log(`[PWA] User response: ${outcome}`); deferredPrompt = null; installBtn.remove(); }); const wrapper = document.createElement('zen-button'); wrapper.setAttribute('appearance', 'plain'); wrapper.setAttribute('size', 'md'); wrapper.append(installBtn); document.body.appendChild(wrapper); setTimeout(() => { installBtn.style.opacity = '0'; installBtn.style.transition = 'opacity 0.3s'; setTimeout(() => wrapper.remove(), 300); }, 5000); } window.addEventListener('appinstalled', () => { console.log('[PWA] App installed successfully!'); deferredPrompt = null; const installBtn = document.getElementById('pwa-install-btn'); if (installBtn) installBtn.closest('zen-button')?.remove(); });