Add queue download progress
This commit is contained in:
@@ -269,6 +269,36 @@ QUEUE_HTML = r"""<!doctype html>
|
||||
.status.done { color: #082312; background: var(--good); }
|
||||
.status.failed { color: #2d0910; background: var(--bad); }
|
||||
.status.canceled { color: #2d1c00; background: var(--warn); }
|
||||
.progress-wrap {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
.progress-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
.progress-label {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.progress-track {
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.progress-fill {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(90deg, var(--accent), #75c9ff);
|
||||
transition: width 0.28s ease;
|
||||
}
|
||||
pre {
|
||||
margin: 0;
|
||||
max-height: 220px;
|
||||
@@ -408,6 +438,38 @@ QUEUE_HTML = r"""<!doctype html>
|
||||
return [...(job.log || [])].slice(-28).reverse().join("\n");
|
||||
}
|
||||
|
||||
function progressPercent(job) {
|
||||
const progress = job.progress || {};
|
||||
const value = Number(progress.percent || 0);
|
||||
if (!Number.isFinite(value)) return job.status === "done" ? 100 : 0;
|
||||
return Math.max(0, Math.min(100, Math.round(value)));
|
||||
}
|
||||
|
||||
function progressLabel(job) {
|
||||
const progress = job.progress || {};
|
||||
if (progress.message) return progress.message;
|
||||
if (job.status === "running") return "Download running.";
|
||||
if (job.status === "pending") return "Waiting for worker.";
|
||||
if (job.status === "done") return "Download completed.";
|
||||
if (job.status === "failed") return "Download failed.";
|
||||
if (job.status === "canceled") return "Download canceled.";
|
||||
return "Waiting.";
|
||||
}
|
||||
|
||||
function progressDetail(job) {
|
||||
const progress = job.progress || {};
|
||||
const parts = [];
|
||||
if (progress.episode_index && progress.episode_total) {
|
||||
parts.push(`episode ${progress.episode_index}/${progress.episode_total}`);
|
||||
} else if (progress.episode) {
|
||||
parts.push(`episode ${progress.episode}`);
|
||||
}
|
||||
if (progress.segment && progress.segment_total) {
|
||||
parts.push(`segment ${progress.segment}/${progress.segment_total}`);
|
||||
}
|
||||
return parts.join(" · ");
|
||||
}
|
||||
|
||||
function renderJobActions(job, actions) {
|
||||
actions.innerHTML = "";
|
||||
if (job.job_type === "jellyfin_handoff") {
|
||||
@@ -436,6 +498,11 @@ QUEUE_HTML = r"""<!doctype html>
|
||||
status.className = "status";
|
||||
status.classList.add(job.status);
|
||||
item.querySelector("pre").textContent = buildJobLog(job) || "Waiting...";
|
||||
const percent = progressPercent(job);
|
||||
item.querySelector(".progress-fill").style.width = `${percent}%`;
|
||||
item.querySelector(".progress-percent").textContent = `${percent}%`;
|
||||
item.querySelector(".progress-label").textContent = progressLabel(job);
|
||||
item.querySelector(".progress-detail").textContent = progressDetail(job);
|
||||
item.querySelector(".toolbar .muted").textContent = job.exit_code === null || job.exit_code === undefined ? "" : `exit ${job.exit_code}`;
|
||||
renderJobActions(job, item.querySelector(".row"));
|
||||
state.jobCards[job.id] = item;
|
||||
@@ -456,6 +523,14 @@ QUEUE_HTML = r"""<!doctype html>
|
||||
<span class="status"></span>
|
||||
</div>
|
||||
<div class="job-body">
|
||||
<div class="progress-wrap">
|
||||
<div class="progress-meta">
|
||||
<span class="progress-label"></span>
|
||||
<span class="progress-percent"></span>
|
||||
</div>
|
||||
<div class="progress-track" aria-hidden="true"><div class="progress-fill"></div></div>
|
||||
<div class="progress-meta"><span class="progress-detail"></span></div>
|
||||
</div>
|
||||
<pre></pre>
|
||||
<div class="toolbar">
|
||||
<span class="muted"></span>
|
||||
|
||||
Reference in New Issue
Block a user