106 lines
3.1 KiB
HTML
106 lines
3.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#f7f4ef" />
|
|
<meta name="color-scheme" content="light" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<title>every.channel</title>
|
|
<link rel="manifest" href="manifest.webmanifest" />
|
|
<link rel="icon" href="icons/icon-192.png" />
|
|
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png" />
|
|
|
|
<link data-trunk rel="css" href="style.css" />
|
|
<link data-trunk rel="rust" data-wasm-opt="z" />
|
|
|
|
<link data-trunk rel="copy-file" href="manifest.webmanifest" />
|
|
<link data-trunk rel="copy-file" href="sw.js" />
|
|
<link data-trunk rel="copy-dir" href="icons" />
|
|
</head>
|
|
<body>
|
|
<div
|
|
id="boot-status"
|
|
style="
|
|
position: fixed;
|
|
inset: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 24px;
|
|
background: #f7f4ef;
|
|
color: #2b241d;
|
|
font: 15px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
white-space: pre-wrap;
|
|
z-index: 9999;
|
|
"
|
|
>
|
|
Loading every.channel…
|
|
</div>
|
|
<div id="main"></div>
|
|
|
|
<script>
|
|
(() => {
|
|
const boot = document.getElementById("boot-status");
|
|
const main = document.getElementById("main");
|
|
if (!boot || !main) return;
|
|
|
|
const show = (message) => {
|
|
boot.textContent = message;
|
|
boot.style.display = "flex";
|
|
};
|
|
|
|
const hide = () => {
|
|
boot.remove();
|
|
};
|
|
|
|
const mounted = () => {
|
|
if (main.childElementCount > 0) {
|
|
hide();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
new MutationObserver(() => {
|
|
mounted();
|
|
}).observe(main, { childList: true, subtree: true });
|
|
|
|
window.addEventListener("error", (event) => {
|
|
const message =
|
|
event?.error?.stack ||
|
|
event?.error?.message ||
|
|
event?.message ||
|
|
"Unknown frontend boot error";
|
|
show(`Frontend boot error\n\n${message}`);
|
|
});
|
|
|
|
window.addEventListener("unhandledrejection", (event) => {
|
|
const reason = event?.reason;
|
|
const message =
|
|
reason?.stack ||
|
|
reason?.message ||
|
|
(typeof reason === "string" ? reason : JSON.stringify(reason, null, 2)) ||
|
|
"Unknown unhandled rejection";
|
|
show(`Frontend boot rejection\n\n${message}`);
|
|
});
|
|
|
|
setTimeout(() => {
|
|
if (!mounted()) {
|
|
show("Loading every.channel is taking longer than expected…");
|
|
}
|
|
}, 4000);
|
|
})();
|
|
</script>
|
|
|
|
<script>
|
|
// Installable app shell (PWA). Keep this tiny and resilient.
|
|
if ("serviceWorker" in navigator) {
|
|
window.addEventListener("load", () => {
|
|
navigator.serviceWorker.register("./sw.js").catch(() => {});
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|