diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html
index 08f0b9faa..e10762d5f 100644
--- a/src/webui/www/private/index.html
+++ b/src/webui/www/private/index.html
@@ -42,6 +42,7 @@
+
diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js
index 09d43f9b5..ccb6e255e 100644
--- a/src/webui/www/private/scripts/client.js
+++ b/src/webui/www/private/scripts/client.js
@@ -1046,20 +1046,8 @@ window.addEventListener("DOMContentLoaded", (event) => {
}
// Statistics dialog
- if (document.getElementById("statisticsContent")) {
- document.getElementById("AlltimeDL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_dl, false);
- document.getElementById("AlltimeUL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_ul, false);
- document.getElementById("TotalWastedSession").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_wasted_session, false);
- document.getElementById("GlobalRatio").textContent = serverState.global_ratio;
- document.getElementById("TotalPeerConnections").textContent = serverState.total_peer_connections;
- document.getElementById("ReadCacheHits").textContent = `${serverState.read_cache_hits}%`;
- document.getElementById("TotalBuffersSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_buffers_size, false);
- document.getElementById("WriteCacheOverload").textContent = `${serverState.write_cache_overload}%`;
- document.getElementById("ReadCacheOverload").textContent = `${serverState.read_cache_overload}%`;
- document.getElementById("QueuedIOJobs").textContent = serverState.queued_io_jobs;
- document.getElementById("AverageTimeInQueue").textContent = `${serverState.average_time_queue} ms`;
- document.getElementById("TotalQueuedSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_queued_size, false);
- }
+ window.qBittorrent.Statistics.save(serverState);
+ window.qBittorrent.Statistics.render();
switch (serverState.connection_status) {
case "connected":
diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js
index 4b6e9a28b..cae3b6fda 100644
--- a/src/webui/www/private/scripts/mocha-init.js
+++ b/src/webui/www/private/scripts/mocha-init.js
@@ -492,7 +492,10 @@ const initializeWindows = () => {
height: loadWindowHeight(id, 415),
onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => {
saveWindowSize(id);
- })
+ }),
+ onContentLoaded: () => {
+ window.qBittorrent.Statistics.render();
+ }
});
};
diff --git a/src/webui/www/private/scripts/statistics.js b/src/webui/www/private/scripts/statistics.js
new file mode 100644
index 000000000..a3b8448d9
--- /dev/null
+++ b/src/webui/www/private/scripts/statistics.js
@@ -0,0 +1,85 @@
+/*
+ * MIT License
+ * Copyright (C) 2025 Thomas Piccirello
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+"use strict";
+
+window.qBittorrent ??= {};
+window.qBittorrent.Statistics ??= (() => {
+ const exports = () => {
+ return {
+ save: save,
+ render: render,
+ };
+ };
+
+ const statistics = {
+ alltimeDL: 0,
+ alltimeUL: 0,
+ totalWastedSession: 0,
+ globalRatio: 0,
+ totalPeerConnections: 0,
+ readCacheHits: 0,
+ totalBuffersSize: 0,
+ writeCacheOverload: 0,
+ readCacheOverload: 0,
+ queuedIOJobs: 0,
+ averageTimeInQueue: 0,
+ totalQueuedSize: 0,
+ };
+
+ const save = (serverState) => {
+ statistics.alltimeDL = serverState.alltime_dl;
+ statistics.alltimeUL = serverState.alltime_ul;
+ statistics.totalWastedSession = serverState.total_wasted_session;
+ statistics.globalRatio = serverState.global_ratio;
+ statistics.totalPeerConnections = serverState.total_peer_connections;
+ statistics.readCacheHits = serverState.read_cache_hits;
+ statistics.totalBuffersSize = serverState.total_buffers_size;
+ statistics.writeCacheOverload = serverState.write_cache_overload;
+ statistics.readCacheOverload = serverState.read_cache_overload;
+ statistics.queuedIOJobs = serverState.queued_io_jobs;
+ statistics.averageTimeInQueue = serverState.average_time_queue;
+ statistics.totalQueuedSize = serverState.total_queued_size;
+ };
+
+ const render = () => {
+ if (!document.getElementById("statisticsContent"))
+ return;
+
+ document.getElementById("AlltimeDL").textContent = window.qBittorrent.Misc.friendlyUnit(statistics.alltimeDL, false);
+ document.getElementById("AlltimeUL").textContent = window.qBittorrent.Misc.friendlyUnit(statistics.alltimeUL, false);
+ document.getElementById("TotalWastedSession").textContent = window.qBittorrent.Misc.friendlyUnit(statistics.totalWastedSession, false);
+ document.getElementById("GlobalRatio").textContent = statistics.globalRatio;
+ document.getElementById("TotalPeerConnections").textContent = statistics.totalPeerConnections;
+ document.getElementById("ReadCacheHits").textContent = `${statistics.readCacheHits}%`;
+ document.getElementById("TotalBuffersSize").textContent = window.qBittorrent.Misc.friendlyUnit(statistics.totalBuffersSize, false);
+ document.getElementById("WriteCacheOverload").textContent = `${statistics.writeCacheOverload}%`;
+ document.getElementById("ReadCacheOverload").textContent = `${statistics.readCacheOverload}%`;
+ document.getElementById("QueuedIOJobs").textContent = statistics.queuedIOJobs;
+ document.getElementById("AverageTimeInQueue").textContent = `${statistics.averageTimeInQueue} ms`;
+ document.getElementById("TotalQueuedSize").textContent = window.qBittorrent.Misc.friendlyUnit(statistics.totalQueuedSize, false);
+ };
+
+ return exports();
+})();
+Object.freeze(window.qBittorrent.Statistics);
diff --git a/src/webui/www/webui.qrc b/src/webui/www/webui.qrc
index 864df1e6a..fa6ed311f 100644
--- a/src/webui/www/webui.qrc
+++ b/src/webui/www/webui.qrc
@@ -419,6 +419,7 @@
private/scripts/prop-webseeds.js
private/scripts/rename-files.js
private/scripts/search.js
+ private/scripts/statistics.js
private/setlocation.html
private/shareratio.html
private/speedlimit.html