From e92a9839475a5febcd645ae4379a7b4f8eaf8aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Sun, 8 Jan 2023 15:12:25 +0100 Subject: [PATCH] fix(pwa): handle sw registration error and status (#858) --- composables/users.ts | 8 +++---- plugins/pwa.client.ts | 54 +++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/composables/users.ts b/composables/users.ts index 3c8ab824..e1c50bcc 100644 --- a/composables/users.ts +++ b/composables/users.ts @@ -180,9 +180,6 @@ export function getUsersIndexByUserId(userId: string) { } export async function removePushNotificationData(user: UserLogin, fromSWPushManager = true) { - if (!user.pushSubscription) - return - // clear push subscription user.pushSubscription = undefined const { acct } = user.account @@ -192,9 +189,12 @@ export async function removePushNotificationData(user: UserLogin, fromSWPushMana delete useLocalStorage(STORAGE_KEY_NOTIFICATION_POLICY, {}).value[acct] const pwaEnabled = useRuntimeConfig().public.pwaEnabled + const pwa = useNuxtApp().$pwa + const registrationError = pwa?.registrationError === true + const unregister = pwaEnabled && !registrationError && pwa?.registrationError === true && fromSWPushManager // we remove the sw push manager if required and there are no more accounts with subscriptions - if (pwaEnabled && fromSWPushManager && (users.value.length === 0 || users.value.every(u => !u.pushSubscription))) { + if (unregister && (users.value.length === 0 || users.value.every(u => !u.pushSubscription))) { // clear sw push subscription try { const registration = await navigator.serviceWorker.ready diff --git a/plugins/pwa.client.ts b/plugins/pwa.client.ts index 1bc21afa..ac0f9932 100644 --- a/plugins/pwa.client.ts +++ b/plugins/pwa.client.ts @@ -2,30 +2,48 @@ import { useRegisterSW } from 'virtual:pwa-register/vue' export default defineNuxtPlugin(() => { const online = useOnline() + const registrationError = ref(false) + const swActivated = ref(false) + + const registerPeriodicSync = (swUrl: string, r: ServiceWorkerRegistration) => { + setInterval(async () => { + if (!online.value) + return + + const resp = await fetch(swUrl, { + cache: 'no-store', + headers: { + 'cache': 'no-store', + 'cache-control': 'no-cache', + }, + }) + + if (resp?.status === 200) + await r.update() + }, 60 * 60 * 1000 /* 1 hour */) + } const { needRefresh, updateServiceWorker, } = useRegisterSW({ immediate: true, + onRegisterError() { + registrationError.value = true + }, onRegisteredSW(swUrl, r) { - if (!r || r.installing) - return - - setInterval(async () => { - if (!online.value) - return - - const resp = await fetch(swUrl, { - cache: 'no-store', - headers: { - 'cache': 'no-store', - 'cache-control': 'no-cache', - }, + // should add support in pwa plugin + if (r?.active?.state === 'activated') { + swActivated.value = true + registerPeriodicSync(swUrl, r) + } + else if (r?.installing) { + r.installing.addEventListener('statechange', (e) => { + const sw = e.target as ServiceWorker + swActivated.value = sw.state === 'activated' + if (swActivated.value) + registerPeriodicSync(swUrl, r) }) - - if (resp?.status === 200) - await r.update() - }, 60 * 60 * 1000 /* 1 hour */) + } }, }) @@ -36,6 +54,8 @@ export default defineNuxtPlugin(() => { return { provide: { pwa: reactive({ + swActivated, + registrationError, needRefresh, updateServiceWorker, close,