WebUI: migrate to fetch API

And away from mootools.

PR #22037.
This commit is contained in:
Chocobo1 2024-12-22 17:51:19 +08:00 committed by GitHub
commit a841fe9320
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 888 additions and 811 deletions

View file

@ -36,20 +36,21 @@
if (peers.length === 0) if (peers.length === 0)
return; return;
new Request({ fetch("api/v2/torrents/addPeers", {
url: "api/v2/torrents/addPeers", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hash,
hashes: hash, "peers": peers.join("|")
peers: peers.join("|") })
}, })
onFailure: () => { .then((response) => {
alert("QBT_TR(Unable to add peers. Please ensure you are adhering to the IP:port format.)QBT_TR[CONTEXT=HttpServer]"); if (!response.ok) {
}, alert("QBT_TR(Unable to add peers. Please ensure you are adhering to the IP:port format.)QBT_TR[CONTEXT=HttpServer]");
onSuccess: () => { return;
}
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -27,18 +27,19 @@
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const hash = new URI().getData("hash"); fetch("api/v2/torrents/addTrackers", {
new Request({ method: "POST",
url: "api/v2/torrents/addTrackers", body: new URLSearchParams({
method: "post", "hash": new URI().getData("hash"),
data: { "urls": $("trackersUrls").value
hash: hash, })
urls: $("trackersUrls").value })
}, .then((response) => {
onComplete: () => { if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -25,18 +25,20 @@
$("urls").focus(); $("urls").focus();
$("addWebSeedsButton").addEventListener("click", (e) => { $("addWebSeedsButton").addEventListener("click", (e) => {
e.stopPropagation(); e.stopPropagation();
const hash = new URI().getData("hash");
new Request({ fetch("api/v2/torrents/addWebSeeds", {
url: "api/v2/torrents/addWebSeeds", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": new URI().getData("hash"),
hash: hash, "urls": $("urls").value.split("\n").map(w => encodeURIComponent(w.trim())).filter(w => (w.length > 0)).join("|")
urls: $("urls").value.split("\n").map(w => encodeURIComponent(w.trim())).filter(w => (w.length > 0)).join("|") })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -26,20 +26,22 @@
let completionCount = 0; let completionCount = 0;
paths.forEach((path) => { paths.forEach((path) => {
new Request({ fetch("api/v2/rss/removeItem", {
url: "api/v2/rss/removeItem", method: "POST",
method: "post", body: new URLSearchParams({
data: { "path": decodeURIComponent(path)
path: decodeURIComponent(path) })
}, })
onComplete: (response) => { .then((response) => {
if (!response.ok)
return;
++completionCount; ++completionCount;
if (completionCount === paths.length) { if (completionCount === paths.length) {
window.parent.qBittorrent.Rss.updateRssFeedList(); window.parent.qBittorrent.Rss.updateRssFeedList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} }
} });
}).send();
}); });
}); });
}); });

View file

@ -27,20 +27,22 @@
let completionCount = 0; let completionCount = 0;
rules.forEach((rule) => { rules.forEach((rule) => {
new Request({ fetch("api/v2/rss/removeRule", {
url: "api/v2/rss/removeRule", method: "POST",
method: "post", body: new URLSearchParams({
data: { "ruleName": decodeURIComponent(rule)
ruleName: decodeURIComponent(rule) })
}, })
onComplete: (response) => { .then((response) => {
if (!response.ok)
return;
++completionCount; ++completionCount;
if (completionCount === rules.length) { if (completionCount === rules.length) {
window.parent.qBittorrent.RssDownloader.updateRulesList(); window.parent.qBittorrent.RssDownloader.updateRulesList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} }
} });
}).send();
}); });
}); });
}); });

View file

