This commit is contained in:
@@ -2,3 +2,4 @@
|
|||||||
.idea
|
.idea
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
/.idea/
|
||||||
|
|||||||
@@ -26,3 +26,4 @@ coverage
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
/dev-dist/
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import {onMounted, ref} from "vue";
|
|||||||
import {Auth} from "@/services/auth";
|
import {Auth} from "@/services/auth";
|
||||||
import DialogHost from "@/components/dialog/DialogHost.vue";
|
import DialogHost from "@/components/dialog/DialogHost.vue";
|
||||||
import {LoginService} from "@/services/LoginService";
|
import {LoginService} from "@/services/LoginService";
|
||||||
|
import {Dialogs} from "@/services/DialogService";
|
||||||
|
import InstallPWADialog from "@/components/dialog/InstallPWADialog.vue";
|
||||||
|
|
||||||
let showPopup = ref(false)
|
let showPopup = ref(false)
|
||||||
let loggedIn = ref(false)
|
let loggedIn = ref(false)
|
||||||
@@ -33,6 +35,40 @@ LoginService.subject.subscribe(() => {
|
|||||||
showPopup.value = true
|
showPopup.value = true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const installEvent = ref<Event>()
|
||||||
|
|
||||||
|
window.addEventListener('beforeinstallprompt', (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
console.log("beforeinstallprompt")
|
||||||
|
installEvent.value = e
|
||||||
|
scheduleInstallDialog()
|
||||||
|
})
|
||||||
|
|
||||||
|
function scheduleInstallDialog() {
|
||||||
|
if (isPwa()) return
|
||||||
|
if (localStorage.getItem('installPromptDismissed')) return
|
||||||
|
if (!installEvent.value) return
|
||||||
|
|
||||||
|
Dialogs.createDialog(InstallPWADialog, {
|
||||||
|
onPositive(dontShowAgain: boolean) {
|
||||||
|
if (dontShowAgain) localStorage.setItem('installPromptDismissed', 'true')
|
||||||
|
;(installEvent.value as any).prompt()
|
||||||
|
},
|
||||||
|
onNegative(dontShowAgain: boolean) {
|
||||||
|
if (dontShowAgain) localStorage.setItem('installPromptDismissed', 'true')
|
||||||
|
},
|
||||||
|
onDismiss() {}
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPwa() {
|
||||||
|
return window.matchMedia('(display-mode: standalone)').matches
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('appinstalled', () => {
|
||||||
|
localStorage.setItem('installPromptDismissed', 'true')
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import {ref} from "vue";
|
||||||
|
import Dialog from "@/components/dialog/Dialog.vue";
|
||||||
|
import type {DialogControls} from "@/components/dialog/dialog";
|
||||||
|
|
||||||
|
interface InstallPWADialogProps extends DialogControls {
|
||||||
|
}
|
||||||
|
|
||||||
|
defineProps<InstallPWADialogProps>()
|
||||||
|
|
||||||
|
const dontShowAgain = ref<boolean>(false)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<Dialog class="dialog">
|
||||||
|
<h3 style="margin-bottom: 10px; display: flex; gap: 1rem; align-items: center">
|
||||||
|
Zum Startbildschirm hinzufügen
|
||||||
|
</h3>
|
||||||
|
<p style="line-height: 1.7rem">
|
||||||
|
Dein Miniplan kann jetzt auf Ihrem Gerät installiert werden, um schnell und einfach darauf zuzugreifen.
|
||||||
|
</p>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-model="dontShowAgain" />
|
||||||
|
Nicht mehr anzeigen
|
||||||
|
</label>
|
||||||
|
<div class="buttons">
|
||||||
|
<button @click="onNegative(dontShowAgain)" class="dismiss">Später</button>
|
||||||
|
<button @click="onPositive(dontShowAgain)" ><i>browser_updated</i>Jetzt hinzufügen</button>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 500px
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
.dismiss {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
+76
-74
@@ -1,79 +1,81 @@
|
|||||||
import { fileURLToPath, URL } from 'node:url'
|
import {fileURLToPath, URL} from 'node:url'
|
||||||
|
|
||||||
import { defineConfig } from 'vite'
|
import {defineConfig} from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
import {VitePWA} from 'vite-plugin-pwa'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig(({mode}) => (
|
||||||
plugins: [
|
{
|
||||||
vue(),
|
plugins: [
|
||||||
VitePWA({
|
vue(),
|
||||||
registerType: 'autoUpdate',
|
VitePWA({
|
||||||
includeAssets: ['favicon.ico', 'minis_logo.png'],
|
registerType: 'autoUpdate',
|
||||||
manifest: {
|
includeAssets: ['favicon.ico', 'minis_logo.png'],
|
||||||
name: 'Miniplan',
|
manifest: {
|
||||||
short_name: 'Miniplan',
|
name: 'Miniplan App',
|
||||||
description: 'Miniplan',
|
short_name: 'Miniplan',
|
||||||
theme_color: '#ffffff',
|
description: 'Lade deinen Miniplan direkt auf dein Handy. So hast du den Miniplan jederzeit und schnell erreichbar.',
|
||||||
background_color: '#ffffff',
|
theme_color: '#ffffff',
|
||||||
display: 'standalone',
|
background_color: '#ffffff',
|
||||||
scope: '/',
|
display: 'standalone',
|
||||||
start_url: '/',
|
scope: '/',
|
||||||
screenshots: [
|
start_url: '/',
|
||||||
{
|
screenshots: [
|
||||||
src: 'screenshot1.png',
|
{
|
||||||
sizes: '505x710',
|
src: 'screenshot1.png',
|
||||||
type: 'image/png',
|
sizes: '505x710',
|
||||||
form_factor: "narrow",
|
type: 'image/png',
|
||||||
label: "Miniplan Liste"
|
form_factor: "narrow",
|
||||||
},
|
label: "Miniplan Liste"
|
||||||
{
|
},
|
||||||
src: 'screenshot2.png',
|
{
|
||||||
sizes: '505x711',
|
src: 'screenshot2.png',
|
||||||
type: 'image/png',
|
sizes: '505x711',
|
||||||
form_factor: "narrow",
|
type: 'image/png',
|
||||||
label: "Miniplan Tabelle"
|
form_factor: "narrow",
|
||||||
},
|
label: "Miniplan Tabelle"
|
||||||
{
|
},
|
||||||
src: "screenshot3.png",
|
{
|
||||||
sizes: '1003x709',
|
src: "screenshot3.png",
|
||||||
type: 'image/png',
|
sizes: '1003x709',
|
||||||
form_factor: "wide",
|
type: 'image/png',
|
||||||
label: "Miniplan Tabelle"
|
form_factor: "wide",
|
||||||
}
|
label: "Miniplan Tabelle"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: "pwa-64x64.png",
|
||||||
|
sizes: "64x64",
|
||||||
|
type: "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "pwa-192x192.png",
|
||||||
|
sizes: "192x192",
|
||||||
|
type: "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "pwa-512x512.png",
|
||||||
|
sizes: "512x512",
|
||||||
|
type: "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "maskable-icon-512x512.png",
|
||||||
|
sizes: "512x512",
|
||||||
|
type: "image/png",
|
||||||
|
purpose: "maskable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
devOptions: {
|
||||||
|
enabled: mode === "development"
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
icons: [
|
resolve: {
|
||||||
{
|
alias: {
|
||||||
src: "pwa-64x64.png",
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
sizes: "64x64",
|
}
|
||||||
type: "image/png"
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "pwa-192x192.png",
|
|
||||||
sizes: "192x192",
|
|
||||||
type: "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "pwa-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "maskable-icon-512x512.png",
|
|
||||||
sizes: "512x512",
|
|
||||||
type: "image/png",
|
|
||||||
purpose: "maskable"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
devOptions: {
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
],
|
)
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|||||||
Reference in New Issue
Block a user