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 @@
+
+
+
+ {{ $t('pwa.install_title') }}
+
+
+
+
+
+
+
+
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,