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