Files
firehose/app/lib/firehose_web/components/layouts/root.html.heex
T

69 lines
3.2 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content={get_csrf_token()} />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<.live_title default="Firehose" suffix=" — Willem van den Ende">
{assigns[:page_title]}
</.live_title>
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/app.js"}>
</script>
<script>
(() => {
// Theme selection is always explicit: the document always carries a
// data-theme attribute, resolved here before first paint. An explicit
// choice therefore always wins in CSS, whatever the OS preference is;
// no stylesheet rule follows the OS on its own.
//
// data-theme-choice records what the visitor actually chose (unset,
// system, light, dark) and is what the toggle's knob follows: in
// "system" mode the palette may resolve to light or dark, but the
// system icon must stay selected.
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
const stored = () => localStorage.getItem("phx:theme");
const resolve = (theme) =>
theme === "system" ? (prefersDark.matches ? "dark" : "light") : theme;
const apply = (theme) => {
document.documentElement.setAttribute("data-theme", resolve(theme));
document.documentElement.setAttribute("data-theme-choice", theme);
};
const setTheme = (theme) => {
localStorage.setItem("phx:theme", theme);
apply(theme);
};
// Light is the default: no stored preference means light, not "follow
// the OS". "System" is an explicit choice and is stored as such.
if (!document.documentElement.hasAttribute("data-theme")) {
apply(stored() || "light");
}
// Follow the OS only while the visitor's recorded choice is "system".
prefersDark.addEventListener("change", () => {
if (stored() === "system") apply("system");
});
window.addEventListener("storage", (e) => e.key === "phx:theme" && setTheme(e.newValue || "light"));
window.addEventListener("phx:set-theme", (e) => setTheme(e.target.dataset.phxTheme));
})();
</script>
<%= for meta <- get_content_for(assigns, :meta_tags) do %>
<meta property="og:title" content={meta.og_title} />
<meta property="og:description" content={meta.og_description} />
<meta property="og:type" content={meta.og_type} />
<meta property="og:url" content={meta.og_url} />
<%= if meta.og_image do %>
<meta property="og:image" content={meta.og_image} />
<% end %>
<meta name="twitter:card" content={meta.twitter_card} />
<% end %>
<%= for feed <- get_content_for(assigns, :feed_links) do %>
<link rel="alternate" type="application/rss+xml" title={feed.title} href={feed.rss_url} />
<% end %>
</head>
<body>
{@inner_content}
</body>
</html>