47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { useEffect, useState } from "react"
|
|
|
|
export function useSwUpdate() {
|
|
const [waitingWorker, setWaitingWorker] = useState<ServiceWorker | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (!("serviceWorker" in navigator)) return
|
|
|
|
navigator.serviceWorker
|
|
.register("/movie-select/sw.js")
|
|
.then((registration) => {
|
|
// Already a waiting worker from a previous visit
|
|
if (registration.waiting) {
|
|
setWaitingWorker(registration.waiting)
|
|
}
|
|
|
|
registration.addEventListener("updatefound", () => {
|
|
const newWorker = registration.installing
|
|
if (!newWorker) return
|
|
|
|
newWorker.addEventListener("statechange", () => {
|
|
if (
|
|
newWorker.state === "installed" &&
|
|
navigator.serviceWorker.controller
|
|
) {
|
|
setWaitingWorker(newWorker)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
// Reload when the new worker takes over
|
|
let refreshing = false
|
|
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
|
if (refreshing) return
|
|
refreshing = true
|
|
window.location.reload()
|
|
})
|
|
}, [])
|
|
|
|
function applyUpdate() {
|
|
waitingWorker?.postMessage("skipWaiting")
|
|
}
|
|
|
|
return { updateAvailable: waitingWorker !== null, applyUpdate }
|
|
}
|