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>
This commit is contained in:
@@ -70,6 +70,17 @@ func New(imagesDir, staticDir string, mailCfg *mail.Config) (*Server, error) {
|
||||
} else {
|
||||
log.Print("gallery thumbnails: ready")
|
||||
}
|
||||
// Thumbnail URLs are resolved during gallery.List. Re-list after derivative
|
||||
// generation so newly-created thumbs appear immediately on first load.
|
||||
if refreshed, err := gallery.List(imagesDir); err != nil {
|
||||
log.Printf("gallery refresh after thumbnails: %v", err)
|
||||
} else {
|
||||
srv.Images = refreshed
|
||||
if hero, hasHero := gallery.SelectHero(refreshed); hasHero {
|
||||
srv.Hero = hero
|
||||
srv.HasHero = true
|
||||
}
|
||||
}
|
||||
return srv, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ templ GalleryGrid(images []gallery.Image) {
|
||||
>
|
||||
if img.ThumbURL != "" {
|
||||
<img
|
||||
src={ img.ThumbURL }
|
||||
src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
|
||||
data-src={ img.ThumbURL }
|
||||
class="lazy-thumb"
|
||||
alt={ fmt.Sprintf("%s — %s", gallery.AlbumLabel(img.Album), formatDate(img.Date)) }
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
|
||||
@@ -34,6 +34,47 @@ templ Layout(title string, preloadImage string, content templ.Component) {
|
||||
</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>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user