diff --git a/index.html b/index.html index e55616d71..3726b8c9f 100644 --- a/index.html +++ b/index.html @@ -12,9 +12,9 @@ - + diff --git a/public/assets/images/favicon/site.webmanifest b/public/assets/images/favicon/site.webmanifest deleted file mode 100644 index 122a030b8..000000000 --- a/public/assets/images/favicon/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Vite ma dose", - "short_name": "Vite ma dose", - "icons": [ - { - "src": "/assets/images/favicon/android-chrome-192x192.png?v=oLnE8zppbY", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/assets/images/favicon/android-chrome-512x512.png?v=oLnE8zppbY", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest new file mode 100644 index 000000000..09486b5f2 --- /dev/null +++ b/public/manifest.webmanifest @@ -0,0 +1,29 @@ +{ + "short_name": "ViteMaDose", + "name": "ViteMaDose : Trouver un vaccin facilement et rapidement", + "icons": [ + { + "src": "/assets/images/favicon/android-chrome-192x192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "/assets/images/favicon/android-chrome-512x512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": "/", + "background_color": "#5561d9", + "display": "minimal-ui", + "theme_color": "#5561d9", + "shortcuts": [], + "description": "Trouver un vaccin facilement et rapidement", + "screenshots": [ + { + "src": "/assets/images/social/vitemadose.png", + "type": "image/png", + "sizes": "2704x1476" + } + ] +} diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 000000000..20cffb7a2 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,31 @@ + +function clientRootUrl() { + return self.location.href.replace("sw.js",""); +} + +function env() { + return (self.location.hostname === "vitemadose.covidtracker.fr")?'prod':'dev'; +} + + +self.addEventListener('install', function(event) { + console.log('Service Worker activating...'); + // event.waitUntil(self.skipWaiting()); // Activate worker immediately +}); + +self.addEventListener('activate', function(event) { + console.log('Service Worker activating...'); + event.waitUntil( + Promise.all([ + Promise.resolve() + ]).then(function() { + console.log('SW activation finished !'); + return self.clients.claim(); + }) + ); +}); + +// Dummy fetch handler to make PWA installable (without this, we won't have the installation CTA on the website) +self.addEventListener('fetch', function(event) { + //console.log("in dummy fetch handler"); +}); diff --git a/src/utils/ServiceWorkers.ts b/src/utils/ServiceWorkers.ts new file mode 100644 index 000000000..0893b5890 --- /dev/null +++ b/src/utils/ServiceWorkers.ts @@ -0,0 +1,50 @@ +import {Router} from "../routing/Router"; + +export class ServiceWorkers { + + public static readonly INSTANCE = new ServiceWorkers(); + + private constructor() { + } + + async startup() { + // Registering background synchronization + if (!navigator.serviceWorker){ + console.info("Service Worker not supported") + return false; + } + + // Waiting for 'load' event to start service worker registration + // see https://developers.google.com/web/fundamentals/primers/service-workers/registration#improving_the_boilerplate + await new Promise((resolve) => window.addEventListener('load', resolve)); + + const serviceWorkerRegistration = await navigator.serviceWorker.register(`${Router.basePath}sw.js`); + + navigator.serviceWorker.addEventListener('controllerchange', () => { + console.log("controllerchange called !"); + }); + + // Cases : + // - navigator.serviceWorker.controller is undefined : this occurs the first time the sw is installed + // in that case, we should look for updatefound + statechange=activated events to resolve controller + // - navigator.serviceWorker.controller is defined, we should play with is, but don't forget to register a + // controller change event in case a new version of the sw is deployed + + await new Promise<{controller: ServiceWorker, updated: boolean}>((resolve) => { + if(navigator.serviceWorker.controller) { + resolve({controller: navigator.serviceWorker.controller, updated: false}); + } + + serviceWorkerRegistration.addEventListener('updatefound', () => { + const newWorker = serviceWorkerRegistration.installing!; + newWorker.addEventListener('statechange', () => { + if(newWorker.state === 'activated') { + resolve({ controller: navigator.serviceWorker.controller!, updated: true}); + } + }) + }); + }) + + return true; + } +} diff --git a/src/vmd-app.component.ts b/src/vmd-app.component.ts index a174a3f76..1cd097c77 100644 --- a/src/vmd-app.component.ts +++ b/src/vmd-app.component.ts @@ -2,6 +2,7 @@ import {LitElement, html, customElement, property, css } from 'lit-element'; import {Router, SlottedTemplateResultFactory} from "./routing/Router"; import smoothscroll from 'smoothscroll-polyfill'; import {CSS_Global} from "./styles/ConstructibleStyleSheets"; +import {ServiceWorkers} from "./utils/ServiceWorkers"; @customElement('vmd-app') export class VmdAppComponent extends LitElement { @@ -27,6 +28,8 @@ export class VmdAppComponent extends LitElement { Router.installRoutes((viewTemplateResult) => { this.viewTemplateResult = viewTemplateResult; }) + + ServiceWorkers.INSTANCE.startup(); } render() {