Files
website/app/templates/layout.templ
jimmy a9095727bf Fix thumbnail loading and startup gallery refresh.
Refresh gallery metadata after thumbnail generation so new thumb URLs are available immediately, and lazy-load gallery thumbnails with IntersectionObserver to avoid fetching all images on initial page load.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 00:16:38 +12:00

81 lines
2.4 KiB
Plaintext

package templates
templ Layout(title string, preloadImage string, content templ.Component) {
<!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="#14100c"/>
<title>{ title }</title>
<meta name="description" content="Technical Kiwi Limited — electronic engineering and interactive art from New Zealand."/>
<link rel="stylesheet" href="/static/style.css"/>
if preloadImage != "" {
<link rel="preload" as="image" href={ preloadImage } fetchpriority="high"/>
}
</head>
<body hx-boost="true">
<header class="site-header">
<a href="/" class="logo">
<span class="logo-mark" aria-hidden="true">T</span>
<span class="logo-text">Technical Kiwi</span>
</a>
<nav class="site-nav">
<a href="#services">Services</a>
<a href="https://git.technical.kiwi/" rel="noopener noreferrer" target="_blank">Code</a>
<a href="#contact">Contact</a>
</nav>
</header>
<main>
@content
</main>
<footer class="site-footer">
<p>&copy; { currentYear() } Technical Kiwi Limited. New Zealand.</p>
</footer>
<div id="modal-root"></div>
<script src="/static/htmx.min.js" defer></script>
<script>
(function () {
function hydrateLazyThumbs(root) {
var lazyImages = root.querySelectorAll("img[data-src]");
if (!lazyImages.length) return;
if (!("IntersectionObserver" in window)) {
lazyImages.forEach(function (img) {
img.src = img.dataset.src;
img.removeAttribute("data-src");
});
return;
}
var observer = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
var img = entry.target;
img.src = img.dataset.src;
img.removeAttribute("data-src");
observer.unobserve(img);
});
},
{ rootMargin: "300px 0px" },
);
lazyImages.forEach(function (img) {
observer.observe(img);
});
}
document.addEventListener("DOMContentLoaded", function () {
hydrateLazyThumbs(document);
});
document.body.addEventListener("htmx:afterSwap", function (event) {
hydrateLazyThumbs(event.target);
});
})();
</script>
</body>
</html>
}