@ -24,18 +24,20 @@
}); });
$("confirmBtn").addEventListener("click", (e) => { $("confirmBtn").addEventListener("click", (e) => {
e.stopPropagation(); e.stopPropagation();
const cmd = "api/v2/torrents/removeTrackers";
new Request({ fetch("api/v2/torrents/removeTrackers", {
url: cmd, method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": "*",
hash: "*", "urls": urls
urls: urls, })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -50,30 +50,34 @@
const setDlLimit = () => { const setDlLimit = () => {
const limit = Number($("dllimitUpdatevalue").value) * 1024; const limit = Number($("dllimitUpdatevalue").value) * 1024;
if (hashes[0] === "global") { if (hashes[0] === "global") {
new Request({ fetch("api/v2/transfer/setDownloadLimit", {
url: "api/v2/transfer/setDownloadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "limit": limit
"limit": limit })
}, })
onComplete: () => { .then(async (response) => {
if (!response.ok)
return;
window.parent.updateMainData(); window.parent.updateMainData();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
} }
else { else {
new Request({ fetch("api/v2/torrents/setDownloadLimit", {
url: "api/v2/torrents/setDownloadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|"),
"hashes": hashes.join("|"), "limit": limit
"limit": limit })
}, })
onComplete: () => { .then(async (response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
} }
}; };

View file

@ -51,25 +51,25 @@
$("submitButton").disabled = true; $("submitButton").disabled = true;
new Request({ fetch("api/v2/rss/setFeedURL", {
url: "api/v2/rss/setFeedURL", method: "POST",
method: "post", body: new URLSearchParams({
data: { "path": new URI().getData("path"),
path: new URI().getData("path"), "url": newUrl
url: newUrl })
}, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok) {
alert((response.status === 409)
? await response.text()
: "QBT_TR(Unable to update URL)QBT_TR[CONTEXT=RSSWidget]");
$("submitButton").disabled = false;
return;
}
window.parent.qBittorrent.Rss.updateRssFeedList(); window.parent.qBittorrent.Rss.updateRssFeedList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: (response) => {
if (response.status === 409)
alert(response.responseText);
else
alert("QBT_TR(Unable to update URL)QBT_TR[CONTEXT=RSSWidget]");
$("submitButton").disabled = false;
}
}).send();
}); });
}); });
</script> </script>

View file

@ -37,19 +37,20 @@
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const hash = new URI().getData("hash"); fetch("api/v2/torrents/editTracker", {
new Request({ method: "POST",
url: "api/v2/torrents/editTracker", body: new URLSearchParams({
method: "post", "hash": new URI().getData("hash"),
data: { "origUrl": currentUrl,
hash: hash, "newUrl": $("trackerUrl").value
origUrl: currentUrl, })
newUrl: $("trackerUrl").value })
}, .then((response) => {
onComplete: () => { if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -32,19 +32,21 @@
$("editWebSeedButton").addEventListener("click", (e) => { $("editWebSeedButton").addEventListener("click", (e) => {
e.stopPropagation(); e.stopPropagation();
const hash = new URI().getData("hash");
new Request({ fetch("api/v2/torrents/editWebSeed", {
url: "api/v2/torrents/editWebSeed", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": new URI().getData("hash"),
hash: hash, "origUrl": origUrl,
origUrl: origUrl, "newUrl": encodeURIComponent($("url").value.trim())
newUrl: encodeURIComponent($("url").value.trim()), })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -72,72 +72,77 @@
if ((uriHashes === "") || !verifyCategoryName(categoryName)) if ((uriHashes === "") || !verifyCategoryName(categoryName))
return; return;
new Request({ fetch("api/v2/torrents/createCategory", {
url: "api/v2/torrents/createCategory", method: "POST",
method: "post", body: new URLSearchParams({
data: { "category": categoryName,
category: categoryName, "savePath": savePath
savePath: savePath })
}, })
onSuccess: () => { .then((response) => {
new Request({ if (!response.ok) {
url: "api/v2/torrents/setCategory", alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category] " + window.qBittorrent.Misc.escapeHtml(categoryName));
method: "post", return;
data: { }
hashes: uriHashes,
category: categoryName fetch("api/v2/torrents/setCategory", {
}, method: "POST",
onSuccess: () => { body: new URLSearchParams({
"hashes": uriHashes,
"category": categoryName
})
})
.then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to set category)QBT_TR[CONTEXT=Category]");
return;
}
window.parent.updateMainData(); window.parent.updateMainData();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: () => { });
alert("QBT_TR(Unable to set category)QBT_TR[CONTEXT=Category]");
}
}).send();
},
onFailure: () => {
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category] " + window.qBittorrent.Misc.escapeHtml(categoryName));
}
}).send();
break; break;
case "create": case "create":
case "createSubcategory": case "createSubcategory":
if (!verifyCategoryName(categoryName)) if (!verifyCategoryName(categoryName))
return; return;
fetch("api/v2/torrents/createCategory", {
method: "POST",
body: new URLSearchParams({
"category": categoryName,
"savePath": savePath
})
})
.then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category]");
return;
}
new Request({
url: "api/v2/torrents/createCategory",
method: "post",
data: {
category: categoryName,
savePath: savePath
},
onSuccess: () => {
window.parent.updateMainData(); window.parent.updateMainData();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: () => {
alert("QBT_TR(Unable to create category)QBT_TR[CONTEXT=Category]");
}
}).send();
break; break;
case "edit": case "edit":
new Request({ fetch("api/v2/torrents/editCategory", {
url: "api/v2/torrents/editCategory", method: "POST",
method: "post", body: new URLSearchParams({
data: { "category": uriCategoryName, // category name can't be changed
category: uriCategoryName, // category name can't be changed "savePath": savePath
savePath: savePath })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to edit category)QBT_TR[CONTEXT=Category]");
return;
}
window.parent.updateMainData(); window.parent.updateMainData();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: () => {
alert("QBT_TR(Unable to edit category)QBT_TR[CONTEXT=Category]");
}
}).send();
break; break;
} }
}); });

View file

@ -42,23 +42,24 @@
$("submitButton").disabled = true; $("submitButton").disabled = true;
new Request({ fetch("api/v2/rss/addFeed", {
url: "api/v2/rss/addFeed", method: "POST",
method: "post", body: new URLSearchParams({
data: { "url": feedURL,
url: feedURL, "path": path ? (path + "\\" + feedURL) : ""
path: path ? (path + "\\" + feedURL) : "" })
}, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok) {
if (response.status === 409)
alert(await response.text());
$("submitButton").disabled = false;
return;
}
window.parent.qBittorrent.Rss.updateRssFeedList(); window.parent.qBittorrent.Rss.updateRssFeedList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: (response) => {
if (response.status === 409)
alert(response.responseText);
$("submitButton").disabled = false;
}
}).send();
}); });
}); });
</script> </script>

View file

@ -43,22 +43,23 @@
$("submitButton").disabled = true; $("submitButton").disabled = true;
new Request({ fetch("api/v2/rss/addFolder", {
url: "api/v2/rss/addFolder", method: "POST",
method: "post", body: new URLSearchParams({
data: { "path": path ? (path + "\\" + folderName) : folderName
path: path ? (path + "\\" + folderName) : folderName })
}, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok) {
if (response.status === 409)
alert(await response.text());
$("submitButton").disabled = false;
return;
}
window.parent.qBittorrent.Rss.updateRssFeedList(); window.parent.qBittorrent.Rss.updateRssFeedList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: (response) => {
if (response.status === 409)
alert(response.responseText);
$("submitButton").disabled = false;
}
}).send();
}); });
}); });

View file

@ -39,18 +39,21 @@
return; return;
} }
$("submitButton").disabled = true; $("submitButton").disabled = true;
new Request({
url: "api/v2/rss/setRule", fetch("api/v2/rss/setRule", {
method: "post", method: "POST",
data: { body: new URLSearchParams({
ruleName: name, "ruleName": name,
ruleDef: "{}" "ruleDef": "{}"
}, })
onSuccess: (response) => { })
.then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.RssDownloader.updateRulesList(); window.parent.qBittorrent.RssDownloader.updateRulesList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -56,33 +56,37 @@
if (uriHashes === "") if (uriHashes === "")
return; return;
new Request({ fetch("api/v2/torrents/addTags", {
url: "api/v2/torrents/addTags", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": uriHashes,
hashes: uriHashes, "tags": tagName
tags: tagName, })
}, })
onComplete: () => { .then(async (response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
break; break;
case "create": case "create":
if (!verifyTagName(tagName)) if (!verifyTagName(tagName))
return; return;
new Request({ fetch("api/v2/torrents/createTags", {
url: "api/v2/torrents/createTags", method: "POST",
method: "post", body: new URLSearchParams({
data: { "tags": tagName
tags: tagName, })
}, })
onComplete: () => { .then(async (response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
break; break;
} }
}); });

View file

@ -44,17 +44,19 @@
const hash = new URI().getData("hash"); const hash = new URI().getData("hash");
if (hash) { if (hash) {
new Request({ fetch("api/v2/torrents/rename", {
url: "api/v2/torrents/rename", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": hash,
hash: hash, "name": name
name: name })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
} }
}); });
}); });

View file

@ -51,23 +51,24 @@
$("renameButton").disabled = true; $("renameButton").disabled = true;
new Request({ fetch("api/v2/rss/moveItem", {
url: "api/v2/rss/moveItem", method: "POST",
method: "post", body: new URLSearchParams({
data: { "itemPath": oldPath,
itemPath: oldPath, "destPath": newPath
destPath: newPath })
}, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok) {
if (response.status === 409)
alert(await response.text());
$("renameButton").disabled = false;
return;
}
window.parent.qBittorrent.Rss.updateRssFeedList(); window.parent.qBittorrent.Rss.updateRssFeedList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: (response) => {
if (response.status === 409)
alert(response.responseText);
$("renameButton").disabled = false;
}
}).send();
}); });
}); });
</script> </script>

