From b1876bc16076044f12233604c3cd519d904d7c9b Mon Sep 17 00:00:00 2001 From: userquin Date: Wed, 18 Jan 2023 20:45:00 +0100 Subject: [PATCH] feat(pwa): installable pwa widget --- components/main/MainContent.vue | 1 + components/pwa/PwaInstallPrompt.client.vue | 22 ++++++++++++ layouts/default.vue | 1 + locales/en-GB.json | 2 ++ locales/en-US.json | 2 ++ locales/es-ES.json | 2 ++ plugins/pwa.client.ts | 40 ++++++++++++++++++++++ 7 files changed, 70 insertions(+) create mode 100644 components/pwa/PwaInstallPrompt.client.vue diff --git a/components/main/MainContent.vue b/components/main/MainContent.vue index 23e68724..b38e9cb5 100644 --- a/components/main/MainContent.vue +++ b/components/main/MainContent.vue @@ -38,6 +38,7 @@ defineProps<{ diff --git a/components/pwa/PwaInstallPrompt.client.vue b/components/pwa/PwaInstallPrompt.client.vue new file mode 100644 index 00000000..bb9cfac0 --- /dev/null +++ b/components/pwa/PwaInstallPrompt.client.vue @@ -0,0 +1,22 @@ + diff --git a/layouts/default.vue b/layouts/default.vue index 6f73ea45..237501ed 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -64,6 +64,7 @@ const isGrayscale = usePreferences('grayscaleMode')
+
diff --git a/locales/en-GB.json b/locales/en-GB.json index 3bea8345..a1de784b 100644 --- a/locales/en-GB.json +++ b/locales/en-GB.json @@ -178,6 +178,8 @@ }, "pwa": { "dismiss": "Dismiss", + "install": "Install", + "install_title": "Install Elk", "title": "New Elk update available!", "update": "Update", "update_available_short": "Update Elk" diff --git a/locales/en-US.json b/locales/en-US.json index 0b991c02..16f9662a 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -241,6 +241,8 @@ }, "pwa": { "dismiss": "Dismiss", + "install": "Install", + "install_title": "Install Elk", "title": "New Elk update available!", "update": "Update", "update_available_short": "Update Elk", diff --git a/locales/es-ES.json b/locales/es-ES.json index 41f79445..5326f17d 100644 --- a/locales/es-ES.json +++ b/locales/es-ES.json @@ -204,6 +204,8 @@ }, "pwa": { "dismiss": "Descartar", + "install": "Instalar", + "install_title": "Instalar Elk", "title": "Nueva versiĆ³n de Elk disponible", "update": "Actualizar", "update_available_short": "Actualiza Elk", diff --git a/plugins/pwa.client.ts b/plugins/pwa.client.ts index dfa60334..5d90f303 100644 --- a/plugins/pwa.client.ts +++ b/plugins/pwa.client.ts @@ -4,6 +4,7 @@ export default defineNuxtPlugin(() => { const online = useOnline() const registrationError = ref(false) const swActivated = ref(false) + const showInstallPrompt = ref(false) // https://thomashunter.name/posts/2021-12-11-detecting-if-pwa-twa-is-installed const ua = navigator.userAgent @@ -57,10 +58,49 @@ export default defineNuxtPlugin(() => { needRefresh.value = false } + type InstallPromptEvent = Event & { + prompt: () => void + userChoice: Promise<{ outcome: 'dismissed' | 'accepted' }> + } + + let deferredPrompt: InstallPromptEvent | undefined + + const beforeInstallPrompt = (e: Event) => { + e.preventDefault() + deferredPrompt = e as InstallPromptEvent + showInstallPrompt.value = true + } + window.addEventListener('beforeinstallprompt', beforeInstallPrompt) + window.addEventListener('appinstalled', () => { + deferredPrompt = undefined + showInstallPrompt.value = false + }) + + const install = async () => { + if (!showInstallPrompt.value || !deferredPrompt) { + showInstallPrompt.value = false + return + } + + showInstallPrompt.value = false + await nextTick() + deferredPrompt.prompt() + const { outcome } = await deferredPrompt.userChoice + if (outcome === 'dismissed') + window.removeEventListener('beforeinstallprompt', beforeInstallPrompt) + } + + const cancelInstall = () => { + showInstallPrompt.value = false + } + return { provide: { pwa: reactive({ isInstalled, + showInstallPrompt, + cancelInstall, + install, swActivated, registrationError, needRefresh,