Add basic loading tracking to new item page preview

The UI for it is just basic for my own testing rn: it sets the preview
background to gray while loading, then back to white when done!

This uses the new CSS `:has()` selector: we have JS manage the loading
state on each layer, then the container just restyles itself based on
whether any currently-loading layers are present.
This commit is contained in:
Emi Matchu 2024-07-01 17:59:07 -07:00
parent ac002f3151
commit 0a9193aed7
2 changed files with 35 additions and 2 deletions

View file

@ -58,6 +58,9 @@ body.items-show
width: 100%
height: 100%
&:has(.outfit-layer[data-status="loading"])
background: gray
.species-color-picker
.error-icon
cursor: help

View file

@ -1,2 +1,32 @@
// eslint-disable-next-line no-console
console.log("OwO!");
// When we load in a new preview, set the status on the images. We use this in
// our CSS to show a loading state when needed.
function setImageStatuses() {
for (const layer of document.querySelectorAll(".outfit-layer")) {
const isLoaded = layer.querySelector("img").complete;
layer.setAttribute("data-status", isLoaded ? "loaded" : "loading");
}
}
document.addEventListener("turbo:frame-render", () => setImageStatuses());
document.addEventListener("turbo:load", () => setImageStatuses());
// When a preview image loads or fails, update its status. (Note that `load`
// does not fire for images that were loaded from cache, which is why we need
// both this and `setImageStatuses` when rendering new images!)
document.addEventListener(
"load",
({ target }) => {
if (target.matches(".outfit-layer img")) {
target.closest(".outfit-layer").setAttribute("data-status", "loaded");
}
},
{ capture: true },
);
document.addEventListener(
"error",
({ target }) => {
if (target.matches(".outfit-layer img")) {
target.closest(".outfit-layer").setAttribute("data-status", "error");
}
},
{ capture: true },
);