const boxPanel = document.querySelector(".box-panel[data-box-id]"); const boxStatus = document.querySelector(".box-statusbar span:first-child"); const zipOnly = boxPanel && boxPanel.dataset.zipOnly === "true"; document.querySelectorAll('.box-file[aria-disabled="true"]').forEach((item) => { item.addEventListener("click", (event) => { if (item.getAttribute("aria-disabled") === "true") { event.preventDefault(); } }); }); function updateBoxFile(file) { const item = document.querySelector(`.box-file[data-file-id="${file.id}"]`); if (!item) { return; } const meta = item.querySelector(".box-file-meta"); const icon = item.querySelector(".box-file-icon"); const isComplete = file.status === "complete"; const isFailed = file.status === "failed"; item.classList.toggle("is-complete", isComplete); item.classList.toggle("is-failed", isFailed); item.classList.toggle("is-loading", !isComplete && !isFailed); item.classList.toggle("has-thumbnail", Boolean(file.thumbnail_path)); item.dataset.status = file.status; item.title = file.title; if (isComplete && !zipOnly) { item.href = file.download_path; item.setAttribute("download", ""); item.removeAttribute("aria-disabled"); } else { item.href = "#"; item.removeAttribute("download"); item.setAttribute("aria-disabled", "true"); } if (meta) { meta.textContent = `${file.status_label} ยท ${file.size_label}`; } if (icon) { icon.src = file.thumbnail_path || file.icon_path; } } async function refreshBoxStatus() { if (!boxPanel) { return false; } const boxID = boxPanel.dataset.boxId; const response = await fetch(`/box/${boxID}/status`); if (!response.ok) { return true; } const result = await response.json(); result.files.forEach(updateBoxFile); if (boxStatus) { const completeCount = result.files.filter((file) => file.status === "complete").length; boxStatus.textContent = `${completeCount}/${result.files.length} ready`; } return result.files.some((file) => { const isUploading = file.status === "pending" || file.status === "uploading"; const isWaitingForThumbnail = file.status === "complete" && !file.thumbnail_status && !file.thumbnail_path; return isUploading || isWaitingForThumbnail || file.thumbnail_status === "processing"; }); } if (boxPanel) { const pollMS = Number.parseInt(boxPanel.dataset.pollMs, 10) || 5000; const timer = setInterval(async () => { try { const hasLoadingFiles = await refreshBoxStatus(); if (!hasLoadingFiles) { clearInterval(timer); } } catch (error) { // Keep polling through temporary network/server hiccups; otherwise // an in-progress file can appear stuck forever after one bad poll. } }, pollMS); }