From 20202b5cd9746a9003226c44bf7f31021a4bb688 Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 8 Jul 2024 16:44:22 -0700 Subject: [PATCH] Potentially improve loading state in new item page preview I thiiiink I've seen the status of a movie `` sometimes be `loading` even when it's clearly already loaded and running. I haven't been able to track down where and how that happens exactly, so this is me acting on a hunch: that maybe the I-would-have-thought-very-unlikely event that the iframe finishes loading before the `` connects with its children maybe happens more often than one might think! In this change, we set up the iframe to receive `requestStatus` messages, which it responds to with the status immediately. And we send one of these when the `` first discovers the iframe. Fingers crossed! --- app/assets/javascripts/outfit-viewer.js | 27 ++++++++++------ app/assets/javascripts/swf_assets/show.js | 38 ++++++++++++++++------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/outfit-viewer.js b/app/assets/javascripts/outfit-viewer.js index 396de92b..19264af3 100644 --- a/app/assets/javascripts/outfit-viewer.js +++ b/app/assets/javascripts/outfit-viewer.js @@ -71,11 +71,11 @@ class OutfitLayer extends HTMLElement { } play() { - this.#forwardIsPlaying(true); + this.#sendMessageToIframe({ type: "play" }); } pause() { - this.#forwardIsPlaying(false); + this.#sendMessageToIframe({ type: "pause" }); } #connectToChildren() { @@ -83,14 +83,23 @@ class OutfitLayer extends HTMLElement { const iframe = this.querySelector("iframe"); if (image) { + // Initialize status based on the image's current `complete` attribute, + // then wait for load/error events to update it further if needed. + this.#setStatus(image.complete ? "loaded" : "loading"); image.addEventListener("load", () => this.#setStatus("loaded")); image.addEventListener("error", () => this.#setStatus("error")); - this.#setStatus(image.complete ? "loaded" : "loading"); } else if (iframe) { this.iframe = iframe; + + // Initialize status to `loading`, and asynchronously request a status + // message from the iframe if it managed to load before this triggers + // (impressive, but I think I've seen it happen!). Then, wait for + // messages or error events from the iframe to update status further if + // needed. + this.#setStatus("loading"); + this.#sendMessageToIframe({ type: "requestStatus" }); window.addEventListener("message", (m) => this.#onMessage(m)); this.iframe.addEventListener("error", () => this.#setStatus("error")); - this.#setStatus("loading"); } else { throw new Error(` must contain an or