View file

@ -60,22 +60,23 @@
const newPath = parentPath const newPath = parentPath
? parentPath + window.qBittorrent.Filesystem.PathSeparator + newName ? parentPath + window.qBittorrent.Filesystem.PathSeparator + newName
: newName; : newName;
new Request({ fetch((isFolder ? "api/v2/torrents/renameFolder" : "api/v2/torrents/renameFile"), {
url: isFolder ? "api/v2/torrents/renameFolder" : "api/v2/torrents/renameFile", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": hash,
hash: hash, "oldPath": oldPath,
oldPath: oldPath, "newPath": newPath
newPath: newPath })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok) {
alert("QBT_TR(Failed to update name)QBT_TR[CONTEXT=HttpServer]");
$("renameButton").disabled = false;
return;
}
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: () => {
alert("QBT_TR(Failed to update name)QBT_TR[CONTEXT=HttpServer]");
$("renameButton").disabled = false;
}
}).send();
}); });
}); });
</script> </script>

View file

@ -379,17 +379,20 @@
}; };
const setupTable = (selectedRows) => { const setupTable = (selectedRows) => {
new Request.JSON({ fetch(new URI("api/v2/torrents/files").setData("hash", data.hash), {
url: new URI("api/v2/torrents/files?hash=" + data.hash), method: "GET",
noCache: true, cache: "no-store"
method: "get", })
onSuccess: (files) => { .then(async (response) => {
if (!response.ok)
return;
const files = await response.json();
if (files.length === 0) if (files.length === 0)
bulkRenameFilesTable.clear(); bulkRenameFilesTable.clear();
else else
handleTorrentFiles(files, selectedRows); handleTorrentFiles(files, selectedRows);
} });
}).send();
}; };
setupTable(data.selectedRows); setupTable(data.selectedRows);
})(); })();

View file

@ -50,18 +50,21 @@
} }
$("renameButton").disabled = true; $("renameButton").disabled = true;
new Request({
url: "api/v2/rss/renameRule", fetch("api/v2/rss/renameRule", {
method: "post", method: "POST",
data: { body: new URLSearchParams({
ruleName: oldName, "ruleName": oldName,
newRuleName: newName "newRuleName": newName
}, })
onSuccess: (response) => { })
.then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.RssDownloader.updateRulesList(); window.parent.qBittorrent.RssDownloader.updateRulesList();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });
</script> </script>

View file

@ -62,8 +62,7 @@ window.qBittorrent.Cache ??= (() => {
if (!response.ok) if (!response.ok)
return; return;
const responseText = await response.text(); const responseJSON = await response.json();
const responseJSON = JSON.parse(responseText);
deepFreeze(responseJSON); deepFreeze(responseJSON);
this.#m_store = responseJSON; this.#m_store = responseJSON;
}); });

View file

