feat: offline & loading indicators

This commit is contained in:
Sébastien NOBILI 2023-06-15 16:37:19 +02:00
parent 4e6831165c
commit f9c8565942
3 changed files with 57 additions and 1 deletions

26
app.js
View file

@ -1,7 +1,10 @@
document.addEventListener('DOMContentLoaded', () => {
fetch_data(1);
if ('serviceWorker' in navigator) {
const channel = new BroadcastChannel('sw-messages');
channel.addEventListener('message', (event) => handle_message(event.data));
navigator.serviceWorker.register('sw.js');
} else {
fetch_data(1);
}
});
@ -34,3 +37,24 @@ async function fetch_data(id) {
}
});
}
function handle_message(message) {
if (message.ready === true) {
setTimeout(() => fetch_data(1), 0);
}
if (message.offline !== undefined) {
document.getElementById('offline').style.visibility = message.offline
? 'visible'
: 'hidden';
}
if (message.loading !== undefined) {
document.getElementById('loading').style.visibility = message.loading
? 'visible'
: 'hidden';
document.getElementById('result').style.visibility = message.loading
? 'hidden'
: 'visible';
}
}

View file

@ -38,6 +38,22 @@
width: 5em;
}
#offline {
border: 1px solid red;
background-color: rgba(255, 0, 0, 0.1);
padding: 5px;
text-align: center;
color: red;
margin-top: 10px;
margin-bottom: 10px;
visibility: hidden;
}
#loading {
text-align: center;
visibility: hidden;
}
pre {
display: flex;
margin-left: auto;
@ -56,6 +72,13 @@
<button onClick="next()">&gt;</button>
</div>
<div id="offline">
You're currently offline. The data below may differ from the current
online version.
</div>
<div id="loading">loading...</div>
<pre id="result"></pre>
</body>
</html>

9
sw.js
View file

@ -9,6 +9,9 @@ const appContentToCache = [
];
const dataCacheName = `${appCacheName}-data`;
// Communication channel with clients
const channel = new BroadcastChannel('sw-messages');
/**
* First of all, the service worker will react to an 'install' event (triggered automatically)
* We'll put the application content into cache.
@ -22,6 +25,7 @@ self.addEventListener('install', (event) => {
*/
self.addEventListener('activate', () => {
self.clients.claim();
channel.postMessage({ ready: true });
});
/**
@ -60,13 +64,18 @@ async function fetch_resource(resource) {
if (response) {
return response;
} else {
channel.postMessage({ loading: true });
try {
response = await fetch(resource);
await put_into_cache(resource, response);
channel.postMessage({ loading: false });
channel.postMessage({ offline: false });
return response;
} catch (error) {
// TODO: check if error is because we're offline
response = await get_from_cache(resource);
channel.postMessage({ loading: false });
channel.postMessage({ offline: true });
if (response) {
// resource was found in data cache
return response;