Show an error page when offline

This commit is contained in:
Karina Kwiatek 2023-01-21 18:54:08 +01:00
parent 95984cfdab
commit 6207863271
2 changed files with 188 additions and 0 deletions

149
public/pwa_offline.html Normal file
View file

@ -0,0 +1,149 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>You are offline</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="theme-color" content="#f0edf4">
<style>
:root {
--primary: #5e35b1;
--muted: 108, 117, 125;
--background: #f0edf4;
}
*, *:before, *:after {
box-sizing: border-box;
}
a {
color: var(--primary);
text-decoration: none;
}
body {
padding: 2rem 1rem 1rem 1rem;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
background-color: var(--background);
}
.text-primary {
color: var(--primary);
}
.text-muted {
color: rgb(var(--muted));
}
.text-center {
text-align: center;
}
.font-weight-bold {
font-weight: bold;
}
.d-none {
display: none !important;
}
.links {
padding: 0;
}
.links li {
display: inline-block;
}
.links li:not(:last-child):after {
content: ' • ';
}
.mb-0 {
margin-bottom: 0;
}
.mt-0 {
margin-top: 0;
}
.error-artwork-container {
display:flex;
justify-content: center;
max-width: 100%;
}
.error-artwork-container picture {
display: block;
max-width: 100%;
}
.error-artwork-container picture img {
max-width: 100%;
}
.error-text-container {
text-align: center;
}
@media (min-width: 768px) {
body {
padding: 3rem 1rem 1rem 1rem;
}
.error-artwork-container picture {
width: 576px;
}
}
@media (min-width: 992px) {
body {
padding: 5rem 1rem 3rem 1rem;
}
.error {
display: flex;
justify-content: center;
}
.error-text-container {
align-self: center;
text-align: left;
}
}
</style>
</head>
<body>
<div class="error">
<div class="error-artwork-container">
<picture>
<source
srcset="/images/errors/small/404.png 576w,
/images/errors/medium/404.png 768w,
/images/errors/original/404.png 1200w">
<img src="/images/errors/small/404.png" alt="A raccoon peeking out of a bin, looking confused" />
</picture>
</div>
<div class="error-text-container">
<h1>
<span class="text-primary font-weight-bold">404</span>
<small class="text-muted">You are offline</small>
</h1>
<p>
This content is not available offline.
</p>
<ul class="links">
<li>
<a href="/">Retry</a>
</li>
</ul>
</div>
</div>
<script>
window.addEventListener('online', () => {
window.location.reload();
});
</script>
</body>
</html>

View file

@ -1,3 +1,14 @@
const OFFLINE_CACHE_NAME = "offline";
// Bumping this version will force an update of the service worker
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const OFFLINE_PAGE_VERSION = 1;
const OFFLINE_CACHE_PATHS = [
"/pwa_offline.html",
"/images/errors/small/404.png",
"/images/errors/medium/404.png",
"/images/errors/original/404.png"
];
self.addEventListener('push', function (event) {
if (event.data) {
const notification = event.data.json();
@ -23,3 +34,31 @@ self.addEventListener('notificationclick', async event => {
console.warn(`Unhandled notification tag: ${event.notification.tag}`);
}
});
self.addEventListener('install', function (event) {
event.waitUntil(
(async () => {
const cache = await caches.open(OFFLINE_CACHE_NAME);
await cache.addAll(OFFLINE_CACHE_PATHS);
})()
);
// Immediately activate new versions of the service worker instead of waiting
self.skipWaiting();
});
self.addEventListener('fetch', function (event) {
event.respondWith(
(async () => {
try {
// Try to load the resource
return await fetch(event.request);
} catch (error) {
// Show an error page if offline
console.log("Fetch failed; returning offline page instead.", error);
const cache = await caches.open(OFFLINE_CACHE_NAME);
return await cache.match(OFFLINE_CACHE_PATHS[0]);
}
})()
);
});