@ -748,199 +748,199 @@ window.addEventListener("DOMContentLoaded", () => {
let syncMainDataTimeoutID = -1; let syncMainDataTimeoutID = -1;
let syncRequestInProgress = false; let syncRequestInProgress = false;
const syncMainData = () => { const syncMainData = () => {
const url = new URI("api/v2/sync/maindata"); syncRequestInProgress = true;
url.setData("rid", syncMainDataLastResponseId); fetch(new URI("api/v2/sync/maindata").setData("rid", syncMainDataLastResponseId), {
const request = new Request.JSON({ method: "GET",
url: url, cache: "no-store"
noCache: true, })
method: "get", .then(async (response) => {
onFailure: () => { if (response.ok) {
const errorDiv = $("error_div"); $("error_div").textContent = "";
if (errorDiv)
errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
syncRequestInProgress = false;
syncData(2000);
},
onSuccess: (response) => {
$("error_div").textContent = "";
if (response) {
clearTimeout(torrentsFilterInputTimer);
torrentsFilterInputTimer = -1;
let torrentsTableSelectedRows; const responseJSON = await response.json();
let updateStatuses = false;
let update_categories = false;
let updateTags = false;
let updateTrackers = false;
let updateTorrents = false;
const full_update = (response["full_update"] === true);
if (full_update) {
torrentsTableSelectedRows = torrentsTable.selectedRowsIds();
updateStatuses = true;
update_categories = true;
updateTags = true;
updateTrackers = true;
updateTorrents = true;
torrentsTable.clear();
category_list.clear();
tagList.clear();
trackerList.clear();
}
if (response["rid"])
syncMainDataLastResponseId = response["rid"];
if (response["categories"]) {
for (const key in response["categories"]) {
if (!Object.hasOwn(response["categories"], key))
continue;
const responseCategory = response["categories"][key]; clearTimeout(torrentsFilterInputTimer);
const categoryHash = window.qBittorrent.Misc.genHash(key); torrentsFilterInputTimer = -1;
const category = category_list.get(categoryHash);
if (category !== undefined) {
// only the save path can change for existing categories
category.savePath = responseCategory.savePath;
}
else {
category_list.set(categoryHash, {
name: responseCategory.name,
savePath: responseCategory.savePath,
torrents: new Set()
});
}
}
update_categories = true;
}
if (response["categories_removed"]) {
response["categories_removed"].each((category) => {
const categoryHash = window.qBittorrent.Misc.genHash(category);
category_list.delete(categoryHash);
});
update_categories = true;
}
if (response["tags"]) {
for (const tag of response["tags"]) {
const tagHash = window.qBittorrent.Misc.genHash(tag);
if (!tagList.has(tagHash)) {
tagList.set(tagHash, {
name: tag,
torrents: new Set()
});
}
}
updateTags = true;
}
if (response["tags_removed"]) {
for (let i = 0; i < response["tags_removed"].length; ++i) {
const tagHash = window.qBittorrent.Misc.genHash(response["tags_removed"][i]);
tagList.delete(tagHash);
}
updateTags = true;
}
if (response["trackers"]) {
for (const [tracker, torrents] of Object.entries(response["trackers"])) {
const host = window.qBittorrent.Misc.getHost(tracker);
const hash = window.qBittorrent.Misc.genHash(host);
let trackerListItem = trackerList.get(hash); let torrentsTableSelectedRows;
if (trackerListItem === undefined) { let updateStatuses = false;
trackerListItem = { host: host, trackerTorrentMap: new Map() }; let update_categories = false;
trackerList.set(hash, trackerListItem); let updateTags = false;
} let updateTrackers = false;
trackerListItem.trackerTorrentMap.set(tracker, new Set(torrents)); let updateTorrents = false;
const fullUpdate = (responseJSON["fullUpdate"] === true);
if (fullUpdate) {
torrentsTableSelectedRows = torrentsTable.selectedRowsIds();
updateStatuses = true;
update_categories = true;
updateTags = true;
updateTrackers = true;
updateTorrents = true;
torrentsTable.clear();
category_list.clear();
tagList.clear();
trackerList.clear();
} }
updateTrackers = true; if (responseJSON["rid"])
} syncMainDataLastResponseId = responseJSON["rid"];
if (response["trackers_removed"]) { if (responseJSON["categories"]) {
for (let i = 0; i < response["trackers_removed"].length; ++i) { for (const key in responseJSON["categories"]) {
const tracker = response["trackers_removed"][i]; if (!Object.hasOwn(responseJSON["categories"], key))
const host = window.qBittorrent.Misc.getHost(tracker); continue;
const hash = window.qBittorrent.Misc.genHash(host);
const trackerListEntry = trackerList.get(hash); const responseCategory = responseJSON["categories"][key];
if (trackerListEntry) { const categoryHash = window.qBittorrent.Misc.genHash(key);
trackerListEntry.trackerTorrentMap.delete(tracker); const category = category_list.get(categoryHash);
// Remove unused trackers if (category !== undefined) {
if (trackerListEntry.trackerTorrentMap.size === 0) { // only the save path can change for existing categories
trackerList.delete(hash); category.savePath = responseCategory.savePath;
if (selectedTracker === hash) { }
selectedTracker = TRACKERS_ALL; else {
LocalPreferences.set("selected_tracker", selectedTracker.toString()); category_list.set(categoryHash, {
name: responseCategory.name,
savePath: responseCategory.savePath,
torrents: new Set()
});
}
}
update_categories = true;
}
if (responseJSON["categories_removed"]) {
responseJSON["categories_removed"].each((category) => {
const categoryHash = window.qBittorrent.Misc.genHash(category);
category_list.delete(categoryHash);
});
update_categories = true;
}
if (responseJSON["tags"]) {
for (const tag of responseJSON["tags"]) {
const tagHash = window.qBittorrent.Misc.genHash(tag);
if (!tagList.has(tagHash)) {
tagList.set(tagHash, {
name: tag,
torrents: new Set()
});
}
}
updateTags = true;
}
if (responseJSON["tags_removed"]) {
for (let i = 0; i < responseJSON["tags_removed"].length; ++i) {
const tagHash = window.qBittorrent.Misc.genHash(responseJSON["tags_removed"][i]);
tagList.delete(tagHash);
}
updateTags = true;
}
if (responseJSON["trackers"]) {
for (const [tracker, torrents] of Object.entries(responseJSON["trackers"])) {
const host = window.qBittorrent.Misc.getHost(tracker);
const hash = window.qBittorrent.Misc.genHash(host);
let trackerListItem = trackerList.get(hash);
if (trackerListItem === undefined) {
trackerListItem = { host: host, trackerTorrentMap: new Map() };
trackerList.set(hash, trackerListItem);
}
trackerListItem.trackerTorrentMap.set(tracker, new Set(torrents));
}
updateTrackers = true;
}
if (responseJSON["trackers_removed"]) {
for (let i = 0; i < responseJSON["trackers_removed"].length; ++i) {
const tracker = responseJSON["trackers_removed"][i];
const host = window.qBittorrent.Misc.getHost(tracker);
const hash = window.qBittorrent.Misc.genHash(host);
const trackerListEntry = trackerList.get(hash);
if (trackerListEntry) {
trackerListEntry.trackerTorrentMap.delete(tracker);
// Remove unused trackers
if (trackerListEntry.trackerTorrentMap.size === 0) {
trackerList.delete(hash);
if (selectedTracker === hash) {
selectedTracker = TRACKERS_ALL;
LocalPreferences.set("selected_tracker", selectedTracker.toString());
}
} }
} }
} }
updateTrackers = true;
} }
updateTrackers = true; if (responseJSON["torrents"]) {
} for (const key in responseJSON["torrents"]) {
if (response["torrents"]) { if (!Object.hasOwn(responseJSON["torrents"], key))
for (const key in response["torrents"]) { continue;
if (!Object.hasOwn(response["torrents"], key))
continue;
response["torrents"][key]["hash"] = key; responseJSON["torrents"][key]["hash"] = key;
response["torrents"][key]["rowId"] = key; responseJSON["torrents"][key]["rowId"] = key;
if (response["torrents"][key]["state"]) { if (responseJSON["torrents"][key]["state"]) {
const state = response["torrents"][key]["state"]; const state = responseJSON["torrents"][key]["state"];
response["torrents"][key]["status"] = state; responseJSON["torrents"][key]["status"] = state;
response["torrents"][key]["_statusOrder"] = statusSortOrder[state]; responseJSON["torrents"][key]["_statusOrder"] = statusSortOrder[state];
updateStatuses = true; updateStatuses = true;
}
torrentsTable.updateRowData(responseJSON["torrents"][key]);
if (addTorrentToCategoryList(responseJSON["torrents"][key]))
update_categories = true;
if (addTorrentToTagList(responseJSON["torrents"][key]))
updateTags = true;
updateTorrents = true;
} }
torrentsTable.updateRowData(response["torrents"][key]); }
if (addTorrentToCategoryList(response["torrents"][key])) if (responseJSON["torrents_removed"]) {
update_categories = true; responseJSON["torrents_removed"].each((hash) => {
if (addTorrentToTagList(response["torrents"][key])) torrentsTable.removeRow(hash);
updateTags = true; removeTorrentFromCategoryList(hash);
update_categories = true; // Always to update All category
removeTorrentFromTagList(hash);
updateTags = true; // Always to update All tag
});
updateTorrents = true; updateTorrents = true;
updateStatuses = true;
} }
}
if (response["torrents_removed"]) {
response["torrents_removed"].each((hash) => {
torrentsTable.removeRow(hash);
removeTorrentFromCategoryList(hash);
update_categories = true; // Always to update All category
removeTorrentFromTagList(hash);
updateTags = true; // Always to update All tag
});
updateTorrents = true;
updateStatuses = true;
}
// don't update the table unnecessarily // don't update the table unnecessarily
if (updateTorrents) if (updateTorrents)
torrentsTable.updateTable(full_update); torrentsTable.updateTable(fullUpdate);
if (response["server_state"]) { if (responseJSON["server_state"]) {
const tmp = response["server_state"]; const tmp = responseJSON["server_state"];
for (const k in tmp) { for (const k in tmp) {
if (!Object.hasOwn(tmp, k)) if (!Object.hasOwn(tmp, k))
continue; continue;
serverState[k] = tmp[k]; serverState[k] = tmp[k];
}
processServerState();
} }
processServerState();
if (updateStatuses)
updateFiltersList();
if (update_categories) {
updateCategoryList();
window.qBittorrent.TransferList.contextMenu.updateCategoriesSubMenu(category_list);
}
if (updateTags) {
updateTagList();
window.qBittorrent.TransferList.contextMenu.updateTagsSubMenu(tagList);
}
if (updateTrackers)
updateTrackerList();
if (fullUpdate)
// re-select previously selected rows
torrentsTable.reselectRows(torrentsTableSelectedRows);
} }
if (updateStatuses) syncRequestInProgress = false;
updateFiltersList(); syncData(window.qBittorrent.Client.getSyncMainDataInterval());
},
if (update_categories) { (error) => {
updateCategoryList(); const errorDiv = $("error_div");
window.qBittorrent.TransferList.contextMenu.updateCategoriesSubMenu(category_list); if (errorDiv)
} errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
if (updateTags) { syncRequestInProgress = false;
updateTagList(); syncData(2000);
window.qBittorrent.TransferList.contextMenu.updateTagsSubMenu(tagList); });
}
if (updateTrackers)
updateTrackerList();
if (full_update)
// re-select previously selected rows
torrentsTable.reselectRows(torrentsTableSelectedRows);
}
syncRequestInProgress = false;
syncData(window.qBittorrent.Client.getSyncMainDataInterval());
}
});
syncRequestInProgress = true;
request.send();
}; };
updateMainData = () => { updateMainData = () => {
@ -1101,18 +1101,19 @@ window.addEventListener("DOMContentLoaded", () => {
// Change icon immediately to give some feedback // Change icon immediately to give some feedback
updateAltSpeedIcon(!alternativeSpeedLimits); updateAltSpeedIcon(!alternativeSpeedLimits);
new Request({ fetch("api/v2/transfer/toggleSpeedLimitsMode", {
url: "api/v2/transfer/toggleSpeedLimitsMode", method: "POST"
method: "post", })
onComplete: () => { .then((response) => {
if (!response.ok) {
// Restore icon in case of failure
updateAltSpeedIcon(alternativeSpeedLimits);
return;
}
alternativeSpeedLimits = !alternativeSpeedLimits; alternativeSpeedLimits = !alternativeSpeedLimits;
updateMainData(); updateMainData();
}, });
onFailure: () => {
// Restore icon in case of failure
updateAltSpeedIcon(alternativeSpeedLimits);
}
}).send();
}); });
$("DlInfos").addEventListener("click", () => { globalDownloadLimitFN(); }); $("DlInfos").addEventListener("click", () => { globalDownloadLimitFN(); });

View file

@ -36,26 +36,28 @@ window.qBittorrent.Download ??= (() => {
let defaultSavePath = ""; let defaultSavePath = "";
const getCategories = () => { const getCategories = () => {
new Request.JSON({ fetch("api/v2/torrents/categories", {
url: "api/v2/torrents/categories", method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onSuccess: (data) => { .then(async (response) => {
if (data) { if (!response.ok)
categories = data; return;
for (const i in data) {
if (!Object.hasOwn(data, i))
continue;
const category = data[i]; const data = await response.json();
const option = document.createElement("option");
option.value = category.name; categories = data;
option.textContent = category.name; for (const i in data) {
$("categorySelect").appendChild(option); if (!Object.hasOwn(data, i))
} continue;
const category = data[i];
const option = document.createElement("option");
option.value = category.name;
option.textContent = category.name;
$("categorySelect").appendChild(option);
} }
} });
}).send();
}; };
const getPreferences = () => { const getPreferences = () => {

View file

@ -308,18 +308,20 @@ window.qBittorrent.PropFiles ??= (() => {
clearTimeout(loadTorrentFilesDataTimer); clearTimeout(loadTorrentFilesDataTimer);
loadTorrentFilesDataTimer = -1; loadTorrentFilesDataTimer = -1;
new Request({ fetch("api/v2/torrents/filePrio", {
url: "api/v2/torrents/filePrio", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": current_hash,
"hash": current_hash, "id": fileIds.join("|"),
"id": fileIds.join("|"), "priority": priority
"priority": priority })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
loadTorrentFilesDataTimer = loadTorrentFilesData.delay(1000); loadTorrentFilesDataTimer = loadTorrentFilesData.delay(1000);
} });
}).send();
const ignore = (priority === FilePriority.Ignored); const ignore = (priority === FilePriority.Ignored);
ids.forEach((_id) => { ids.forEach((_id) => {
@ -352,16 +354,16 @@ window.qBittorrent.PropFiles ??= (() => {
current_hash = new_hash; current_hash = new_hash;
loadedNewTorrent = true; loadedNewTorrent = true;
} }
const url = new URI("api/v2/torrents/files?hash=" + current_hash); fetch(new URI("api/v2/torrents/files").setData("hash", current_hash), {
new Request.JSON({ method: "GET",
url: url, cache: "no-store"
method: "get", })
noCache: true, .then(async (response) => {
onComplete: () => { if (!response.ok)
clearTimeout(loadTorrentFilesDataTimer); return;
loadTorrentFilesDataTimer = loadTorrentFilesData.delay(5000);
}, const files = await response.json();
onSuccess: (files) => {
clearTimeout(torrentFilesFilterInputTimer); clearTimeout(torrentFilesFilterInputTimer);
torrentFilesFilterInputTimer = -1; torrentFilesFilterInputTimer = -1;
@ -373,8 +375,11 @@ window.qBittorrent.PropFiles ??= (() => {
if (loadedNewTorrent) if (loadedNewTorrent)
collapseAllNodes(); collapseAllNodes();
} }
} })
}).send(); .finally(() => {
clearTimeout(loadTorrentFilesDataTimer);
loadTorrentFilesDataTimer = loadTorrentFilesData.delay(5000);
});
}; };
const updateData = () => { const updateData = () => {

View file

@ -87,18 +87,22 @@ window.qBittorrent.PropGeneral ??= (() => {
clearTimeout(loadTorrentDataTimer); clearTimeout(loadTorrentDataTimer);
return; return;
} }
const url = new URI("api/v2/torrents/properties?hash=" + current_id);
new Request.JSON({ fetch(new URI("api/v2/torrents/properties").setData("hash", current_id), {
url: url, method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onFailure: () => { .then(async (response) => {
$("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; if (!response.ok) {
clearTimeout(loadTorrentDataTimer); $("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
loadTorrentDataTimer = loadTorrentData.delay(10000); clearTimeout(loadTorrentDataTimer);
}, loadTorrentDataTimer = loadTorrentData.delay(10000);
onSuccess: (data) => { return;
}
$("error_div").textContent = ""; $("error_div").textContent = "";
const data = await response.json();
if (data) { if (data) {
// Update Torrent data // Update Torrent data
@ -224,22 +228,23 @@ window.qBittorrent.PropGeneral ??= (() => {
} }
clearTimeout(loadTorrentDataTimer); clearTimeout(loadTorrentDataTimer);
loadTorrentDataTimer = loadTorrentData.delay(5000); loadTorrentDataTimer = loadTorrentData.delay(5000);
} });
}).send();
fetch(new URI("api/v2/torrents/pieceStates").setData("hash", current_id), {
method: "GET",
cache: "no-store"
})
.then(async (response) => {
if (!response.ok) {
$("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
clearTimeout(loadTorrentDataTimer);
loadTorrentDataTimer = loadTorrentData.delay(10000);
return;
}
const piecesUrl = new URI("api/v2/torrents/pieceStates?hash=" + current_id);
new Request.JSON({
url: piecesUrl,
method: "get",
noCache: true,
onFailure: () => {
$("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
clearTimeout(loadTorrentDataTimer);
loadTorrentDataTimer = loadTorrentData.delay(10000);
},
onSuccess: (data) => {
$("error_div").textContent = ""; $("error_div").textContent = "";
const data = await response.json();
if (data) if (data)
piecesBar.setPieces(data); piecesBar.setPieces(data);
else else
@ -247,8 +252,7 @@ window.qBittorrent.PropGeneral ??= (() => {
clearTimeout(loadTorrentDataTimer); clearTimeout(loadTorrentDataTimer);
loadTorrentDataTimer = loadTorrentData.delay(5000); loadTorrentDataTimer = loadTorrentData.delay(5000);
} });
}).send();
}; };
const updateData = () => { const updateData = () => {

View file

@ -56,44 +56,45 @@ window.qBittorrent.PropPeers ??= (() => {
clearTimeout(loadTorrentPeersTimer); clearTimeout(loadTorrentPeersTimer);
return; return;
} }
const url = new URI("api/v2/sync/torrentPeers"); const url = new URI("api/v2/sync/torrentPeers")
url.setData("rid", syncTorrentPeersLastResponseId); .setData("rid", syncTorrentPeersLastResponseId)
url.setData("hash", current_hash); .setData("hash", current_hash);
new Request.JSON({ fetch(url, {
url: url, method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onComplete: () => { .then(async (response) => {
clearTimeout(loadTorrentPeersTimer); if (!response.ok)
loadTorrentPeersTimer = loadTorrentPeersData.delay(window.qBittorrent.Client.getSyncMainDataInterval()); return;
},
onSuccess: (response) => { const responseJSON = await response.json();
$("error_div").textContent = ""; $("error_div").textContent = "";
if (response) { if (responseJSON) {
const full_update = (response["full_update"] === true); const full_update = (responseJSON["full_update"] === true);
if (full_update) if (full_update)
torrentPeersTable.clear(); torrentPeersTable.clear();
if (response["rid"]) if (responseJSON["rid"])
syncTorrentPeersLastResponseId = response["rid"]; syncTorrentPeersLastResponseId = responseJSON["rid"];
if (response["peers"]) { if (responseJSON["peers"]) {
for (const key in response["peers"]) { for (const key in responseJSON["peers"]) {
if (!Object.hasOwn(response["peers"], key)) if (!Object.hasOwn(responseJSON["peers"], key))
continue; continue;
response["peers"][key]["rowId"] = key; responseJSON["peers"][key]["rowId"] = key;
torrentPeersTable.updateRowData(response["peers"][key]); torrentPeersTable.updateRowData(responseJSON["peers"][key]);
} }
} }
if (response["peers_removed"]) { if (responseJSON["peers_removed"]) {
response["peers_removed"].each((hash) => { responseJSON["peers_removed"].each((hash) => {
torrentPeersTable.removeRow(hash); torrentPeersTable.removeRow(hash);
}); });
} }
torrentPeersTable.updateTable(full_update); torrentPeersTable.updateTable(full_update);
if (response["show_flags"]) { if (responseJSON["show_flags"]) {
if (show_flags !== response["show_flags"]) { if (show_flags !== responseJSON["show_flags"]) {
show_flags = response["show_flags"]; show_flags = responseJSON["show_flags"];
torrentPeersTable.columns["country"].force_hide = !show_flags; torrentPeersTable.columns["country"].force_hide = !show_flags;
torrentPeersTable.updateColumn("country"); torrentPeersTable.updateColumn("country");
} }
@ -102,8 +103,12 @@ window.qBittorrent.PropPeers ??= (() => {
else { else {
torrentPeersTable.clear(); torrentPeersTable.clear();
} }
}
}).send(); })
.finally(() => {
clearTimeout(loadTorrentPeersTimer);
loadTorrentPeersTimer = loadTorrentPeersData.delay(window.qBittorrent.Client.getSyncMainDataInterval());
});
}; };
const updateData = () => { const updateData = () => {
@ -146,14 +151,13 @@ window.qBittorrent.PropPeers ??= (() => {
return; return;
if (confirm("QBT_TR(Are you sure you want to permanently ban the selected peers?)QBT_TR[CONTEXT=PeerListWidget]")) { if (confirm("QBT_TR(Are you sure you want to permanently ban the selected peers?)QBT_TR[CONTEXT=PeerListWidget]")) {
new Request({ fetch("api/v2/transfer/banPeers", {
url: "api/v2/transfer/banPeers", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hash": torrentsTable.getCurrentTorrentID(),
hash: torrentsTable.getCurrentTorrentID(), "peers": selectedPeers.join("|")
peers: selectedPeers.join("|") })
} });
}).send();
} }
} }
}, },

View file

@ -32,24 +32,28 @@ MochaUI.extend({
addUpLimitSlider: (hashes) => { addUpLimitSlider: (hashes) => {
if ($("uplimitSliderarea")) { if ($("uplimitSliderarea")) {
// Get global upload limit // Get global upload limit
let maximum = 500; fetch("api/v2/transfer/uploadLimit", {
new Request({ method: "GET",
url: "api/v2/transfer/uploadLimit", cache: "no-store"
method: "get", })
data: {}, .then(async (response) => {
onSuccess: (data) => { if (!response.ok)
if (data) { return;
const tmp = Number(data);
if (tmp > 0) { const data = await response.text();
maximum = tmp / 1024.0;
} let maximum = 500;
else { const tmp = Number(data);
if (hashes[0] === "global") if (tmp > 0) {
maximum = 10000; maximum = tmp / 1024.0;
else
maximum = 1000;
}
} }
else {
if (hashes[0] === "global")
maximum = 10000;
else
maximum = 1000;
}
// Get torrents upload limit // Get torrents upload limit
// And create slider // And create slider
if (hashes[0] === "global") { if (hashes[0] === "global") {
@ -83,77 +87,82 @@ MochaUI.extend({
} }
} }
else { else {
new Request.JSON({ fetch("api/v2/torrents/uploadLimit", {
url: "api/v2/torrents/uploadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|")
hashes: hashes.join("|") })
}, })
onSuccess: (data) => { .then(async (response) => {
if (data) { if (!response.ok)
let up_limit = data[hashes[0]]; return;
for (const key in data) {
if (up_limit !== data[key]) { const data = await response.json();
up_limit = 0;
break; let up_limit = data[hashes[0]];
} for (const key in data) {
} if (up_limit !== data[key]) {
if (up_limit < 0)
up_limit = 0; up_limit = 0;
new Slider($("uplimitSliderarea"), $("uplimitSliderknob"), { break;
steps: maximum,
offset: 0,
initialStep: (up_limit / 1024.0).round(),
onChange: (pos) => {
if (pos > 0) {
$("uplimitUpdatevalue").value = pos;
$("upLimitUnit").style.visibility = "visible";
}
else {
$("uplimitUpdatevalue").value = "∞";
$("upLimitUnit").style.visibility = "hidden";
}
}
});
// Set default value
if (up_limit === 0) {
$("uplimitUpdatevalue").value = "∞";
$("upLimitUnit").style.visibility = "hidden";
}
else {
$("uplimitUpdatevalue").value = (up_limit / 1024.0).round();
$("upLimitUnit").style.visibility = "visible";
} }
} }
} if (up_limit < 0)
}).send(); up_limit = 0;
new Slider($("uplimitSliderarea"), $("uplimitSliderknob"), {
steps: maximum,
offset: 0,
initialStep: (up_limit / 1024.0).round(),
onChange: (pos) => {
if (pos > 0) {
$("uplimitUpdatevalue").value = pos;
$("upLimitUnit").style.visibility = "visible";
}
else {
$("uplimitUpdatevalue").value = "∞";
$("upLimitUnit").style.visibility = "hidden";
}
}
});
// Set default value
if (up_limit === 0) {
$("uplimitUpdatevalue").value = "∞";
$("upLimitUnit").style.visibility = "hidden";
}
else {
$("uplimitUpdatevalue").value = (up_limit / 1024.0).round();
$("upLimitUnit").style.visibility = "visible";
}
});
} }
} });
}).send();
} }
}, },
addDlLimitSlider: (hashes) => { addDlLimitSlider: (hashes) => {
if ($("dllimitSliderarea")) { if ($("dllimitSliderarea")) {
// Get global upload limit // Get global upload limit
let maximum = 500; fetch("api/v2/transfer/downloadLimit", {
new Request({ method: "GET",
url: "api/v2/transfer/downloadLimit", cache: "no-store"
method: "get", })
data: {}, .then(async (response) => {
onSuccess: (data) => { if (!response.ok)
if (data) { return;
const tmp = Number(data);
if (tmp > 0) { const data = await response.text();
maximum = tmp / 1024.0;
} let maximum = 500;
else { const tmp = Number(data);
if (hashes[0] === "global") if (tmp > 0) {
maximum = 10000; maximum = tmp / 1024.0;
else
maximum = 1000;
}
} }
else {
if (hashes[0] === "global")
maximum = 10000;
else
maximum = 1000;
}
// Get torrents download limit // Get torrents download limit
// And create slider // And create slider
if (hashes[0] === "global") { if (hashes[0] === "global") {
@ -187,53 +196,54 @@ MochaUI.extend({
} }
} }
else { else {
new Request.JSON({ fetch("api/v2/torrents/downloadLimit", {
url: "api/v2/torrents/downloadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|")
hashes: hashes.join("|") })
}, })
onSuccess: (data) => { .then(async (response) => {
if (data) { if (!response.ok)
let dl_limit = data[hashes[0]]; return;
for (const key in data) {
if (dl_limit !== data[key]) { const data = await response.json();
dl_limit = 0;
break; let dl_limit = data[hashes[0]];
} for (const key in data) {
} if (dl_limit !== data[key]) {
if (dl_limit < 0)
dl_limit = 0; dl_limit = 0;
new Slider($("dllimitSliderarea"), $("dllimitSliderknob"), { break;
steps: maximum,
offset: 0,
initialStep: (dl_limit / 1024.0).round(),
onChange: (pos) => {
if (pos > 0) {
$("dllimitUpdatevalue").value = pos;
$("dlLimitUnit").style.visibility = "visible";
}
else {
$("dllimitUpdatevalue").value = "∞";
$("dlLimitUnit").style.visibility = "hidden";
}
}
});
// Set default value
if (dl_limit === 0) {
$("dllimitUpdatevalue").value = "∞";
$("dlLimitUnit").style.visibility = "hidden";
}
else {
$("dllimitUpdatevalue").value = (dl_limit / 1024.0).round();
$("dlLimitUnit").style.visibility = "visible";
} }
} }
} if (dl_limit < 0)
}).send(); dl_limit = 0;
new Slider($("dllimitSliderarea"), $("dllimitSliderknob"), {
steps: maximum,
offset: 0,
initialStep: (dl_limit / 1024.0).round(),
onChange: (pos) => {
if (pos > 0) {
$("dllimitUpdatevalue").value = pos;
$("dlLimitUnit").style.visibility = "visible";
}
else {
$("dllimitUpdatevalue").value = "∞";
$("dlLimitUnit").style.visibility = "hidden";
}
}
});
// Set default value
if (dl_limit === 0) {
$("dllimitUpdatevalue").value = "∞";
$("dlLimitUnit").style.visibility = "hidden";
}
else {
$("dllimitUpdatevalue").value = (dl_limit / 1024.0).round();
$("dlLimitUnit").style.visibility = "visible";
}
});
} }
} });
}).send();
} }
} }
}); });

View file

@ -45,21 +45,21 @@
return; return;
} }
const hashesList = new URI().getData("hashes"); fetch("api/v2/torrents/setLocation", {
new Request({ method: "POST",
url: "api/v2/torrents/setLocation", body: new URLSearchParams({
method: "post", "hashes": new URI().getData("hashes"),
data: { "location": location
hashes: hashesList, })
location: location })
}, .then(async (response) => {
onSuccess: () => { if (!response.ok) {
$("error_div").textContent = await response.text();
return;
}
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
}, });
onFailure: (xhr) => {
$("error_div").textContent = xhr.response;
}
}).send();
}); });
}); });
</script> </script>

View file

@ -100,19 +100,21 @@
return; return;
} }
new Request({ fetch("api/v2/torrents/setShareLimits", {
url: "api/v2/torrents/setShareLimits", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashesList.join("|"),
hashes: hashesList.join("|"), "ratioLimit": ratioLimitValue,
ratioLimit: ratioLimitValue, "seedingTimeLimit": seedingTimeLimitValue,
seedingTimeLimit: seedingTimeLimitValue, "inactiveSeedingTimeLimit": inactiveSeedingTimeLimitValue
inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue })
}, })
onComplete: () => { .then(async (response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
}); });
}); });

