From f96cdae1ba75003a31cf57d75d9519818217402e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Wed, 25 Jan 2023 16:26:51 +0100 Subject: [PATCH] feat(pwa): add install PWA widget (#1451) --- components/main/MainContent.vue | 1 + components/pwa/PwaInstallPrompt.client.vue | 22 ++++++++++++ components/pwa/PwaPrompt.client.vue | 2 +- layouts/default.vue | 1 + locales/en.json | 2 ++ locales/es.json | 2 ++ locales/fr-FR.json | 2 ++ plugins/pwa.client.ts | 42 ++++++++++++++++++++++ 8 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 components/pwa/PwaInstallPrompt.client.vue diff --git a/components/main/MainContent.vue b/components/main/MainContent.vue index c6a0bc0f..9e5804e4 100644 --- a/components/main/MainContent.vue +++ b/components/main/MainContent.vue @@ -42,6 +42,7 @@ const wideLayout = computed(() => route.meta.wideLayout ?? false) -
+
diff --git a/layouts/default.vue b/layouts/default.vue index 06fed06e..aca1daa1 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -65,6 +65,7 @@ const isGrayscale = usePreferences('grayscaleMode')
+ diff --git a/locales/en.json b/locales/en.json index a2f79959..6b028be7 100644 --- a/locales/en.json +++ b/locales/en.json @@ -248,6 +248,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.json b/locales/es.json index ee7cc2fd..a73d615d 100644 --- a/locales/es.json +++ b/locales/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/locales/fr-FR.json b/locales/fr-FR.json index 09be1fa5..3418d1fe 100644 --- a/locales/fr-FR.json +++ b/locales/fr-FR.json @@ -253,6 +253,8 @@ }, "pwa": { "dismiss": "Fermer", + "install": "Installer", + "install_title": "Installer Elk", "title": "Nouvelle mise à jour Elk disponible !", "update": "Mettre à jour", "update_available_short": "Mettre à jour Elk", diff --git a/plugins/pwa.client.ts b/plugins/pwa.client.ts index dfa60334..79e8c776 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,51 @@ 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 cancelInstall = () => { + deferredPrompt = undefined + showInstallPrompt.value = false + window.removeEventListener('beforeinstallprompt', beforeInstallPrompt) + } + + 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') + cancelInstall() + } + return { provide: { pwa: reactive({ isInstalled, + showInstallPrompt, + cancelInstall, + install, swActivated, registrationError, needRefresh,