WebUI: Support reannouncing individual trackers

PR #22954.
This commit is contained in:
Thomas Piccirello
2025-07-19 09:29:14 +02:00
committed by GitHub
parent 7c443b0c3b
commit 163f683186
5 changed files with 72 additions and 3 deletions

View File

@@ -248,6 +248,8 @@
<li class="separator"><a href="#EditTracker"><img src="images/edit-rename.svg" alt="QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
<li><a href="#RemoveTracker"><img src="images/list-remove.svg" alt="QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Remove tracker)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
<li><a href="#CopyTrackerUrl" id="CopyTrackerUrl"><img src="images/edit-copy.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
<li><a href="#ReannounceTrackers" id="ReannounceTrackers"><img src="images/view-refresh.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Force reannounce to selected tracker(s))QBT_TR[CONTEXT=TrackerListWidget]</a></li>
<li class="separator"><a href="#ReannounceAllTrackers" id="ReannounceAllTrackers"><img src="images/view-refresh.svg" alt="QBT_TR(Copy tracker URL)QBT_TR[CONTEXT=TrackerListWidget]"> QBT_TR(Force reannounce to all trackers)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
</ul>
<ul id="torrentPeersMenu" class="contextMenu">
<li><a href="#addPeer"><img src="images/peers-add.svg" alt="QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]"> QBT_TR(Add peers...)QBT_TR[CONTEXT=PeerListWidget]</a></li>

View File

@@ -1818,6 +1818,11 @@ window.qBittorrent.DynamicTable ??= (() => {
onSelectedRowChanged() {
updatePropertiesPanel();
}
isStopped(hash) {
const row = this.getRow(hash);
return (row === undefined) ? true : row.full_data.state.includes("stopped");
}
}
class TorrentPeersTable extends DynamicTable {

View File

@@ -148,6 +148,12 @@ window.qBittorrent.PropTrackers ??= (() => {
},
RemoveTracker: (element, ref) => {
removeTrackerFN(element);
},
ReannounceTrackers: (element, ref) => {
reannounceTrackersFN(element, torrentTrackersTable.selectedRowsIds());
},
ReannounceAllTrackers: (element, ref) => {
reannounceTrackersFN(element, []);
}
},
offsets: {
@@ -164,6 +170,8 @@ window.qBittorrent.PropTrackers ??= (() => {
this.hideItem("EditTracker");
this.hideItem("RemoveTracker");
this.hideItem("CopyTrackerUrl");
this.hideItem("ReannounceTrackers");
this.hideItem("ReannounceAllTrackers");
}
else {
if (selectedTrackers.length === 1)
@@ -173,6 +181,16 @@ window.qBittorrent.PropTrackers ??= (() => {
this.showItem("RemoveTracker");
this.showItem("CopyTrackerUrl");
const torrentHash = torrentsTable.getCurrentTorrentID();
if (torrentsTable.isStopped(torrentHash)) {
this.hideItem("ReannounceTrackers");
this.hideItem("ReannounceAllTrackers");
}
else {
this.showItem("ReannounceTrackers");
this.showItem("ReannounceAllTrackers");
}
}
}
});
@@ -253,6 +271,28 @@ window.qBittorrent.PropTrackers ??= (() => {
});
};
const reannounceTrackersFN = (element, trackers) => {
if (current_hash.length === 0)
return;
const body = new URLSearchParams({
hashes: current_hash
});
if (trackers.length > 0)
body.set("urls", trackers.map(encodeURIComponent).join("|"));
fetch("api/v2/torrents/reannounce", {
method: "POST",
body: body
})
.then((response) => {
if (!response.ok)
return;
updateData();
});
};
const clear = () => {
torrentTrackersTable.clear();
};