View file

@ -50,30 +50,34 @@
const setUpLimit = () => { const setUpLimit = () => {
const limit = Number($("uplimitUpdatevalue").value) * 1024; const limit = Number($("uplimitUpdatevalue").value) * 1024;
if (hashes[0] === "global") { if (hashes[0] === "global") {
new Request({ fetch("api/v2/transfer/setUploadLimit", {
url: "api/v2/transfer/setUploadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "limit": limit
"limit": limit })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.updateMainData(); window.parent.updateMainData();
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
} }
else { else {
new Request({ fetch("api/v2/torrents/setUploadLimit", {
url: "api/v2/torrents/setUploadLimit", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|"),
"hashes": hashes.join("|"), "limit": limit
"limit": limit })
}, })
onComplete: () => { .then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window); window.parent.qBittorrent.Client.closeFrameWindow(window);
} });
}).send();
} }
}; };

View file

@ -26,21 +26,22 @@
cancelButton.addEventListener("click", (e) => { window.qBittorrent.Client.closeWindow(windowEl); }); cancelButton.addEventListener("click", (e) => { window.qBittorrent.Client.closeWindow(windowEl); });
confirmButton.addEventListener("click", (e) => { confirmButton.addEventListener("click", (e) => {
new Request({ fetch("api/v2/torrents/setAutoManagement", {
url: "api/v2/torrents/setAutoManagement", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|"),
hashes: hashes.join("|"), "enable": enable
enable: enable })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to set Auto Torrent Management for the selected torrents.)QBT_TR[CONTEXT=HttpServer]");
return;
}
updateMainData(); updateMainData();
window.qBittorrent.Client.closeWindow(windowEl); window.qBittorrent.Client.closeWindow(windowEl);
}, });
onFailure: () => {
alert("QBT_TR(Unable to set Auto Torrent Management for the selected torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
}); });
// set tabindex so window element receives keydown events // set tabindex so window element receives keydown events

