2019-05-08 07:52:12 -07:00
|
|
|
|
import { snackbar } from '../_components/snackbar/snackbar'
|
2018-01-18 23:37:43 -08:00
|
|
|
|
|
2019-05-28 08:18:11 -07:00
|
|
|
|
// A lot of this code is borrowed from https://github.com/GoogleChromeLabs/squoosh/blob/53b46f8/src/lib/offliner.ts
|
|
|
|
|
// Service Workers are hard!
|
2018-01-18 23:37:43 -08:00
|
|
|
|
|
2019-05-28 08:18:11 -07:00
|
|
|
|
// Tell the service worker to skip waiting
|
|
|
|
|
async function skipWaiting () {
|
|
|
|
|
const reg = await navigator.serviceWorker.getRegistration()
|
|
|
|
|
if (!reg || !reg.waiting) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
reg.waiting.postMessage('skip-waiting')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait for an installing worker
|
|
|
|
|
async function installingWorker (reg) {
|
|
|
|
|
if (reg.installing) {
|
|
|
|
|
return reg.installing
|
|
|
|
|
}
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
reg.addEventListener(
|
|
|
|
|
'updatefound',
|
|
|
|
|
() => resolve(reg.installing),
|
|
|
|
|
{ once: true }
|
|
|
|
|
)
|
2018-02-08 22:29:29 -08:00
|
|
|
|
})
|
2018-01-18 23:37:43 -08:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 08:18:11 -07:00
|
|
|
|
// Wait a service worker to become waiting
|
|
|
|
|
async function updateReady (reg) {
|
|
|
|
|
if (reg.waiting) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const installing = await installingWorker(reg)
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
const listener = () => {
|
|
|
|
|
if (installing.state === 'installed') {
|
|
|
|
|
installing.removeEventListener('statechange', listener)
|
|
|
|
|
resolve()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
installing.addEventListener('statechange', listener)
|
2018-01-18 23:37:43 -08:00
|
|
|
|
})
|
2018-02-08 22:29:29 -08:00
|
|
|
|
}
|
2019-05-28 08:18:11 -07:00
|
|
|
|
|
|
|
|
|
(async () => {
|
|
|
|
|
if ('serviceWorker' in navigator) {
|
|
|
|
|
navigator.serviceWorker.register('/service-worker.js')
|
|
|
|
|
|
|
|
|
|
const hasController = !!navigator.serviceWorker.controller
|
|
|
|
|
|
|
|
|
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
|
|
|
if (!hasController) { // first install
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
location.reload()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// If we don't have a controller, we don't need to check for updates – we've just loaded from the
|
|
|
|
|
// network.
|
|
|
|
|
if (!hasController) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const reg = await navigator.serviceWorker.getRegistration()
|
|
|
|
|
if (!reg) { // SW not registered yet
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look for updates
|
|
|
|
|
await updateReady(reg)
|
|
|
|
|
|
|
|
|
|
// Ask the user if they want to update.
|
|
|
|
|
snackbar.announce('App update available.', 'Reload', () => {
|
|
|
|
|
// Tell the waiting worker to activate, this will change the controller and cause a reload (see
|
|
|
|
|
// 'controllerchange')
|
|
|
|
|
/* no await */ skipWaiting()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})()
|