Fix result modal cache mismatch
build-push / docker (push) Successful in 4m22s

This commit is contained in:
AI Assistant
2026-03-16 12:05:47 +09:00
parent 45ff5b860c
commit 975bd99610
3 changed files with 68 additions and 29 deletions
+10
View File
@@ -255,6 +255,16 @@
- backend debug broadcasts - backend debug broadcasts
## Recent Change Log ## Recent Change Log
- Date: `2026-03-16`
- What changed:
- Bumped frontend asset version and added result-modal initialization guards to avoid click failures when browser cache serves mismatched HTML/JS.
- Why it changed:
- The result modal stopped opening after the modal markup refactor, which is consistent with stale cached frontend assets or partially initialized modal DOM.
- How it was verified:
- static code inspection of modal DOM/JS bindings
- What is still risky or incomplete:
- Browser cache behavior itself was not fully reproduced here, so a hard refresh may still be needed in an already-open client session.
- Date: `2026-03-16` - Date: `2026-03-16`
- What changed: - What changed:
- Envato preview extraction now also inspects `INITIAL_HYDRATION_DATA` when direct page meta / JSON-LD preview URLs are missing. - Envato preview extraction now also inspects `INITIAL_HYDRATION_DATA` when direct page meta / JSON-LD preview URLs are missing.
+57 -28
View File
@@ -49,6 +49,20 @@ const resultModalMediaFrame = document.getElementById("resultModalMediaFrame");
const resultModalVideo = document.getElementById("resultModalVideo"); const resultModalVideo = document.getElementById("resultModalVideo");
const resultModalThumbnail = document.getElementById("resultModalThumbnail"); const resultModalThumbnail = document.getElementById("resultModalThumbnail");
const resultModalEmbedNotice = document.getElementById("resultModalEmbedNotice"); const resultModalEmbedNotice = document.getElementById("resultModalEmbedNotice");
const resultModalReady = Boolean(
resultModal &&
resultModalTitle &&
resultModalSource &&
resultModalSnippet &&
resultModalReason &&
resultModalOpenExternal &&
resultModalDownload &&
closeResultModal &&
resultModalMediaFrame &&
resultModalVideo &&
resultModalThumbnail &&
resultModalEmbedNotice,
);
let pendingDownload = null; let pendingDownload = null;
let cropStart = 0; let cropStart = 0;
@@ -349,6 +363,9 @@ function hideModal(element) {
} }
function resetResultModalMedia() { function resetResultModalMedia() {
if (!resultModalReady) {
return;
}
resultModalVideo.pause(); resultModalVideo.pause();
detachVideoSource(resultModalVideo); detachVideoSource(resultModalVideo);
resultModalMediaFrame.style.aspectRatio = ""; resultModalMediaFrame.style.aspectRatio = "";
@@ -420,6 +437,10 @@ async function prepareDirectDownload(targetUrl) {
} }
function openResultModal(item) { function openResultModal(item) {
if (!resultModalReady) {
logEvent("result:modal:error", { message: "result modal is not fully initialized" });
return;
}
activeResultItem = item; activeResultItem = item;
resultModalTitle.textContent = item.title || "Untitled"; resultModalTitle.textContent = item.title || "Untitled";
resultModalSource.textContent = item.source || ""; resultModalSource.textContent = item.source || "";
@@ -444,6 +465,9 @@ function openResultModal(item) {
} }
function closeResultViewer() { function closeResultViewer() {
if (!resultModalReady) {
return;
}
if (!resultModal.classList.contains("hidden")) { if (!resultModal.classList.contains("hidden")) {
logEvent("result:modal:close", { title: activeResultItem?.title || "" }); logEvent("result:modal:close", { title: activeResultItem?.title || "" });
} }
@@ -586,24 +610,27 @@ confirmDownload.addEventListener("click", async () => {
}); });
closePreviewModal.addEventListener("click", closeModal); closePreviewModal.addEventListener("click", closeModal);
closeResultModal.addEventListener("click", closeResultViewer); if (resultModalReady) {
resultModal.addEventListener("click", (event) => { closeResultModal.addEventListener("click", closeResultViewer);
if (event.target === resultModal) { resultModal.addEventListener("click", (event) => {
closeResultViewer(); if (event.target === resultModal) {
} closeResultViewer();
}); }
resultModalDownload.addEventListener("click", async () => { });
if (!activeResultItem?.link) { resultModalDownload.addEventListener("click", async () => {
return; if (!activeResultItem?.link) {
} return;
try { }
closeResultViewer(); const currentItem = activeResultItem;
await prepareDirectDownload(activeResultItem.link); try {
} catch (error) { closeResultViewer();
downloadResult.textContent = error.message; await prepareDirectDownload(currentItem.link);
logEvent("download:preview:error", { message: error.message, data: error.data || null, source: activeResultItem?.source || "" }); } catch (error) {
} downloadResult.textContent = error.message;
}); logEvent("download:preview:error", { message: error.message, data: error.data || null, source: currentItem?.source || "" });
}
});
}
previewModal.addEventListener("click", (event) => { previewModal.addEventListener("click", (event) => {
if (event.target === previewModal) { if (event.target === previewModal) {
closeModal(); closeModal();
@@ -663,16 +690,18 @@ previewThumbnail.addEventListener("load", () => {
previewMediaFrame.style.aspectRatio = `${previewThumbnail.naturalWidth} / ${previewThumbnail.naturalHeight}`; previewMediaFrame.style.aspectRatio = `${previewThumbnail.naturalWidth} / ${previewThumbnail.naturalHeight}`;
} }
}); });
resultModalVideo.addEventListener("loadedmetadata", () => { if (resultModalReady) {
if (resultModalVideo.videoWidth > 0 && resultModalVideo.videoHeight > 0) { resultModalVideo.addEventListener("loadedmetadata", () => {
resultModalMediaFrame.style.aspectRatio = `${resultModalVideo.videoWidth} / ${resultModalVideo.videoHeight}`; if (resultModalVideo.videoWidth > 0 && resultModalVideo.videoHeight > 0) {
} resultModalMediaFrame.style.aspectRatio = `${resultModalVideo.videoWidth} / ${resultModalVideo.videoHeight}`;
}); }
resultModalThumbnail.addEventListener("load", () => { });
if (!resultModalVideo.src && resultModalThumbnail.naturalWidth > 0 && resultModalThumbnail.naturalHeight > 0) { resultModalThumbnail.addEventListener("load", () => {
resultModalMediaFrame.style.aspectRatio = `${resultModalThumbnail.naturalWidth} / ${resultModalThumbnail.naturalHeight}`; if (!resultModalVideo.src && resultModalThumbnail.naturalWidth > 0 && resultModalThumbnail.naturalHeight > 0) {
} resultModalMediaFrame.style.aspectRatio = `${resultModalThumbnail.naturalWidth} / ${resultModalThumbnail.naturalHeight}`;
}); }
});
}
for (const button of platformToggles) { for (const button of platformToggles) {
button.addEventListener("click", () => { button.addEventListener("click", () => {
const platform = button.dataset.platformToggle; const platform = button.dataset.platformToggle;
+1 -1
View File
@@ -206,6 +206,6 @@
</button> </button>
</template> </template>
<script src="/app.js?v=20260316a" defer></script> <script src="/app.js?v=20260316b" defer></script>
</body> </body>
</html> </html>