View file

@ -28,20 +28,21 @@
window.qBittorrent.Client.closeWindow(document.getElementById("confirmRecheckDialog")); window.qBittorrent.Client.closeWindow(document.getElementById("confirmRecheckDialog"));
}); });
confirmButton.addEventListener("click", (e) => { confirmButton.addEventListener("click", (e) => {
new Request({ fetch("api/v2/torrents/recheck", {
url: "api/v2/torrents/recheck", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|")
hashes: hashes.join("|"), })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to recheck torrents.)QBT_TR[CONTEXT=HttpServer]");
return;
}
updateMainData(); updateMainData();
window.qBittorrent.Client.closeWindow(document.getElementById("confirmRecheckDialog")); window.qBittorrent.Client.closeWindow(document.getElementById("confirmRecheckDialog"));
}, });
onFailure: () => {
alert("QBT_TR(Unable to recheck torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
}); });
// set tabindex so window element receives keydown events // set tabindex so window element receives keydown events

View file

@ -77,23 +77,24 @@
? torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker) ? torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker)
: torrentsTable.selectedRowsIds(); : torrentsTable.selectedRowsIds();
new Request({ fetch("api/v2/torrents/delete", {
url: "api/v2/torrents/delete", method: "POST",
method: "post", body: new URLSearchParams({
data: { "hashes": hashes.join("|"),
"hashes": hashes.join("|"), "deleteFiles": deleteCB.checked
"deleteFiles": deleteCB.checked })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok) {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
return;
}
torrentsTable.deselectAll(); torrentsTable.deselectAll();
updateMainData(); updateMainData();
updatePropertiesPanel(); updatePropertiesPanel();
window.qBittorrent.Client.closeWindow(document.getElementById("confirmDeletionPage")); window.qBittorrent.Client.closeWindow(document.getElementById("confirmDeletionPage"));
}, });
onFailure: () => {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
},
}).send();
}); });
})(); })();
</script> </script>

