who_need_help/priv/static/offline.html

163 lines
3.9 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#047b68" />
<meta name="color-scheme" content="light dark" />
<title>Offline · Who Need Help</title>
<style>
:root {
color-scheme: light dark;
font-family:
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", sans-serif;
background: #f7f8f7;
color: #1c1d20;
}
body {
display: grid;
min-height: 100vh;
margin: 0;
place-items: center;
}
main {
width: min(31rem, calc(100% - 3rem));
text-align: center;
}
img {
width: 5rem;
height: 5rem;
}
h1 {
margin: 1.5rem 0 0.75rem;
font-size: clamp(2rem, 8vw, 3.5rem);
line-height: 1;
}
p {
margin: 0 auto;
color: #61636a;
font-size: 1.0625rem;
line-height: 1.6;
}
button {
margin-top: 1.75rem;
border: 0;
border-radius: 0.5rem;
padding: 0.8rem 1.15rem;
background: #a53a16;
color: #fff;
font: inherit;
font-weight: 700;
cursor: pointer;
}
button:focus-visible {
outline: 3px solid #047b68;
outline-offset: 3px;
}
.translations {
margin-top: 1.25rem;
font-size: 0.875rem;
}
.connection-status {
min-height: 1.5rem;
margin-top: 1rem;
font-size: 0.875rem;
}
@media (prefers-color-scheme: dark) {
:root {
background: #151618;
color: #f5f5f4;
}
p {
color: #b9bbc1;
}
}
</style>
</head>
<body>
<main aria-labelledby="offline-title">
<img src="/images/logo.svg" alt="" width="80" height="80" />
<h1 id="offline-title">You're offline</h1>
<p>
Reconnect to view current requests, messages, maps, and live locations.
We do not save private pages on this device.
</p>
<p
id="connection-status"
class="connection-status"
role="status"
aria-live="polite"
>
Waiting for a connection…
</p>
<form method="get">
<button type="submit">Try again</button>
</form>
<p class="translations">
Немає з’єднання · Нет соединения
</p>
</main>
<script>
(() => {
const status = document.getElementById("connection-status")
let retryTimer
let checking = false
const scheduleRetry = delay => {
window.clearTimeout(retryTimer)
retryTimer = window.setTimeout(checkConnection, delay)
}
const setStatus = message => {
if (status) status.textContent = message
}
const checkConnection = async () => {
if (checking) return
checking = true
setStatus("Checking the connection…")
try {
const response = await fetch("/healthz/ready", {
cache: "no-store",
headers: {accept: "application/json"}
})
if (response.ok) {
setStatus("Connection restored. Reloading…")
window.location.reload()
return
}
} catch (_error) {
// The next scheduled attempt handles temporary network failures.
}
checking = false
setStatus("Still offline. We will keep trying.")
scheduleRetry(3_000)
}
window.addEventListener("online", checkConnection)
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") checkConnection()
})
scheduleRetry(navigator.onLine ? 0 : 3_000)
})()
</script>
</body>
</html>