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/components/pwa/PwaInstallPrompt.client.vue b/components/pwa/PwaInstallPrompt.client.vue
new file mode 100644
index 00000000..6685f7d8
--- /dev/null
+++ b/components/pwa/PwaInstallPrompt.client.vue
@@ -0,0 +1,22 @@
+
+
+
+ {{ $t('pwa.install_title') }}
+
+
+
+
+
+
+
+
diff --git a/components/pwa/PwaPrompt.client.vue b/components/pwa/PwaPrompt.client.vue
index 5ed5f271..1a9cd92e 100644
--- a/components/pwa/PwaPrompt.client.vue
+++ b/components/pwa/PwaPrompt.client.vue
@@ -16,6 +16,6 @@
{{ $t('pwa.dismiss') }}
-
+
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,