View file

@ -356,48 +356,51 @@
url.setData("last_known_id", tableInfo[curTab].last_id); url.setData("last_known_id", tableInfo[curTab].last_id);
tableInfo[curTab].progress = true; tableInfo[curTab].progress = true;
new Request.JSON({ fetch(url, {
url: url, method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onFailure: (response) => { .then(async (response) => {
const errorDiv = $("error_div"); if (!response.ok) {
if (errorDiv) const errorDiv = $("error_div");
errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; if (errorDiv)
tableInfo[curTab].progress = false; errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]";
syncLogWithInterval(10000); tableInfo[curTab].progress = false;
}, syncLogWithInterval(10000);
onSuccess: (response) => { return;
}
$("error_div").textContent = ""; $("error_div").textContent = "";
if ($("logTabColumn").classList.contains("invisible")) if ($("logTabColumn").classList.contains("invisible"))
return; return;
if (response.length > 0) { const responseJSON = await response.json();
if (responseJSON.length > 0) {
clearTimeout(logFilterTimer); clearTimeout(logFilterTimer);
logFilterTimer = -1; logFilterTimer = -1;
for (let i = 0; i < response.length; ++i) { for (let i = 0; i < responseJSON.length; ++i) {
let row; let row;
if (curTab === "main") { if (curTab === "main") {
row = { row = {
rowId: response[i].id, rowId: responseJSON[i].id,
message: response[i].message, message: responseJSON[i].message,
timestamp: response[i].timestamp, timestamp: responseJSON[i].timestamp,
type: response[i].type, type: responseJSON[i].type,
}; };
} }
else { else {
row = { row = {
rowId: response[i].id, rowId: responseJSON[i].id,
ip: response[i].ip, ip: responseJSON[i].ip,
timestamp: response[i].timestamp, timestamp: responseJSON[i].timestamp,
blocked: response[i].blocked, blocked: responseJSON[i].blocked,
reason: response[i].reason, reason: responseJSON[i].reason,
}; };
} }
tableInfo[curTab].instance.updateRowData(row); tableInfo[curTab].instance.updateRowData(row);
tableInfo[curTab].last_id = Math.max(Number(response[i].id), tableInfo[curTab].last_id); tableInfo[curTab].last_id = Math.max(Number(responseJSON[i].id), tableInfo[curTab].last_id);
} }
tableInfo[curTab].instance.updateTable(); tableInfo[curTab].instance.updateTable();
@ -406,8 +409,7 @@
tableInfo[curTab].progress = false; tableInfo[curTab].progress = false;
syncLogWithInterval(getSyncLogDataInterval()); syncLogWithInterval(getSyncLogDataInterval());
} });
}).send();
}; };
new ClipboardJS(".copyLogDataToClipboard", { new ClipboardJS(".copyLogDataToClipboard", {