Show finished queue items as done instead of uploading.

Map qBittorrent-style uploading state to a done badge in the Web UI; keep backend state for *arr compatibility.
This commit is contained in:
2026-08-07 12:06:36 +02:00
parent daefd503f0
commit 4a756c4be3
2 changed files with 30 additions and 9 deletions

View File

@@ -149,6 +149,19 @@ async function fetchQueue() {
return apiFetch('/api/queue'); return apiFetch('/api/queue');
} }
/** Map internal qBittorrent-shaped states to labels the UI should show. */
function displayState(e) {
const s = e.state || '';
// Fake qBt uses "uploading" for finished (seeding) — show "done" in the UI.
if (s === 'uploading' || ((e.progress || 0) >= 1 && s !== 'error' && s !== 'downloading')) {
return { key: 'done', label: 'done' };
}
if (s === 'queuedDL') return { key: 'queued', label: 'queued' };
if (s === 'downloading') return { key: 'downloading', label: 'downloading' };
if (s === 'error') return { key: 'error', label: 'error' };
return { key: s || 'unknown', label: s || 'unknown' };
}
function renderQueue() { function renderQueue() {
fetchQueue().then(entries => { fetchQueue().then(entries => {
if (!entries || entries.length === 0) { if (!entries || entries.length === 0) {
@@ -159,22 +172,24 @@ function renderQueue() {
const pct = Math.round((e.progress || 0) * 100); const pct = Math.round((e.progress || 0) * 100);
const downloaded = formatSize(e.progress * e.size); const downloaded = formatSize(e.progress * e.size);
const total = formatSize(e.size); const total = formatSize(e.size);
const st = displayState(e);
let fillClass = ''; let fillClass = '';
if (e.state === 'uploading') fillClass = 'done'; if (st.key === 'done') fillClass = 'done';
else if (e.state === 'error') fillClass = 'error'; else if (st.key === 'error') fillClass = 'error';
else if (e.state === 'queuedDL') fillClass = 'queued'; else if (st.key === 'queued') fillClass = 'queued';
const speed = st.key === 'done' ? '' : (e.speed || '');
return ` return `
<div class="queue-item"> <div class="queue-item">
<div class="queue-name"> <div class="queue-name">
<span class="badge ${e.state}">${e.state}</span> <span class="badge ${st.key}">${st.label}</span>
<span>${escapeHtml(e.name)}</span> <span>${escapeHtml(e.name)}</span>
<button class="cancel-btn" data-hash="${e.hash}">[x]</button> <button class="cancel-btn" data-hash="${e.hash}" title="${st.key === 'done' ? 'dismiss' : 'cancel'}">[x]</button>
</div> </div>
<div class="queue-stats"> <div class="queue-stats">
<span>${downloaded} / ${total}</span> <span>${downloaded} / ${total}</span>
<span>${pct}%</span> <span>${pct}%</span>
</div> </div>
<div class="queue-speed">${e.speed || ''}</div> <div class="queue-speed">${speed}</div>
<div class="progress-bar"> <div class="progress-bar">
<div class="progress-fill ${fillClass}" style="width:${pct}%"></div> <div class="progress-fill ${fillClass}" style="width:${pct}%"></div>
</div> </div>

View File

@@ -356,14 +356,20 @@ body {
color: var(--fg); color: var(--fg);
} }
.badge.downloading, .badge.downloading {
.badge.uploading {
background: var(--fg); background: var(--fg);
color: var(--bg); color: var(--bg);
border-color: var(--fg); border-color: var(--fg);
} }
.badge.queuedDL { /* finished (backend may still say "uploading") */
.badge.done {
background: var(--fg);
color: var(--bg);
border-color: var(--fg);
}
.badge.queued {
border-style: dashed; border-style: dashed;
color: var(--muted); color: var(--muted);
border-color: var(--muted); border-color: var(--muted);