Files
movie-select/src/client/hooks/use-sw-update.ts

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 }
}