Mercurial
annotate mrjunejune/src/public/pwa-register.js @ 258:60a876c4587a
[ui] Add semantic primitive ownership
Build a layered Zenbu token and sizing system, make authored controls use native-underneath primitives, migrate mrjunejune without imposing visual surfaces, and document/enforce HTML ownership in the catalog and wiki.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Wed, 05 Aug 2026 05:25:40 -0700 |
| parents | 30c2196d03d4 |
| children | e02e2036ef84 |
| rev | line source |
|---|---|
| 209 | 1 // PWA Service Worker Registration |
| 2 if ('serviceWorker' in navigator) { | |
| 3 window.addEventListener('load', () => { | |
| 4 navigator.serviceWorker | |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
211
diff
changeset
|
5 .register('/sw.js', { scope: '/' }) |
| 209 | 6 .then((registration) => { |
|
211
a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
MrJuneJune <me@mrjunejune.com>
parents:
209
diff
changeset
|
7 // console.log('[PWA] Service Worker registered:', registration.scope); |
| 209 | 8 |
| 9 // Check for updates periodically | |
| 10 setInterval(() => { | |
| 11 registration.update(); | |
| 12 }, 60000); // Check every minute | |
| 13 | |
| 14 // Handle updates | |
| 15 registration.addEventListener('updatefound', () => { | |
| 16 const newWorker = registration.installing; | |
| 17 newWorker.addEventListener('statechange', () => { | |
| 18 if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { | |
| 19 // New content available, show update notification | |
| 20 if (confirm('New version available! Reload to update?')) { | |
| 21 newWorker.postMessage({ type: 'SKIP_WAITING' }); | |
| 22 window.location.reload(); | |
| 23 } | |
| 24 } | |
| 25 }); | |
| 26 }); | |
| 27 }) | |
| 28 .catch((error) => { | |
| 29 console.error('[PWA] Service Worker registration failed:', error); | |
| 30 }); | |
| 31 | |
| 32 // Handle service worker updates | |
| 33 let refreshing = false; | |
| 34 navigator.serviceWorker.addEventListener('controllerchange', () => { | |
| 35 if (!refreshing) { | |
| 36 refreshing = true; | |
| 37 window.location.reload(); | |
| 38 } | |
| 39 }); | |
| 40 }); | |
| 41 } | |
| 42 | |
| 43 // Add install prompt handler | |
| 44 let deferredPrompt; | |
| 45 | |
| 46 window.addEventListener('beforeinstallprompt', (e) => { | |
| 47 e.preventDefault(); | |
| 48 deferredPrompt = e; | |
| 49 | |
| 50 showInstallPromotion(); | |
| 51 }); | |
| 52 | |
| 53 function showInstallPromotion() { | |
| 54 // Create an install button if it doesn't exist | |
| 55 if (document.getElementById('pwa-install-btn')) return; | |
| 56 | |
| 57 const installBtn = document.createElement('button'); | |
| 58 installBtn.classList.add('with-icon'); | |
| 59 installBtn.id = 'pwa-install-btn'; | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
60 const installIcon = document.createElement('zen-icon'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
61 installIcon.setAttribute('name', 'download'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
62 const installLabel = document.createElement('span'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
63 installLabel.textContent = 'Install as App'; |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
64 installBtn.append(installIcon, installLabel); |
| 209 | 65 |
| 66 installBtn.addEventListener('click', async () => { | |
| 67 if (!deferredPrompt) return; | |
| 68 | |
| 69 deferredPrompt.prompt(); | |
| 70 const { outcome } = await deferredPrompt.userChoice; | |
| 71 console.log(`[PWA] User response: ${outcome}`); | |
| 72 | |
| 73 deferredPrompt = null; | |
| 74 installBtn.remove(); | |
| 75 }); | |
| 76 | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
77 const wrapper = document.createElement('zen-button'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
78 wrapper.setAttribute('appearance', 'plain'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
79 wrapper.setAttribute('size', 'md'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
80 wrapper.append(installBtn); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
81 document.body.appendChild(wrapper); |
| 209 | 82 |
|
211
a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
MrJuneJune <me@mrjunejune.com>
parents:
209
diff
changeset
|
83 setTimeout(() => { |
|
a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
MrJuneJune <me@mrjunejune.com>
parents:
209
diff
changeset
|
84 installBtn.style.opacity = '0'; |
|
a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
MrJuneJune <me@mrjunejune.com>
parents:
209
diff
changeset
|
85 installBtn.style.transition = 'opacity 0.3s'; |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
86 setTimeout(() => wrapper.remove(), 300); |
|
211
a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
MrJuneJune <me@mrjunejune.com>
parents:
209
diff
changeset
|
87 }, 5000); |
| 209 | 88 } |
| 89 | |
| 90 window.addEventListener('appinstalled', () => { | |
| 91 console.log('[PWA] App installed successfully!'); | |
| 92 deferredPrompt = null; | |
| 93 | |
| 94 const installBtn = document.getElementById('pwa-install-btn'); | |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
95 if (installBtn) installBtn.closest('zen-button')?.remove(); |
| 209 | 96 }); |