feat: offline & loading indicators
This commit is contained in:
parent
4e6831165c
commit
f9c8565942
26
app.js
26
app.js
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
23
index.html
23
index.html
|
@ -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()">></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
9
sw.js
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue