JournalBook
JournalBook copied to clipboard
Service Worker update notifier
I've been using this:
let hasInteracted, toast;
function setHasInteracted() {
hasInteracted = true
}
['popstate','click','touchstart'].forEach(e => {
addEventListener(e, setHasInteracted, { passive: true });
})
navigator.serviceWorker.register('/sw.js').then(reg => {
reg.onupdatefound = () => {
reg.installing.onstatechange = () => {
if (toast || (navigator.serviceWorker.controller || {}).state !== 'installed') return;
if (!hasInteracted) location.reload();
toast = render(
<div id="toast">
Update available
<button onClick={() => location.reload()}>Reload</button>
</div>
, document.body);
};
};
});
#toast {
box-sizing: border-box;
position: fixed;
display: flex;
align-items: center;
justify-content: space-between;
left: 50%;
bottom: 10px;
width: 300px;
max-width: calc(100vw - 20px);
padding: 10px;
transform: translate(-50%, 0);
background: rgba(50,50,50,0.99);
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0,0,0,0.5);
color: #ddd;
font-size: 14px;
pointer-events: none;
animation: toast-in 500ms ease-out forwards 1;
}
#toast button {
flex: 0;
padding: 6px 12px;
margin: 0;
border: none;
border-radius: 5px;
background: rgba(0,0,0,0.3);
font: inherit;
text-transform: uppercase;
color: white;
pointer-events: all;
outline: none;
}
#toast button:focus {
background-color: rgba(0,0,0,0.6);
}
@keyframes toast-in {
0% { transform: translate(-50%, 150%); }
}
@developit oh lovely! Thanks so much - I'll give it a go now 😁 This is using the Preact CLI SW, is calling navigator.serviceWorker.register('/sw.js') manually all good, or does this need to hook into the existing registration somehow?