added pwa
@ -20,6 +20,7 @@
|
|||||||
import { doc, getFirestore, serverTimestamp, writeBatch, collection, getDoc } from "firebase/firestore";
|
import { doc, getFirestore, serverTimestamp, writeBatch, collection, getDoc } from "firebase/firestore";
|
||||||
import { getAuth, onAuthStateChanged, signInWithEmailAndPassword } from "firebase/auth";
|
import { getAuth, onAuthStateChanged, signInWithEmailAndPassword } from "firebase/auth";
|
||||||
import { PushNotifications } from '@capacitor/push-notifications';
|
import { PushNotifications } from '@capacitor/push-notifications';
|
||||||
|
import { Device } from '@capacitor/device';
|
||||||
|
|
||||||
const db = getFirestore()
|
const db = getFirestore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -34,6 +35,15 @@ const userAllPersons = ref([])
|
|||||||
const calEvents = ref([])
|
const calEvents = ref([])
|
||||||
const news = ref(null)
|
const news = ref(null)
|
||||||
|
|
||||||
|
if (process.client) {
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
if (!('serviceWorker' in navigator)) {
|
||||||
|
throw new Error('serviceWorker is not supported in current browser!')
|
||||||
|
}
|
||||||
|
navigator.serviceWorker.register('/sw.js')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
auth.value = getAuth()
|
auth.value = getAuth()
|
||||||
|
|
||||||
@ -55,7 +65,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
isAuthenticated.value = true
|
isAuthenticated.value = true
|
||||||
|
|
||||||
setupNotifications()
|
logDeviceInfo()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
isAuthenticated.value = false
|
isAuthenticated.value = false
|
||||||
@ -125,6 +135,14 @@ const setupNotifications = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logDeviceInfo = async () => {
|
||||||
|
const info = await Device.getInfo();
|
||||||
|
|
||||||
|
console.log(info);
|
||||||
|
|
||||||
|
if (info.platform !== 'web') setupNotifications()
|
||||||
|
};
|
||||||
|
|
||||||
const ledenlijst = ref([])
|
const ledenlijst = ref([])
|
||||||
|
|
||||||
provide('firebase', { db, ledenlijst, isAuthenticated, user, userData, userPersons, auth, userAllPersons, getPersons, calEvents, news })
|
provide('firebase', { db, ledenlijst, isAuthenticated, user, userData, userPersons, auth, userAllPersons, getPersons, calEvents, news })
|
||||||
|
@ -9,4 +9,15 @@ export default defineNuxtConfig({
|
|||||||
build: {
|
build: {
|
||||||
transpile: ['vue-toastification'],
|
transpile: ['vue-toastification'],
|
||||||
},
|
},
|
||||||
|
meta: {
|
||||||
|
title: 'WRB App',
|
||||||
|
charset: 'utf-8',
|
||||||
|
meta: [
|
||||||
|
{ name: 'theme-color', content: '#eb6330' }
|
||||||
|
],
|
||||||
|
link: [
|
||||||
|
{ rel: 'manifest', href: '/manifest.json' },
|
||||||
|
{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' }
|
||||||
|
]
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
15
frontend/package-lock.json
generated
@ -7,6 +7,7 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/core": "^4.3.0",
|
"@capacitor/core": "^4.3.0",
|
||||||
|
"@capacitor/device": "^4.0.1",
|
||||||
"@capacitor/ios": "^4.3.0",
|
"@capacitor/ios": "^4.3.0",
|
||||||
"@capacitor/push-notifications": "^4.1.0",
|
"@capacitor/push-notifications": "^4.1.0",
|
||||||
"@formkit/nuxt": "^1.0.0-beta.11-c95e605",
|
"@formkit/nuxt": "^1.0.0-beta.11-c95e605",
|
||||||
@ -585,6 +586,14 @@
|
|||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@capacitor/device": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@capacitor/device/-/device-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-D0jJFQYifmsgcz4X9MEEKH5E36ARK2CJcUCXJbcuFTChHSxK+ly7Kd6PZC73Y5GkEZIjpebWAWo5F3w9S4hsYQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@capacitor/core": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@capacitor/ios": {
|
"node_modules/@capacitor/ios": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-4.3.0.tgz",
|
||||||
@ -11282,6 +11291,12 @@
|
|||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@capacitor/device": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@capacitor/device/-/device-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-D0jJFQYifmsgcz4X9MEEKH5E36ARK2CJcUCXJbcuFTChHSxK+ly7Kd6PZC73Y5GkEZIjpebWAWo5F3w9S4hsYQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"@capacitor/ios": {
|
"@capacitor/ios": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-4.3.0.tgz",
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/core": "^4.3.0",
|
"@capacitor/core": "^4.3.0",
|
||||||
|
"@capacitor/device": "^4.0.1",
|
||||||
"@capacitor/ios": "^4.3.0",
|
"@capacitor/ios": "^4.3.0",
|
||||||
"@capacitor/push-notifications": "^4.1.0",
|
"@capacitor/push-notifications": "^4.1.0",
|
||||||
"@formkit/nuxt": "^1.0.0-beta.11-c95e605",
|
"@formkit/nuxt": "^1.0.0-beta.11-c95e605",
|
||||||
|
BIN
frontend/public/android/android-launchericon-144-144.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
frontend/public/android/android-launchericon-192-192.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
frontend/public/android/android-launchericon-48-48.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
frontend/public/android/android-launchericon-512-512.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
frontend/public/android/android-launchericon-72-72.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
frontend/public/android/android-launchericon-96-96.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
frontend/public/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
frontend/public/ios/100.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/public/ios/1024.png
Normal file
After Width: | Height: | Size: 662 KiB |
BIN
frontend/public/ios/114.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
frontend/public/ios/120.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
frontend/public/ios/128.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
frontend/public/ios/144.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
frontend/public/ios/152.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
frontend/public/ios/16.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
frontend/public/ios/167.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
frontend/public/ios/180.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
frontend/public/ios/192.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
frontend/public/ios/20.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
frontend/public/ios/256.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
frontend/public/ios/29.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
frontend/public/ios/32.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
frontend/public/ios/40.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
frontend/public/ios/50.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
frontend/public/ios/512.png
Normal file
After Width: | Height: | Size: 186 KiB |
BIN
frontend/public/ios/57.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
frontend/public/ios/58.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
frontend/public/ios/60.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
frontend/public/ios/64.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
frontend/public/ios/72.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
frontend/public/ios/76.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
frontend/public/ios/80.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
frontend/public/ios/87.png
Normal file
After Width: | Height: | Size: 10 KiB |
140
frontend/public/manifest.json
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"name": "WRB App",
|
||||||
|
"short_name": "WRB",
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#eb6330",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"scope": "/",
|
||||||
|
"start_url": "/",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-512-512.png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-192-192.png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-144-144.png",
|
||||||
|
"sizes": "144x144"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-96-96.png",
|
||||||
|
"sizes": "96x96"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-72-72.png",
|
||||||
|
"sizes": "72x72"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android/android-launchericon-48-48.png",
|
||||||
|
"sizes": "48x48"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/16.png",
|
||||||
|
"sizes": "16x16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/20.png",
|
||||||
|
"sizes": "20x20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/29.png",
|
||||||
|
"sizes": "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/32.png",
|
||||||
|
"sizes": "32x32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/40.png",
|
||||||
|
"sizes": "40x40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/50.png",
|
||||||
|
"sizes": "50x50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/57.png",
|
||||||
|
"sizes": "57x57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/58.png",
|
||||||
|
"sizes": "58x58"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/60.png",
|
||||||
|
"sizes": "60x60"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/64.png",
|
||||||
|
"sizes": "64x64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/72.png",
|
||||||
|
"sizes": "72x72"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/76.png",
|
||||||
|
"sizes": "76x76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/80.png",
|
||||||
|
"sizes": "80x80"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/87.png",
|
||||||
|
"sizes": "87x87"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/100.png",
|
||||||
|
"sizes": "100x100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/114.png",
|
||||||
|
"sizes": "114x114"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/120.png",
|
||||||
|
"sizes": "120x120"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/128.png",
|
||||||
|
"sizes": "128x128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/144.png",
|
||||||
|
"sizes": "144x144"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/152.png",
|
||||||
|
"sizes": "152x152"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/167.png",
|
||||||
|
"sizes": "167x167"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/180.png",
|
||||||
|
"sizes": "180x180"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/192.png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/256.png",
|
||||||
|
"sizes": "256x256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/512.png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "ios/1024.png",
|
||||||
|
"sizes": "1024x1024"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
48
frontend/public/sw.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
importScripts('https://cdn.jsdelivr.net/npm/workbox-cdn/workbox/workbox-sw.js')
|
||||||
|
|
||||||
|
self.addEventListener('install', () => {
|
||||||
|
self.skipWaiting()
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('activate', () => {
|
||||||
|
self.clients.claim()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Navigation route are handled by network first strategy
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
({ request }) => request.mode === 'navigate',
|
||||||
|
new workbox.strategies.NetworkFirst({ cacheName: 'navigation' })
|
||||||
|
)
|
||||||
|
|
||||||
|
// CSS are handled by a Stale While Revalidate strategy
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
({ request }) => request.destination === 'style',
|
||||||
|
new workbox.strategies.StaleWhileRevalidate({
|
||||||
|
cacheName: 'assets',
|
||||||
|
plugins: [
|
||||||
|
// Ensure that only requests that result in a 200 status are cached
|
||||||
|
new workbox.cacheableResponse.CacheableResponse({
|
||||||
|
statuses: [200]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// Images are handled with a Cache First strategy
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
({ request }) => request.destination === 'image',
|
||||||
|
new workbox.strategies.CacheFirst({
|
||||||
|
cacheName: 'images',
|
||||||
|
plugins: [
|
||||||
|
// Ensure that only requests that result in a 200 status are cached
|
||||||
|
new workbox.cacheableResponse.CacheableResponse({
|
||||||
|
statuses: [200]
|
||||||
|
}),
|
||||||
|
// Don't cache more than 50 items, and expire them after 30 days
|
||||||
|
new workbox.expiration.CacheExpiration('images', {
|
||||||
|
maxEntries: 50,
|
||||||
|
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 Days
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
BIN
frontend/resources/icon.png
Normal file
After Width: | Height: | Size: 259 KiB |
BIN
frontend/resources/splash.png
Normal file
After Width: | Height: | Size: 135 KiB |