feat(downloads): live speeds and active/completed split on the download panel (DL-2)
- GET /download-tasks/board?state=active|completed: per-torrent dl/up speed, ETA, seeds/leechs, downloader total speed (transfer/info), counts for both groups, latest organize result (status, reason code, open decision) - live qB data cached per instance for 2 s with in-flight coalescing - panel: total speed line, 进行中 / 已完成 segments remembered locally, 4 s polling while the page is visible, mobile layout, "—" for zero speed Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
8086250ec2
commit
3b340745bf
17 files changed
+1113
-93
No files matched your search
@@ -90,6 +90,12 @@ export interface QbTorrent {
|
||||
eta: number | null;
|
||||
ratio: number | null;
|
||||
seedingTimeSec: number | null;
|
||||
/** 已连接的做种 / 下载用户数(num_seeds / num_leechs) */
|
||||
numSeeds: number;
|
||||
numLeechs: number;
|
||||
/** Tracker 报告的做种 / 下载总数(num_complete / num_incomplete;未知为 null) */
|
||||
numComplete: number | null;
|
||||
numIncomplete: number | null;
|
||||
}
|
||||
|
||||
export interface QbFile {
|
||||
@@ -226,6 +232,11 @@ const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
||||
function num(v: unknown): number | null {
|
||||
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
||||
}
|
||||
/** qB 用 -1 表示未知(num_complete 等) */
|
||||
function nonNeg(v: unknown): number | null {
|
||||
const n = num(v);
|
||||
return n !== null && n >= 0 ? n : null;
|
||||
}
|
||||
function str(v: unknown): string | null {
|
||||
return typeof v === "string" && v !== "" ? v : null;
|
||||
}
|
||||
@@ -282,6 +293,10 @@ export function normalizeTorrent(instanceId: string, r: Record<string, unknown>)
|
||||
eta: num(r.eta),
|
||||
ratio: num(r.ratio),
|
||||
seedingTimeSec: num(r.seeding_time),
|
||||
numSeeds: num(r.num_seeds) ?? 0,
|
||||
numLeechs: num(r.num_leechs) ?? 0,
|
||||
numComplete: nonNeg(r.num_complete),
|
||||
numIncomplete: nonNeg(r.num_incomplete),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user