diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp
index 5b547862b..469f58459 100644
--- a/src/webui/api/synccontroller.cpp
+++ b/src/webui/api/synccontroller.cpp
@@ -500,6 +500,9 @@ void SyncController::updateFreeDiskSpace(const qint64 freeDiskSpace)
// - "seen_complete": Indicates the time when the torrent was last seen complete/whole
// - "last_activity": Last time when a chunk was downloaded/uploaded
// - "total_size": Size including unwanted data
+// - "has_tracker_warning": the torrent has working tracker that has a message
+// - "has_tracker_error": the torrent has a tracker error
+// - "has_other_announce_error": the torrent has other problems announcing to a tracker
// Server state map may contain the following keys:
// - "connection_status": connection status
// - "dht_nodes": DHT nodes count
diff --git a/src/webui/www/private/images/tracker-error.svg b/src/webui/www/private/images/tracker-error.svg
new file mode 100644
index 000000000..8a531c3f2
--- /dev/null
+++ b/src/webui/www/private/images/tracker-error.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/webui/www/private/images/tracker-warning.svg b/src/webui/www/private/images/tracker-warning.svg
new file mode 100644
index 000000000..4e473d9e3
--- /dev/null
+++ b/src/webui/www/private/images/tracker-warning.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/webui/www/private/images/trackerless.svg b/src/webui/www/private/images/trackerless.svg
new file mode 100644
index 000000000..ab9d8e751
--- /dev/null
+++ b/src/webui/www/private/images/trackerless.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js
index 7f95a74f5..d0b13f1c1 100644
--- a/src/webui/www/private/scripts/client.js
+++ b/src/webui/www/private/scripts/client.js
@@ -161,7 +161,10 @@ let setTagFilter = () => {};
/* Trackers filter */
const TRACKERS_ALL = "b4af0e4c-e76d-4bac-a392-46cbc18d9655";
+const TRACKERS_ANNOUNCE_ERROR = "d0b4cad2-9f6f-4e7f-8d4b-f80a103dd436";
+const TRACKERS_ERROR = "b551cfc3-64e9-4393-bc88-5d6ea2fab5cc";
const TRACKERS_TRACKERLESS = "e24bd469-ea22-404c-8e2e-a17c82f37ea0";
+const TRACKERS_WARNING = "82a702c5-210c-412b-829f-97632d7557e9";
// Map>
const trackerMap = new Map();
@@ -685,17 +688,41 @@ window.addEventListener("DOMContentLoaded", (event) => {
const span = trackerFilterItem.firstElementChild;
span.lastChild.textContent = `${text} (${count})`;
+ switch (host) {
+ case TRACKERS_ANNOUNCE_ERROR:
+ case TRACKERS_ERROR:
+ span.lastElementChild.src = "images/tracker-error.svg";
+ break;
+ case TRACKERS_TRACKERLESS:
+ span.lastElementChild.src = "images/trackerless.svg";
+ break;
+ case TRACKERS_WARNING:
+ span.lastElementChild.src = "images/tracker-warning.svg";
+ break;
+ }
+
return trackerFilterItem;
};
- let trackerlessTorrentsCount = 0;
- for (const { full_data: { trackers_count: trackersCount } } of torrentsTable.getRowValues()) {
- if (trackersCount === 0)
- trackerlessTorrentsCount += 1;
+ let trackerlessCount = 0;
+ let trackerErrorCount = 0;
+ let announceErrorCount = 0;
+ let trackerWarningCount = 0;
+ for (const { full_data } of torrentsTable.getRowValues()) {
+ if (full_data.trackers_count === 0)
+ trackerlessCount += 1;
+
+ // counting bools by adding them
+ trackerErrorCount += full_data.has_tracker_error;
+ announceErrorCount += full_data.has_other_announce_error;
+ trackerWarningCount += full_data.has_tracker_warning;
}
trackerFilterList.appendChild(createLink(TRACKERS_ALL, "QBT_TR(All)QBT_TR[CONTEXT=TrackerFiltersList]", torrentsTable.getRowSize()));
- trackerFilterList.appendChild(createLink(TRACKERS_TRACKERLESS, "QBT_TR(Trackerless)QBT_TR[CONTEXT=TrackerFiltersList]", trackerlessTorrentsCount));
+ trackerFilterList.appendChild(createLink(TRACKERS_TRACKERLESS, "QBT_TR(Trackerless)QBT_TR[CONTEXT=TrackerFiltersList]", trackerlessCount));
+ trackerFilterList.appendChild(createLink(TRACKERS_ERROR, "QBT_TR(Tracker error)QBT_TR[CONTEXT=TrackerFiltersList]", trackerErrorCount));
+ trackerFilterList.appendChild(createLink(TRACKERS_ANNOUNCE_ERROR, "QBT_TR(Other error)QBT_TR[CONTEXT=TrackerFiltersList]", announceErrorCount));
+ trackerFilterList.appendChild(createLink(TRACKERS_WARNING, "QBT_TR(Warning)QBT_TR[CONTEXT=TrackerFiltersList]", trackerWarningCount));
// Sort trackers by hostname
const sortedList = [];
diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js
index a16424b07..6ab9a0c12 100644
--- a/src/webui/www/private/scripts/contextmenu.js
+++ b/src/webui/www/private/scripts/contextmenu.js
@@ -620,11 +620,18 @@ window.qBittorrent.ContextMenu ??= (() => {
class TrackersFilterContextMenu extends FilterListContextMenu {
updateMenuItems() {
- const id = this.options.element.id;
- if ((id !== TRACKERS_ALL) && (id !== TRACKERS_TRACKERLESS))
- this.showItem("deleteTracker");
- else
- this.hideItem("deleteTracker");
+ switch (this.options.element.id) {
+ case TRACKERS_ALL:
+ case TRACKERS_ANNOUNCE_ERROR:
+ case TRACKERS_ERROR:
+ case TRACKERS_TRACKERLESS:
+ case TRACKERS_WARNING:
+ this.hideItem("deleteTracker");
+ break;
+ default:
+ this.showItem("deleteTracker");
+ break;
+ }
this.updateTorrentActions();
}
diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js
index a2db88589..f1c5c2444 100644
--- a/src/webui/www/private/scripts/dynamicTable.js
+++ b/src/webui/www/private/scripts/dynamicTable.js
@@ -1558,7 +1558,7 @@ window.qBittorrent.DynamicTable ??= (() => {
};
}
- applyFilter(row, filterName, category, tag, tracker, filterTerms) {
+ applyFilter(row, filterName, category, tag, trackerHost, filterTerms) {
const state = row["full_data"].state;
let inactive = false;
@@ -1666,17 +1666,32 @@ window.qBittorrent.DynamicTable ??= (() => {
}
}
- switch (tracker) {
+ switch (trackerHost) {
case TRACKERS_ALL:
break; // do nothing
+ case TRACKERS_ANNOUNCE_ERROR:
+ if (!row["full_data"]["has_other_announce_error"])
+ return false;
+ break;
+
+ case TRACKERS_ERROR:
+ if (!row["full_data"]["has_tracker_error"])
+ return false;
+ break;
+
case TRACKERS_TRACKERLESS:
if (row["full_data"].trackers_count > 0)
return false;
break;
+ case TRACKERS_WARNING:
+ if (!row["full_data"]["has_tracker_warning"])
+ return false;
+ break;
+
default: {
- const trackerTorrentMap = trackerMap.get(tracker);
+ const trackerTorrentMap = trackerMap.get(trackerHost);
if (trackerTorrentMap !== undefined) {
let found = false;
for (const torrents of trackerTorrentMap.values()) {
diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js
index e7473071f..4b6e9a28b 100644
--- a/src/webui/www/private/scripts/mocha-init.js
+++ b/src/webui/www/private/scripts/mocha-init.js
@@ -1093,7 +1093,11 @@ const initializeWindows = () => {
};
deleteTrackerFN = (trackerHost) => {
- if ((trackerHost === TRACKERS_ALL) || (trackerHost === TRACKERS_TRACKERLESS))
+ if ((trackerHost === TRACKERS_ALL)
+ || (trackerHost === TRACKERS_ANNOUNCE_ERROR)
+ || (trackerHost === TRACKERS_ERROR)
+ || (trackerHost === TRACKERS_TRACKERLESS)
+ || (trackerHost === TRACKERS_WARNING))
return;
const contentURL = new URL("confirmtrackerdeletion.html", window.location);
diff --git a/src/webui/www/private/scripts/prop-trackers.js b/src/webui/www/private/scripts/prop-trackers.js
index 05a5de700..b95bef5e7 100644
--- a/src/webui/www/private/scripts/prop-trackers.js
+++ b/src/webui/www/private/scripts/prop-trackers.js
@@ -74,10 +74,11 @@ window.qBittorrent.PropTrackers ??= (() => {
return;
const selectedTrackers = torrentTrackersTable.selectedRowsIds();
- torrentTrackersTable.clear();
const trackers = await response.json();
if (trackers) {
+ torrentTrackersTable.clear();
+
trackers.each((tracker) => {
let status;
switch (tracker.status) {
@@ -122,7 +123,7 @@ window.qBittorrent.PropTrackers ??= (() => {
})
.finally(() => {
clearTimeout(loadTrackersDataTimer);
- loadTrackersDataTimer = loadTrackersData.delay(10000);
+ loadTrackersDataTimer = loadTrackersData.delay(window.qBittorrent.Client.getSyncMainDataInterval());
});
};
diff --git a/src/webui/www/webui.qrc b/src/webui/www/webui.qrc
index 123790da2..d2ddbe9e6 100644
--- a/src/webui/www/webui.qrc
+++ b/src/webui/www/webui.qrc
@@ -372,6 +372,9 @@
private/images/torrent-start-forced.svg
private/images/torrent-start.svg
private/images/torrent-stop.svg
+ private/images/tracker-error.svg
+ private/images/tracker-warning.svg
+ private/images/trackerless.svg
private/images/trackers.svg
private/images/upload.svg
private/images/view-categories.svg