WebUI: migrate to fetch API
[qBittorrent.git] / src / webui / www / private / scripts / prop-trackers.js
blobfd5b7ec4b1f19ab50c3307226f94a4b795940894
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2009 Christophe Dumez <chris@qbittorrent.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
29 "use strict";
31 window.qBittorrent ??= {};
32 window.qBittorrent.PropTrackers ??= (() => {
33 const exports = () => {
34 return {
35 updateData: updateData,
36 clear: clear
40 let current_hash = "";
42 const torrentTrackersTable = new window.qBittorrent.DynamicTable.TorrentTrackersTable();
43 let loadTrackersDataTimer = -1;
45 const loadTrackersData = () => {
46 if ($("propTrackers").classList.contains("invisible")
47 || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) {
48 // Tab changed, don't do anything
49 return;
51 const new_hash = torrentsTable.getCurrentTorrentID();
52 if (new_hash === "") {
53 torrentTrackersTable.clear();
54 clearTimeout(loadTrackersDataTimer);
55 return;
57 if (new_hash !== current_hash) {
58 torrentTrackersTable.clear();
59 current_hash = new_hash;
62 const url = new URL("api/v2/torrents/trackers", window.location);
63 url.search = new URLSearchParams({
64 hash: current_hash
65 });
66 fetch(url, {
67 method: "GET",
68 cache: "no-store"
70 .then(async (response) => {
71 if (!response.ok)
72 return;
74 const selectedTrackers = torrentTrackersTable.selectedRowsIds();
75 torrentTrackersTable.clear();
77 const trackers = await response.json();
78 if (trackers) {
79 trackers.each((tracker) => {
80 let status;
81 switch (tracker.status) {
82 case 0:
83 status = "QBT_TR(Disabled)QBT_TR[CONTEXT=TrackerListWidget]";
84 break;
85 case 1:
86 status = "QBT_TR(Not contacted yet)QBT_TR[CONTEXT=TrackerListWidget]";
87 break;
88 case 2:
89 status = "QBT_TR(Working)QBT_TR[CONTEXT=TrackerListWidget]";
90 break;
91 case 3:
92 status = "QBT_TR(Updating...)QBT_TR[CONTEXT=TrackerListWidget]";
93 break;
94 case 4:
95 status = "QBT_TR(Not working)QBT_TR[CONTEXT=TrackerListWidget]";
96 break;
99 const row = {
100 rowId: tracker.url,
101 tier: (tracker.tier >= 0) ? tracker.tier : "",
102 url: tracker.url,
103 status: status,
104 peers: (tracker.num_peers >= 0) ? tracker.num_peers : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
105 seeds: (tracker.num_seeds >= 0) ? tracker.num_seeds : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
106 leeches: (tracker.num_leeches >= 0) ? tracker.num_leeches : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
107 downloaded: (tracker.num_downloaded >= 0) ? tracker.num_downloaded : "QBT_TR(N/A)QBT_TR[CONTEXT=TrackerListWidget]",
108 message: tracker.msg,
109 _sortable: !tracker.url.startsWith("** [")
112 torrentTrackersTable.updateRowData(row);
115 torrentTrackersTable.updateTable(false);
117 if (selectedTrackers.length > 0)
118 torrentTrackersTable.reselectRows(selectedTrackers);
121 .finally(() => {
122 clearTimeout(loadTrackersDataTimer);
123 loadTrackersDataTimer = loadTrackersData.delay(10000);
127 const updateData = () => {
128 clearTimeout(loadTrackersDataTimer);
129 loadTrackersDataTimer = -1;
130 loadTrackersData();
133 const torrentTrackersContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
134 targets: "#torrentTrackersTableDiv",
135 menu: "torrentTrackersMenu",
136 actions: {
137 AddTracker: (element, ref) => {
138 addTrackerFN();
140 EditTracker: (element, ref) => {
141 // only allow editing of one row
142 element.firstElementChild.click();
143 editTrackerFN(element);
145 RemoveTracker: (element, ref) => {
146 removeTrackerFN(element);
149 offsets: {
150 x: 0,
151 y: 2
153 onShow: function() {
154 const selectedTrackers = torrentTrackersTable.selectedRowsIds();
155 const containsStaticTracker = selectedTrackers.some((tracker) => {
156 return tracker.startsWith("** [");
159 if (containsStaticTracker || (selectedTrackers.length === 0)) {
160 this.hideItem("EditTracker");
161 this.hideItem("RemoveTracker");
162 this.hideItem("CopyTrackerUrl");
164 else {
165 this.showItem("EditTracker");
166 this.showItem("RemoveTracker");
167 this.showItem("CopyTrackerUrl");
172 const addTrackerFN = () => {
173 if (current_hash.length === 0)
174 return;
175 new MochaUI.Window({
176 id: "trackersPage",
177 icon: "images/qbittorrent-tray.svg",
178 title: "QBT_TR(Add trackers)QBT_TR[CONTEXT=TrackersAdditionDialog]",
179 loadMethod: "iframe",
180 contentURL: "addtrackers.html?hash=" + current_hash,
181 scrollbars: true,
182 resizable: false,
183 maximizable: false,
184 closable: true,
185 paddingVertical: 0,
186 paddingHorizontal: 0,
187 width: 500,
188 height: 260,
189 onCloseComplete: () => {
190 updateData();
195 const editTrackerFN = (element) => {
196 if (current_hash.length === 0)
197 return;
199 const trackerUrl = encodeURIComponent(element.childNodes[1].textContent);
200 new MochaUI.Window({
201 id: "trackersPage",
202 icon: "images/qbittorrent-tray.svg",
203 title: "QBT_TR(Tracker editing)QBT_TR[CONTEXT=TrackerListWidget]",
204 loadMethod: "iframe",
205 contentURL: "edittracker.html?hash=" + current_hash + "&url=" + trackerUrl,
206 scrollbars: true,
207 resizable: false,
208 maximizable: false,
209 closable: true,
210 paddingVertical: 0,
211 paddingHorizontal: 0,
212 width: 500,
213 height: 150,
214 onCloseComplete: () => {
215 updateData();
220 const removeTrackerFN = (element) => {
221 if (current_hash.length === 0)
222 return;
224 fetch("api/v2/torrents/removeTrackers", {
225 method: "POST",
226 body: new URLSearchParams({
227 hash: current_hash,
228 urls: torrentTrackersTable.selectedRowsIds().map(encodeURIComponent).join("|")
231 .then((response) => {
232 if (!response.ok)
233 return;
235 updateData();
239 const clear = () => {
240 torrentTrackersTable.clear();
243 new ClipboardJS("#CopyTrackerUrl", {
244 text: (trigger) => {
245 return torrentTrackersTable.selectedRowsIds().join("\n");
249 torrentTrackersTable.setup("torrentTrackersTableDiv", "torrentTrackersTableFixedHeaderDiv", torrentTrackersContextMenu);
251 return exports();
252 })();
253 Object.freeze(window.qBittorrent.PropTrackers);