diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 3fb778c22..b49f35a2f 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -2912,6 +2912,10 @@ window.qBittorrent.DynamicTable ??= (() => { return this.getNode(row.rowId); } + calculateRemaining() { + this.fileTree.getRoot().calculateRemaining(); + } + initColumns() { this.newColumn("checked", "", "", 50, true); this.newColumn("name", "", "QBT_TR(Name)QBT_TR[CONTEXT=TrackerListWidget]", 300, true); @@ -3188,14 +3192,6 @@ window.qBittorrent.DynamicTable ??= (() => { return rows; } - setIgnored(rowId, ignore) { - const node = this.getNode(rowId.toString()); - if (ignore) - node.remaining = 0; - else - node.remaining = (node.size * (1.0 - (node.progress / 100))); - } - setupCommonEvents() { super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("keydown", (e) => { diff --git a/src/webui/www/private/scripts/file-tree.js b/src/webui/www/private/scripts/file-tree.js index 13bbf0488..4c4c32ed0 100644 --- a/src/webui/www/private/scripts/file-tree.js +++ b/src/webui/www/private/scripts/file-tree.js @@ -126,6 +126,14 @@ window.qBittorrent.FileTree ??= (() => { isFolder = false; children = []; + isIgnored() { + return this.priority === FilePriority.Ignored; + } + + calculateRemaining() { + this.remaining = this.isIgnored() ? 0 : (this.size * (1.0 - (this.progress / 100))); + } + serialize() { return { name: this.name, @@ -150,6 +158,7 @@ window.qBittorrent.FileTree ??= (() => { fileId = -1; addChild(node) { + node.calculateRemaining(); this.children.push(node); } @@ -196,8 +205,7 @@ window.qBittorrent.FileTree ??= (() => { root.checked = TriState.Partial; } - const isIgnored = (child.priority === FilePriority.Ignored); - if (!isIgnored) { + if (!child.isIgnored()) { root.remaining += child.remaining; root.progress += (child.progress * child.size); root.availability += (child.availability * child.size); @@ -212,6 +220,17 @@ window.qBittorrent.FileTree ??= (() => { stack.pop(); } } + + /** + * Recursively recalculate the amount of data remaining to be downloaded. + * This is useful for updating a folder's "remaining" size as files are unchecked/ignored. + */ + calculateRemaining() { + this.remaining = this.children.reduce((sum, node) => { + node.calculateRemaining(); + return sum + node.remaining; + }, 0); + } } return exports(); diff --git a/src/webui/www/private/scripts/torrent-content.js b/src/webui/www/private/scripts/torrent-content.js index 932b4ab94..37a216b96 100644 --- a/src/webui/www/private/scripts/torrent-content.js +++ b/src/webui/www/private/scripts/torrent-content.js @@ -293,15 +293,16 @@ window.qBittorrent.TorrentContent ??= (() => { if (onFilePriorityChanged) onFilePriorityChanged(fileIds, priority); - const ignore = (priority === FilePriority.Ignored); - ids.forEach((id) => { - id = id.toString(); - torrentFilesTable.setIgnored(id, ignore); - - const node = torrentFilesTable.getNode(id); + const nodes = ids.map((id) => { + const node = torrentFilesTable.getNode(id.toString()); node.priority = priority; node.checked = triStateFromPriority(priority); + return node; }); + + // must update all nodes above before recalculating + for (const node of nodes) + node.calculateRemaining(); }; const updateData = (files) => { @@ -315,7 +316,6 @@ window.qBittorrent.TorrentContent ??= (() => { size: file.size, progress: window.qBittorrent.Misc.toFixedPointString((file.progress * 100), 1), priority: normalizePriority(file.priority), - remaining: (ignore ? 0 : (file.size * (1 - file.progress))), availability: file.availability }; @@ -369,7 +369,6 @@ window.qBittorrent.TorrentContent ??= (() => { }); const isChecked = row.checked ? TriState.Checked : TriState.Unchecked; - const remaining = (row.priority === FilePriority.Ignored) ? 0 : row.remaining; const childNode = new window.qBittorrent.FileTree.FileNode(); childNode.name = row.name; childNode.path = row.fileName; @@ -377,7 +376,6 @@ window.qBittorrent.TorrentContent ??= (() => { childNode.fileId = row.fileId; childNode.size = row.size; childNode.checked = isChecked; - childNode.remaining = remaining; childNode.progress = row.progress; childNode.priority = row.priority; childNode.availability = row.availability; @@ -427,6 +425,7 @@ window.qBittorrent.TorrentContent ??= (() => { const updateComplete = () => { // we've finished recursing updateGlobalCheckbox(); + torrentFilesTable.calculateRemaining(); torrentFilesTable.updateTable(true); };