|
1 |
| -// Stores |
2 |
| -import { usePwaStore } from '@/store/pwa' |
3 |
| -import { useUserStore } from '@/store/user' |
4 |
| - |
5 | 1 | // Types
|
6 | 2 | import type { Router } from 'vue-router'
|
7 | 3 |
|
8 | 4 | export async function installPwa (router: Router) {
|
9 |
| - const { registerSW } = await import('virtual:pwa-register') |
10 |
| - |
11 | 5 | await router.isReady()
|
12 | 6 |
|
13 |
| - const pwa = usePwaStore() |
14 |
| - const user = useUserStore() |
15 |
| - pwa.updateSW = registerSW({ |
16 |
| - async onNeedRefresh () { |
17 |
| - const registration = await navigator.serviceWorker?.getRegistration() |
18 |
| - if (registration?.active && registration?.waiting) { |
19 |
| - const manifest = await messageSW(registration.active, { type: 'GET_MANIFEST' }) |
20 |
| - await messageSW(registration.waiting, { type: 'SET_MANIFEST', manifest }) |
21 |
| - } |
| 7 | + let pendingUpdate = false |
| 8 | + if ('serviceWorker' in navigator) { |
| 9 | + navigator.serviceWorker.addEventListener('controllerchange', async () => { |
| 10 | + pendingUpdate = true |
| 11 | + }) |
| 12 | + } |
22 | 13 |
|
23 |
| - if (user.pwaRefresh) pwa.snackbar = true |
24 |
| - }, |
25 |
| - }) |
26 |
| - |
27 |
| - let registration: ServiceWorkerRegistration | undefined |
28 | 14 | router.beforeEach(async (to, from) => {
|
29 | 15 | if (to.path !== from.path) {
|
| 16 | + if (pendingUpdate) { |
| 17 | + console.log('Reloading page to update service worker') |
| 18 | + window.location.pathname = to.fullPath |
| 19 | + } |
| 20 | + |
30 | 21 | navigator.serviceWorker?.getRegistration().then(reg => {
|
31 |
| - registration = reg |
32 | 22 | reg?.update()
|
33 | 23 | })
|
34 |
| - |
35 |
| - if (!user.pwaRefresh && registration?.active && registration?.waiting) { |
36 |
| - pwa.loading = true |
37 |
| - const promise = new Promise<void>(resolve => { |
38 |
| - registration!.waiting?.addEventListener('statechange', e => { |
39 |
| - const sw = e.target as ServiceWorker |
40 |
| - console.log('SW state change:', sw.state) |
41 |
| - if (sw.state === 'activated') { |
42 |
| - window.location.pathname = to.fullPath |
43 |
| - resolve() |
44 |
| - } else if (sw.state === 'redundant') { |
45 |
| - resolve() |
46 |
| - } |
47 |
| - }) |
48 |
| - }) |
49 |
| - await messageSW(registration.waiting, { type: 'SKIP_WAITING' }) |
50 |
| - await promise |
51 |
| - } |
52 |
| - } |
53 |
| - }) |
54 |
| -} |
55 |
| - |
56 |
| -function messageSW (sw: ServiceWorker, data: {}): Promise<any> { |
57 |
| - return new Promise(resolve => { |
58 |
| - const messageChannel = new MessageChannel() |
59 |
| - messageChannel.port1.onmessage = (event: MessageEvent) => { |
60 |
| - resolve(event.data) |
61 | 24 | }
|
62 |
| - sw.postMessage(data, [messageChannel.port2]) |
63 | 25 | })
|
64 | 26 | }
|
0 commit comments