WebUI: migrate to fetch API

This is the final part of it.

PR #22072.
This commit is contained in:
Chocobo1 2024-12-29 15:44:28 +08:00 committed by GitHub
parent e740a42366
commit 9c0475ebfa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 626 additions and 551 deletions

View file

@ -267,8 +267,8 @@
} }
setupTable(selectedRows); setupTable(selectedRows);
}; };
fileRenamer.onRenameError = (err, row) => { fileRenamer.onRenameError = (response, row) => {
if (err.xhr.status === 409) if (response.status === 409)
$("rename_error").textContent = `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``; $("rename_error").textContent = `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``;
}; };
$("renameOptions").addEventListener("change", (e) => { $("renameOptions").addEventListener("change", (e) => {
@ -379,7 +379,11 @@
}; };
const setupTable = (selectedRows) => { const setupTable = (selectedRows) => {
fetch(new URI("api/v2/torrents/files").setData("hash", data.hash), { const url = new URL("api/v2/torrents/files", window.location);
url.search = new URLSearchParams({
hash: data.hash
});
fetch(url, {
method: "GET", method: "GET",
cache: "no-store" cache: "no-store"
}) })

View file

@ -749,7 +749,11 @@ window.addEventListener("DOMContentLoaded", () => {
let syncRequestInProgress = false; let syncRequestInProgress = false;
const syncMainData = () => { const syncMainData = () => {
syncRequestInProgress = true; syncRequestInProgress = true;
fetch(new URI("api/v2/sync/maindata").setData("rid", syncMainDataLastResponseId), { const url = new URL("api/v2/sync/maindata", window.location);
url.search = new URLSearchParams({
rid: syncMainDataLastResponseId
});
fetch(url, {
method: "GET", method: "GET",
cache: "no-store" cache: "no-store"
}) })

View file

@ -360,13 +360,12 @@ const initializeWindows = () => {
toggleSequentialDownloadFN = () => { toggleSequentialDownloadFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/toggleSequentialDownload", {
url: "api/v2/torrents/toggleSequentialDownload", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hashes.join("|") hashes: hashes.join("|")
} })
}).send(); });
updateMainData(); updateMainData();
} }
}; };
@ -374,13 +373,12 @@ const initializeWindows = () => {
toggleFirstLastPiecePrioFN = () => { toggleFirstLastPiecePrioFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/toggleFirstLastPiecePrio", {
url: "api/v2/torrents/toggleFirstLastPiecePrio", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hashes.join("|") hashes: hashes.join("|")
} })
}).send(); });
updateMainData(); updateMainData();
} }
}; };
@ -388,14 +386,13 @@ const initializeWindows = () => {
setSuperSeedingFN = (val) => { setSuperSeedingFN = (val) => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/setSuperSeeding", {
url: "api/v2/torrents/setSuperSeeding", method: "POST",
method: "post", body: new URLSearchParams({
data: { hashes: hashes.join("|"),
value: val, value: val
hashes: hashes.join("|") })
} });
}).send();
updateMainData(); updateMainData();
} }
}; };
@ -403,14 +400,13 @@ const initializeWindows = () => {
setForceStartFN = () => { setForceStartFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/setForceStart", {
url: "api/v2/torrents/setForceStart", method: "POST",
method: "post", body: new URLSearchParams({
data: { hashes: hashes.join("|"),
value: "true", value: "true"
hashes: hashes.join("|") })
} });
}).send();
updateMainData(); updateMainData();
} }
}; };
@ -494,22 +490,23 @@ const initializeWindows = () => {
}); });
} }
else { else {
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: forceDeleteFiles
deleteFiles: forceDeleteFiles })
}, })
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();
}, });
onFailure: () => {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
} }
}; };
@ -523,13 +520,12 @@ const initializeWindows = () => {
stopFN = () => { stopFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/stop", {
url: "api/v2/torrents/stop", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hashes.join("|") hashes: hashes.join("|")
} })
}).send(); });
updateMainData(); updateMainData();
} }
}; };
@ -537,13 +533,12 @@ const initializeWindows = () => {
startFN = () => { startFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/start", {
url: "api/v2/torrents/start", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hashes.join("|") hashes: hashes.join("|")
} })
}).send(); });
updateMainData(); updateMainData();
} }
}; };
@ -565,20 +560,21 @@ const initializeWindows = () => {
}); });
} }
else { else {
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: enableAutoTMM
enable: enableAutoTMM })
}, })
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();
}, });
onFailure: () => {
alert("QBT_TR(Unable to set Auto Torrent Management for the selected torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
} }
}; };
@ -596,19 +592,20 @@ const initializeWindows = () => {
}); });
} }
else { else {
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();
}, });
onFailure: () => {
alert("QBT_TR(Unable to recheck torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
} }
}; };
@ -616,13 +613,12 @@ const initializeWindows = () => {
reannounceFN = () => { reannounceFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/reannounce", {
url: "api/v2/torrents/reannounce", method: "POST",
method: "post", body: new URLSearchParams({
data: { hashes: hashes.join("|")
hashes: hashes.join("|"), })
} });
}).send();
updateMainData(); updateMainData();
} }
}; };
@ -703,40 +699,42 @@ const initializeWindows = () => {
startVisibleTorrentsFN = () => { startVisibleTorrentsFN = () => {
const hashes = torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker); const hashes = torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker);
if (hashes.length > 0) { if (hashes.length > 0) {
new Request({ fetch("api/v2/torrents/start", {
url: "api/v2/torrents/start", 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 start torrents.)QBT_TR[CONTEXT=HttpServer]");
return;
}
updateMainData(); updateMainData();
updatePropertiesPanel(); updatePropertiesPanel();
}, });
onFailure: () => {
alert("QBT_TR(Unable to start torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
}; };
stopVisibleTorrentsFN = () => { stopVisibleTorrentsFN = () => {
const hashes = torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker); const hashes = torrentsTable.getFilteredTorrentsHashes(selectedStatus, selectedCategory, selectedTag, selectedTracker);
if (hashes.length > 0) { if (hashes.length > 0) {
new Request({ fetch("api/v2/torrents/stop", {
url: "api/v2/torrents/stop", 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 stop torrents.)QBT_TR[CONTEXT=HttpServer]");
return;
}
updateMainData(); updateMainData();
updatePropertiesPanel(); updatePropertiesPanel();
}, });
onFailure: () => {
alert("QBT_TR(Unable to stop torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
}; };
@ -760,22 +758,23 @@ const initializeWindows = () => {
}); });
} }
else { else {
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: false,
deleteFiles: false, })
}, })
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();
}, });
onFailure: () => {
alert("QBT_TR(Unable to delete torrents.)QBT_TR[CONTEXT=HttpServer]");
}
}).send();
} }
} }
}; };
@ -809,17 +808,19 @@ const initializeWindows = () => {
const categoryName = category_list.has(categoryHash) const categoryName = category_list.has(categoryHash)
? category_list.get(categoryHash).name ? category_list.get(categoryHash).name
: ""; : "";
new Request({ fetch("api/v2/torrents/setCategory", {
url: "api/v2/torrents/setCategory", method: "POST",
method: "post", body: new URLSearchParams({
data: { hashes: hashes.join("|"),
hashes: hashes.join("|"), category: categoryName
category: categoryName })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok)
return;
updateMainData(); updateMainData();
} });
}).send();
}; };
createCategoryFN = () => { createCategoryFN = () => {
@ -879,18 +880,19 @@ const initializeWindows = () => {
}; };
removeCategoryFN = (categoryHash) => { removeCategoryFN = (categoryHash) => {
const categoryName = category_list.get(categoryHash).name; fetch("api/v2/torrents/removeCategories", {
new Request({ method: "POST",
url: "api/v2/torrents/removeCategories", body: new URLSearchParams({
method: "post", categories: category_list.get(categoryHash).name
data: { })
categories: categoryName })
}, .then((response) => {
onSuccess: () => { if (!response.ok)
return;
setCategoryFilter(CATEGORIES_ALL); setCategoryFilter(CATEGORIES_ALL);
updateMainData(); updateMainData();
} });
}).send();
}; };
deleteUnusedCategoriesFN = () => { deleteUnusedCategoriesFN = () => {
@ -899,18 +901,19 @@ const initializeWindows = () => {
if (torrentsTable.getFilteredTorrentsNumber("all", hash, TAGS_ALL, TRACKERS_ALL) === 0) if (torrentsTable.getFilteredTorrentsNumber("all", hash, TAGS_ALL, TRACKERS_ALL) === 0)
categories.push(category.name); categories.push(category.name);
}); });
fetch("api/v2/torrents/removeCategories", {
method: "POST",
body: new URLSearchParams({
categories: categories.join("\n")
})
})
.then((response) => {
if (!response.ok)
return;
new Request({
url: "api/v2/torrents/removeCategories",
method: "post",
data: {
categories: categories.join("\n")
},
onSuccess: () => {
setCategoryFilter(CATEGORIES_ALL); setCategoryFilter(CATEGORIES_ALL);
updateMainData(); updateMainData();
} });
}).send();
}; };
torrentAddTagsFN = () => { torrentAddTagsFN = () => {
@ -939,27 +942,24 @@ const initializeWindows = () => {
if (hashes.length <= 0) if (hashes.length <= 0)
return; return;
const tagName = tagList.has(tagHash) ? tagList.get(tagHash).name : ""; fetch((isSet ? "api/v2/torrents/addTags" : "api/v2/torrents/removeTags"), {
new Request({ method: "POST",
url: (isSet ? "api/v2/torrents/addTags" : "api/v2/torrents/removeTags"), body: new URLSearchParams({
method: "post",
data: {
hashes: hashes.join("|"), hashes: hashes.join("|"),
tags: tagName, tags: (tagList.get(tagHash)?.name || "")
} })
}).send(); });
}; };
torrentRemoveAllTagsFN = () => { torrentRemoveAllTagsFN = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch("api/v2/torrents/removeTags", {
url: ("api/v2/torrents/removeTags"), method: "POST",
method: "post", body: new URLSearchParams({
data: { hashes: hashes.join("|")
hashes: hashes.join("|"), })
} });
}).send();
} }
}; };
@ -983,14 +983,12 @@ const initializeWindows = () => {
}; };
removeTagFN = (tagHash) => { removeTagFN = (tagHash) => {
const tagName = tagList.get(tagHash).name; fetch("api/v2/torrents/deleteTags", {
new Request({ method: "POST",
url: "api/v2/torrents/deleteTags", body: new URLSearchParams({
method: "post", tags: tagList.get(tagHash).name
data: { })
tags: tagName });
}
}).send();
setTagFilter(TAGS_ALL); setTagFilter(TAGS_ALL);
}; };
@ -1000,13 +998,12 @@ const initializeWindows = () => {
if (torrentsTable.getFilteredTorrentsNumber("all", CATEGORIES_ALL, hash, TRACKERS_ALL) === 0) if (torrentsTable.getFilteredTorrentsNumber("all", CATEGORIES_ALL, hash, TRACKERS_ALL) === 0)
tags.push(tag.name); tags.push(tag.name);
}); });
new Request({ fetch("api/v2/torrents/deleteTags", {
url: "api/v2/torrents/deleteTags", method: "POST",
method: "post", body: new URLSearchParams({
data: {
tags: tags.join(",") tags: tags.join(",")
} })
}).send(); });
setTagFilter(TAGS_ALL); setTagFilter(TAGS_ALL);
}; };
@ -1130,13 +1127,12 @@ const initializeWindows = () => {
e.stopPropagation(); e.stopPropagation();
if (confirm("QBT_TR(Would you like to stop all torrents?)QBT_TR[CONTEXT=MainWindow]")) { if (confirm("QBT_TR(Would you like to stop all torrents?)QBT_TR[CONTEXT=MainWindow]")) {
new Request({ fetch("api/v2/torrents/stop", {
url: "api/v2/torrents/stop", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: "all" hashes: "all"
} })
}).send(); });
updateMainData(); updateMainData();
} }
}); });
@ -1146,13 +1142,12 @@ const initializeWindows = () => {
e.stopPropagation(); e.stopPropagation();
if (confirm("QBT_TR(Would you like to start all torrents?)QBT_TR[CONTEXT=MainWindow]")) { if (confirm("QBT_TR(Would you like to start all torrents?)QBT_TR[CONTEXT=MainWindow]")) {
new Request({ fetch("api/v2/torrents/start", {
url: "api/v2/torrents/start", method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: "all" hashes: "all"
} })
}).send(); });
updateMainData(); updateMainData();
} }
}); });
@ -1165,13 +1160,12 @@ const initializeWindows = () => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
hashes.each((hash, index) => { hashes.each((hash, index) => {
new Request({ fetch(`api/v2/torrents/${item}`, {
url: "api/v2/torrents/" + item, method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hash hashes: hash
} })
}).send(); });
}); });
updateMainData(); updateMainData();
} }
@ -1189,13 +1183,12 @@ const initializeWindows = () => {
setQueuePositionFN = (cmd) => { setQueuePositionFN = (cmd) => {
const hashes = torrentsTable.selectedRowsIds(); const hashes = torrentsTable.selectedRowsIds();
if (hashes.length) { if (hashes.length) {
new Request({ fetch(`api/v2/torrents/${cmd}`, {
url: "api/v2/torrents/" + cmd, method: "POST",
method: "post", body: new URLSearchParams({
data: {
hashes: hashes.join("|") hashes: hashes.join("|")
} })
}).send(); });
updateMainData(); updateMainData();
} }
}; };
@ -1229,13 +1222,15 @@ const initializeWindows = () => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
new Request({ fetch("api/v2/auth/logout", {
url: "api/v2/auth/logout", method: "POST"
method: "post", })
onSuccess: () => { .then((response) => {
if (!response.ok)
return;
window.location.reload(true); window.location.reload(true);
} });
}).send();
}); });
addClickEvent("shutdown", (e) => { addClickEvent("shutdown", (e) => {
@ -1243,17 +1238,19 @@ const initializeWindows = () => {
e.stopPropagation(); e.stopPropagation();
if (confirm("QBT_TR(Are you sure you want to quit qBittorrent?)QBT_TR[CONTEXT=MainWindow]")) { if (confirm("QBT_TR(Are you sure you want to quit qBittorrent?)QBT_TR[CONTEXT=MainWindow]")) {
new Request({ fetch("api/v2/app/shutdown", {
url: "api/v2/app/shutdown", method: "POST"
method: "post", })
onSuccess: () => { .then((response) => {
if (!response.ok)
return;
const shutdownMessage = "QBT_TR(%1 has been shutdown)QBT_TR[CONTEXT=HttpServer]".replace("%1", window.qBittorrent.Client.mainTitle()); const shutdownMessage = "QBT_TR(%1 has been shutdown)QBT_TR[CONTEXT=HttpServer]".replace("%1", window.qBittorrent.Client.mainTitle());
document.write(`<!doctype html><html lang="${LANG}"><head> <meta charset="UTF-8"> <meta name="color-scheme" content="light dark"> <title>${shutdownMessage}</title> <style>* {font-family: Arial, Helvetica, sans-serif;}</style></head><body> <h1 style="text-align: center;">${shutdownMessage}</h1></body></html>`); document.write(`<!doctype html><html lang="${LANG}"><head> <meta charset="UTF-8"> <meta name="color-scheme" content="light dark"> <title>${shutdownMessage}</title> <style>* {font-family: Arial, Helvetica, sans-serif;}</style></head><body> <h1 style="text-align: center;">${shutdownMessage}</h1></body></html>`);
document.close(); document.close();
window.stop(); window.stop();
window.qBittorrent.Client.stop(); window.qBittorrent.Client.stop();
} });
}).send();
} }
}); });

View file

@ -354,7 +354,12 @@ window.qBittorrent.PropFiles ??= (() => {
current_hash = new_hash; current_hash = new_hash;
loadedNewTorrent = true; loadedNewTorrent = true;
} }
fetch(new URI("api/v2/torrents/files").setData("hash", current_hash), {
const url = new URL("api/v2/torrents/files", window.location);
url.search = new URLSearchParams({
hash: current_hash
});
fetch(url, {
method: "GET", method: "GET",
cache: "no-store" cache: "no-store"
}) })

View file

@ -88,7 +88,11 @@ window.qBittorrent.PropGeneral ??= (() => {
return; return;
} }
fetch(new URI("api/v2/torrents/properties").setData("hash", current_id), { const propertiesURL = new URL("api/v2/torrents/properties", window.location);
propertiesURL.search = new URLSearchParams({
hash: current_id
});
fetch(propertiesURL, {
method: "GET", method: "GET",
cache: "no-store" cache: "no-store"
}) })
@ -230,7 +234,11 @@ window.qBittorrent.PropGeneral ??= (() => {
loadTorrentDataTimer = loadTorrentData.delay(5000); loadTorrentDataTimer = loadTorrentData.delay(5000);
}); });
fetch(new URI("api/v2/torrents/pieceStates").setData("hash", current_id), { const pieceStatesURL = new URL("api/v2/torrents/pieceStates", window.location);
pieceStatesURL.search = new URLSearchParams({
hash: current_id
});
fetch(pieceStatesURL, {
method: "GET", method: "GET",
cache: "no-store" cache: "no-store"
}) })

View file

@ -58,19 +58,23 @@ window.qBittorrent.PropTrackers ??= (() => {
torrentTrackersTable.clear(); torrentTrackersTable.clear();
current_hash = new_hash; current_hash = new_hash;
} }
const url = new URI("api/v2/torrents/trackers?hash=" + current_hash);
new Request.JSON({ const url = new URL("api/v2/torrents/trackers", window.location);
url: url, url.search = new URLSearchParams({
method: "get", hash: current_hash
noCache: true, });
onComplete: () => { fetch(url, {
clearTimeout(loadTrackersDataTimer); method: "GET",
loadTrackersDataTimer = loadTrackersData.delay(10000); cache: "no-store"
}, })
onSuccess: (trackers) => { .then(async (response) => {
if (!response.ok)
return;
const selectedTrackers = torrentTrackersTable.selectedRowsIds(); const selectedTrackers = torrentTrackersTable.selectedRowsIds();
torrentTrackersTable.clear(); torrentTrackersTable.clear();
const trackers = await response.json();
if (trackers) { if (trackers) {
trackers.each((tracker) => { trackers.each((tracker) => {
let status; let status;
@ -113,8 +117,11 @@ window.qBittorrent.PropTrackers ??= (() => {
if (selectedTrackers.length > 0) if (selectedTrackers.length > 0)
torrentTrackersTable.reselectRows(selectedTrackers); torrentTrackersTable.reselectRows(selectedTrackers);
} }
} })
}).send(); .finally(() => {
clearTimeout(loadTrackersDataTimer);
loadTrackersDataTimer = loadTrackersData.delay(10000);
});
}; };
const updateData = () => { const updateData = () => {
@ -214,18 +221,19 @@ window.qBittorrent.PropTrackers ??= (() => {
if (current_hash.length === 0) if (current_hash.length === 0)
return; return;
const selectedTrackers = torrentTrackersTable.selectedRowsIds(); fetch("api/v2/torrents/removeTrackers", {
new Request({ method: "POST",
url: "api/v2/torrents/removeTrackers", body: new URLSearchParams({
method: "post", hash: current_hash,
data: { urls: torrentTrackersTable.selectedRowsIds().map(encodeURIComponent).join("|")
hash: current_hash, })
urls: selectedTrackers.map(encodeURIComponent).join("|") })
}, .then((response) => {
onSuccess: () => { if (!response.ok)
return;
updateData(); updateData();
} });
}).send();
}; };
const clear = () => { const clear = () => {

View file

@ -58,18 +58,23 @@ window.qBittorrent.PropWebseeds ??= (() => {
torrentWebseedsTable.clear(); torrentWebseedsTable.clear();
current_hash = new_hash; current_hash = new_hash;
} }
new Request.JSON({
url: new URI("api/v2/torrents/webseeds").setData("hash", current_hash), const url = new URL("api/v2/torrents/webseeds", window.location);
method: "get", url.search = new URLSearchParams({
noCache: true, hash: current_hash
onComplete: () => { });
clearTimeout(loadWebSeedsDataTimer); fetch(url, {
loadWebSeedsDataTimer = loadWebSeedsData.delay(10000); method: "GET",
}, cache: "no-store"
onSuccess: (webseeds) => { })
.then(async (response) => {
if (!response.ok)
return;
const selectedWebseeds = torrentWebseedsTable.selectedRowsIds(); const selectedWebseeds = torrentWebseedsTable.selectedRowsIds();
torrentWebseedsTable.clear(); torrentWebseedsTable.clear();
const webseeds = await response.json();
if (webseeds) { if (webseeds) {
// Update WebSeeds data // Update WebSeeds data
webseeds.each((webseed) => { webseeds.each((webseed) => {
@ -84,8 +89,11 @@ window.qBittorrent.PropWebseeds ??= (() => {
if (selectedWebseeds.length > 0) if (selectedWebseeds.length > 0)
torrentWebseedsTable.reselectRows(selectedWebseeds); torrentWebseedsTable.reselectRows(selectedWebseeds);
} })
}).send(); .finally(() => {
clearTimeout(loadWebSeedsDataTimer);
loadWebSeedsDataTimer = loadWebSeedsData.delay(10000);
});
}; };
const updateData = () => { const updateData = () => {
@ -190,18 +198,19 @@ window.qBittorrent.PropWebseeds ??= (() => {
if (current_hash.length === 0) if (current_hash.length === 0)
return; return;
const selectedWebseeds = torrentWebseedsTable.selectedRowsIds(); fetch("api/v2/torrents/removeWebSeeds", {
new Request({ method: "POST",
url: "api/v2/torrents/removeWebSeeds", body: new URLSearchParams({
method: "post", hash: current_hash,
data: { urls: torrentWebseedsTable.selectedRowsIds().map(webseed => encodeURIComponent(webseed)).join("|")
hash: current_hash, })
urls: selectedWebseeds.map(webseed => encodeURIComponent(webseed)).join("|") })
}, .then((response) => {
onSuccess: () => { if (!response.ok)
return;
updateData(); updateData();
} });
}).send();
}; };
const clear = () => { const clear = () => {

View file

@ -47,7 +47,7 @@ window.qBittorrent.MultiRename ??= (() => {
onChanged: (rows) => {}, onChanged: (rows) => {},
onInvalidRegex: (err) => {}, onInvalidRegex: (err) => {},
onRenamed: (rows) => {}, onRenamed: (rows) => {},
onRenameError: (err) => {}, onRenameError: (response) => {},
_inner_update: function() { _inner_update: function() {
const findMatches = (regex, str) => { const findMatches = (regex, str) => {
@ -240,21 +240,19 @@ window.qBittorrent.MultiRename ??= (() => {
const newPath = parentPath const newPath = parentPath
? parentPath + window.qBittorrent.Filesystem.PathSeparator + newName ? parentPath + window.qBittorrent.Filesystem.PathSeparator + newName
: newName; : newName;
const renameRequest = new Request({
url: isFolder ? "api/v2/torrents/renameFolder" : "api/v2/torrents/renameFile",
method: "post",
data: {
hash: this.hash,
oldPath: oldPath,
newPath: newPath
}
});
try { try {
await renameRequest.send(); await fetch((isFolder ? "api/v2/torrents/renameFolder" : "api/v2/torrents/renameFile"), {
method: "POST",
body: new URLSearchParams({
hash: this.hash,
oldPath: oldPath,
newPath: newPath
})
});
replaced.push(match); replaced.push(match);
} }
catch (err) { catch (response) {
this.onRenameError(err, match); this.onRenameError(response, match);
} }
}.bind(this); }.bind(this);

View file

@ -247,13 +247,12 @@ window.qBittorrent.Search ??= (() => {
tab.destroy(); tab.destroy();
new Request({ fetch("api/v2/search/delete", {
url: new URI("api/v2/search/delete"), method: "POST",
method: "post", body: new URLSearchParams({
data: {
id: searchId id: searchId
}, })
}).send(); });
const searchJobs = JSON.parse(LocalPreferences.get("search_jobs", "[]")); const searchJobs = JSON.parse(LocalPreferences.get("search_jobs", "[]"));
const jobIndex = searchJobs.findIndex((job) => job.id === searchId); const jobIndex = searchJobs.findIndex((job) => job.id === searchId);
@ -395,42 +394,45 @@ window.qBittorrent.Search ??= (() => {
const startSearch = (pattern, category, plugins) => { const startSearch = (pattern, category, plugins) => {
searchPatternChanged = false; searchPatternChanged = false;
fetch("api/v2/search/start", {
method: "POST",
body: new URLSearchParams({
pattern: pattern,
category: category,
plugins: plugins
})
})
.then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
const url = new URI("api/v2/search/start");
new Request.JSON({
url: url,
method: "post",
data: {
pattern: pattern,
category: category,
plugins: plugins
},
onSuccess: (response) => {
document.getElementById("startSearchButton").lastChild.textContent = "QBT_TR(Stop)QBT_TR[CONTEXT=SearchEngineWidget]"; document.getElementById("startSearchButton").lastChild.textContent = "QBT_TR(Stop)QBT_TR[CONTEXT=SearchEngineWidget]";
const searchId = response.id; const searchId = responseJSON.id;
createSearchTab(searchId, pattern); createSearchTab(searchId, pattern);
const searchJobs = JSON.parse(LocalPreferences.get("search_jobs", "[]")); const searchJobs = JSON.parse(LocalPreferences.get("search_jobs", "[]"));
searchJobs.push({ id: searchId, pattern: pattern }); searchJobs.push({ id: searchId, pattern: pattern });
LocalPreferences.set("search_jobs", JSON.stringify(searchJobs)); LocalPreferences.set("search_jobs", JSON.stringify(searchJobs));
} });
}).send();
}; };
const stopSearch = (searchId) => { const stopSearch = (searchId) => {
const url = new URI("api/v2/search/stop"); fetch("api/v2/search/stop", {
new Request({ method: "POST",
url: url, body: new URLSearchParams({
method: "post", id: searchId
data: { })
id: searchId })
}, .then((response) => {
onSuccess: (response) => { if (!response.ok)
return;
resetSearchState(searchId); resetSearchState(searchId);
// not strictly necessary to do this when the tab is being closed, but there's no harm in it // not strictly necessary to do this when the tab is being closed, but there's no harm in it
updateStatusIconElement(searchId, "QBT_TR(Search aborted)QBT_TR[CONTEXT=SearchJobWidget]", "images/task-reject.svg"); updateStatusIconElement(searchId, "QBT_TR(Search aborted)QBT_TR[CONTEXT=SearchJobWidget]", "images/task-reject.svg");
} });
}).send();
}; };
const getSelectedSearchId = () => { const getSelectedSearchId = () => {
@ -638,11 +640,16 @@ window.qBittorrent.Search ??= (() => {
}; };
const getPlugins = () => { const getPlugins = () => {
new Request.JSON({ fetch("api/v2/search/plugins", {
url: new URI("api/v2/search/plugins"), method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
const createOption = (text, value, disabled = false) => { const createOption = (text, value, disabled = false) => {
const option = document.createElement("option"); const option = document.createElement("option");
if (value !== undefined) if (value !== undefined)
@ -652,10 +659,10 @@ window.qBittorrent.Search ??= (() => {
return option; return option;
}; };
if (response !== prevSearchPluginsResponse) { if (prevSearchPluginsResponse !== responseJSON) {
prevSearchPluginsResponse = response; prevSearchPluginsResponse = responseJSON;
searchPlugins.length = 0; searchPlugins.length = 0;
response.forEach((plugin) => { responseJSON.forEach((plugin) => {
searchPlugins.push(plugin); searchPlugins.push(plugin);
}); });
@ -697,8 +704,7 @@ window.qBittorrent.Search ??= (() => {
reselectPlugin(); reselectPlugin();
} }
} });
}).send();
}; };
const getPlugin = (name) => { const getPlugin = (name) => {
@ -766,30 +772,30 @@ window.qBittorrent.Search ??= (() => {
const loadSearchResultsData = function(searchId) { const loadSearchResultsData = function(searchId) {
const state = searchState.get(searchId); const state = searchState.get(searchId);
const url = new URL("api/v2/search/results", window.location);
url.search = new URLSearchParams({
id: searchId,
limit: 500,
offset: state.rowId
});
fetch(url, {
method: "GET",
cache: "no-store"
})
.then(async (response) => {
if (!response.ok) {
if ((response.status === 400) || (response.status === 404)) {
// bad params. search id is invalid
resetSearchState(searchId);
updateStatusIconElement(searchId, "QBT_TR(An error occurred during search...)QBT_TR[CONTEXT=SearchJobWidget]", "images/error.svg");
}
else {
clearTimeout(state.loadResultsTimer);
state.loadResultsTimer = loadSearchResultsData.delay(3000, this, searchId);
}
return;
}
const maxResults = 500;
const url = new URI("api/v2/search/results");
new Request.JSON({
url: url,
method: "get",
noCache: true,
data: {
id: searchId,
limit: maxResults,
offset: state.rowId
},
onFailure: function(response) {
if ((response.status === 400) || (response.status === 404)) {
// bad params. search id is invalid
resetSearchState(searchId);
updateStatusIconElement(searchId, "QBT_TR(An error occurred during search...)QBT_TR[CONTEXT=SearchJobWidget]", "images/error.svg");
}
else {
clearTimeout(state.loadResultsTimer);
state.loadResultsTimer = loadSearchResultsData.delay(3000, this, searchId);
}
},
onSuccess: function(response) {
$("error_div").textContent = ""; $("error_div").textContent = "";
const state = searchState.get(searchId); const state = searchState.get(searchId);
@ -800,12 +806,13 @@ window.qBittorrent.Search ??= (() => {
return; return;
} }
if (response) { const responseJSON = await response.json();
if (responseJSON) {
const state = searchState.get(searchId); const state = searchState.get(searchId);
const newRows = []; const newRows = [];
if (response.results) { if (responseJSON.results) {
const results = response.results; const results = responseJSON.results;
for (let i = 0; i < results.length; ++i) { for (let i = 0; i < results.length; ++i) {
const result = results[i]; const result = results[i];
const row = { const row = {
@ -838,7 +845,7 @@ window.qBittorrent.Search ??= (() => {
searchResultsTable.updateTable(); searchResultsTable.updateTable();
} }
if ((response.status === "Stopped") && (state.rowId >= response.total)) { if ((responseJSON.status === "Stopped") && (state.rowId >= responseJSON.total)) {
resetSearchState(searchId); resetSearchState(searchId);
updateStatusIconElement(searchId, "QBT_TR(Search has finished)QBT_TR[CONTEXT=SearchJobWidget]", "images/task-complete.svg"); updateStatusIconElement(searchId, "QBT_TR(Search has finished)QBT_TR[CONTEXT=SearchJobWidget]", "images/task-complete.svg");
return; return;
@ -847,8 +854,7 @@ window.qBittorrent.Search ??= (() => {
clearTimeout(state.loadResultsTimer); clearTimeout(state.loadResultsTimer);
state.loadResultsTimer = loadSearchResultsData.delay(2000, this, searchId); state.loadResultsTimer = loadSearchResultsData.delay(2000, this, searchId);
} });
}).send();
}; };
const updateSearchResultsData = function(searchId) { const updateSearchResultsData = function(searchId) {

View file

@ -122,38 +122,43 @@
expirationDate: expDate, expirationDate: expDate,
}; };
}); });
fetch("api/v2/app/setCookies", {
method: "POST",
body: new URLSearchParams({
cookies: JSON.stringify(cookies)
})
})
.then(async (response) => {
if (!response.ok) {
let error = "Unable to save cookies";
const responseText = await response.text();
if (responseText.length > 0)
error += `: ${responseText}`;
alert(error);
return;
}
new Request({
url: "api/v2/app/setCookies",
method: "post",
noCache: true,
data: {
cookies: JSON.stringify(cookies)
},
onFailure: (response) => {
let error = "Unable to save cookies";
if (response?.responseText)
error += `: ${response.responseText}`;
alert(error);
},
onSuccess: (response) => {
window.qBittorrent.Client.closeWindow(document.getElementById("cookiesPage")); window.qBittorrent.Client.closeWindow(document.getElementById("cookiesPage"));
} });
}).send();
}; };
const loadCookies = () => { const loadCookies = () => {
new Request.JSON({ fetch("api/v2/app/cookies", {
url: "api/v2/app/cookies", method: "GET",
method: "get", cache: "no-store"
onFailure: (response) => { })
let error = "Unable to load cookies"; .then(async (response) => {
if (response?.responseText) if (!response.ok) {
error += `: ${response.responseText}`; let error = "Unable to load cookies";
alert(error); const responseText = await response.text();
}, if (responseText.length > 0)
onSuccess: (response) => { error += `: ${responseText}`;
for (const cookie of response) { alert(error);
return;
}
const responseJSON = await response.json();
for (const cookie of responseJSON) {
const row = addCookie(); const row = addCookie();
row.querySelector("td.domain input").value = cookie.domain; row.querySelector("td.domain input").value = cookie.domain;
row.querySelector("td.path input").value = cookie.path; row.querySelector("td.path input").value = cookie.path;
@ -167,8 +172,7 @@
row.querySelector("td.expDate input").valueAsNumber = date.getTime(); row.querySelector("td.expDate input").valueAsNumber = date.getTime();
} }
} }
} });
}).send();
}; };
const setup = () => { const setup = () => {

View file

@ -67,16 +67,18 @@
const newPluginOk = () => { const newPluginOk = () => {
const path = $("newPluginPath").value.trim(); const path = $("newPluginPath").value.trim();
if (path) { if (path) {
new Request({ fetch("api/v2/search/installPlugin", {
url: "api/v2/search/installPlugin", method: "POST",
method: "post", body: new URLSearchParams({
data: { sources: path
sources: path, })
}, })
onRequest: () => { .then((response) => {
if (!response.ok)
return;
window.qBittorrent.Client.closeWindow(document.getElementById("installSearchPlugin")); window.qBittorrent.Client.closeWindow(document.getElementById("installSearchPlugin"));
} });
}).send();
} }
}; };

View file

@ -1888,16 +1888,17 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
}; };
const sendTestEmail = () => { const sendTestEmail = () => {
new Request({ fetch("api/v2/app/sendTestEmail", {
url: "api/v2/app/sendTestEmail", method: "POST"
method: "post", })
onFailure: () => { .then((response) => {
alert("QBT_TR(Could not contact qBittorrent)QBT_TR[CONTEXT=HttpServer]"); if (!response.ok) {
}, alert("QBT_TR(Could not contact qBittorrent)QBT_TR[CONTEXT=HttpServer]");
onSuccess: () => { return;
}
alert("QBT_TR(Attempted to send email. Check your inbox to confirm success)QBT_TR[CONTEXT=OptionsDialog]"); alert("QBT_TR(Attempted to send email. Check your inbox to confirm success)QBT_TR[CONTEXT=OptionsDialog]");
} });
}).send();
}; };
const updateAutoRunOnTorrentAdded = () => { const updateAutoRunOnTorrentAdded = () => {
@ -2078,16 +2079,18 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
// Advanced Tab // Advanced Tab
const updateNetworkInterfaces = (default_iface, default_iface_name) => { const updateNetworkInterfaces = (default_iface, default_iface_name) => {
const url = "api/v2/app/networkInterfaceList";
$("networkInterface").getChildren().each(c => c.destroy()); $("networkInterface").getChildren().each(c => c.destroy());
new Request.JSON({ fetch("api/v2/app/networkInterfaceList", {
url: url, method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onFailure: () => { .then(async (response) => {
alert("Could not contact qBittorrent"); if (!response.ok) {
}, alert("Could not contact qBittorrent");
onSuccess: (ifaces) => { return;
}
const ifaces = await response.json();
if (!Array.isArray(ifaces)) if (!Array.isArray(ifaces))
return; return;
@ -2100,24 +2103,26 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
$("networkInterface").options.add(new Option(item.name, item.value)); $("networkInterface").options.add(new Option(item.name, item.value));
}); });
$("networkInterface").value = default_iface; $("networkInterface").value = default_iface;
} });
}).send();
}; };
const updateInterfaceAddresses = (iface, default_addr) => { const updateInterfaceAddresses = (iface, default_addr) => {
const url = "api/v2/app/networkInterfaceAddressList";
$("optionalIPAddressToBind").getChildren().each(c => c.destroy()); $("optionalIPAddressToBind").getChildren().each(c => c.destroy());
new Request.JSON({ const url = new URL("api/v2/app/networkInterfaceAddressList", window.location);
url: url, url.search = new URLSearchParams({
method: "get", iface: iface
noCache: true, });
data: { fetch(url, {
iface: iface method: "GET",
}, cache: "no-store"
onFailure: () => { })
alert("Could not contact qBittorrent"); .then(async (response) => {
}, if (!response.ok) {
onSuccess: (addresses) => { alert("Could not contact qBittorrent");
return;
}
const addresses = await response.json();
if (!addresses) if (!addresses)
return; return;
@ -2128,8 +2133,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
$("optionalIPAddressToBind").options.add(new Option(item, item)); $("optionalIPAddressToBind").options.add(new Option(item, item));
}); });
$("optionalIPAddressToBind").value = default_addr; $("optionalIPAddressToBind").value = default_addr;
} });
}).send();
}; };
const updateWebuiLocaleSelect = (selected) => { const updateWebuiLocaleSelect = (selected) => {

View file

@ -454,14 +454,20 @@
}; };
const updateRssFeedList = () => { const updateRssFeedList = () => {
new Request.JSON({ const url = new URL("api/v2/rss/items", window.location);
url: "api/v2/rss/items", url.search = new URLSearchParams({
method: "get", withData: true
noCache: true, });
data: { fetch(url, {
withData: true method: "GET",
}, cache: "no-store"
onSuccess: (response) => { })
.then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
// flatten folder structure // flatten folder structure
const flattenedResp = []; const flattenedResp = [];
const recFlatten = (current, name = "", depth = 0, fullName = "") => { const recFlatten = (current, name = "", depth = 0, fullName = "") => {
@ -488,7 +494,7 @@
} }
} }
}; };
recFlatten(response); recFlatten(responseJSON);
// check if rows matches flattened response // check if rows matches flattened response
const rssFeedRows = [...rssFeedTable.getRowValues()]; const rssFeedRows = [...rssFeedTable.getRowValues()];
@ -687,8 +693,7 @@
rssFeedTable.updateTable(false); rssFeedTable.updateTable(false);
rssFeedTable.updateIcons(); rssFeedTable.updateIcons();
} }
} });
}).send();
}; };
const refreshFeed = (feedUid) => { const refreshFeed = (feedUid) => {
@ -699,17 +704,19 @@
} }
rssFeedTable.updateIcons(); rssFeedTable.updateIcons();
new Request({ fetch("api/v2/rss/refreshItem", {
url: "api/v2/rss/refreshItem", method: "POST",
method: "post", body: new URLSearchParams({
data: { itemPath: pathByFeedId.get(feedUid)
itemPath: pathByFeedId.get(feedUid) })
}, })
onFailure: (response) => { .then(async (response) => {
if (response.status === 409) if (!response.ok) {
alert(response.responseText); if (response.status === 409)
} alert(await response.text());
}).send(); return;
}
});
}; };
const refreshAllFeeds = () => { const refreshAllFeeds = () => {
@ -802,17 +809,19 @@
rssFeedTable.updateTable(true); rssFeedTable.updateTable(true);
// send request // send request
new Request({ fetch("api/v2/rss/markAsRead", {
url: "api/v2/rss/markAsRead", method: "POST",
method: "post", body: new URLSearchParams({
data: { itemPath: path
itemPath: path })
}, })
onFailure: (response) => { .then(async (response) => {
if (response.status === 409) if (!response.ok) {
alert(response.responseText); if (response.status === 409)
} alert(await response.text());
}).send(); return;
}
});
}; };
const markArticleAsRead = (path, id) => { const markArticleAsRead = (path, id) => {
@ -843,18 +852,20 @@
rssFeedTable.updateTable(true); rssFeedTable.updateTable(true);
new Request({ fetch("api/v2/rss/markAsRead", {
url: "api/v2/rss/markAsRead", method: "POST",
method: "post", body: new URLSearchParams({
data: { itemPath: path,
itemPath: path, articleId: id
articleId: id })
}, })
onFailure: (response) => { .then(async (response) => {
if (response.status === 409) if (!response.ok) {
alert(response.responseText); if (response.status === 409)
} alert(await response.text());
}).send(); return;
}
});
} }
}; };

View file

@ -437,31 +437,41 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
} }
}); });
// get all categories and add to combobox // get all categories and add to combobox
new Request.JSON({ fetch("api/v2/torrents/categories", {
url: "api/v2/torrents/categories", method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
const combobox = $("assignCategoryCombobox"); const combobox = $("assignCategoryCombobox");
for (const cat in response) { for (const cat in responseJSON) {
if (!Object.hasOwn(response, cat)) if (!Object.hasOwn(responseJSON, cat))
continue; continue;
const option = document.createElement("option"); const option = document.createElement("option");
option.text = option.value = cat; option.text = option.value = cat;
combobox.add(option); combobox.add(option);
} }
} });
}).send();
// get all rss feed // get all rss feed
new Request.JSON({ const url = new URL("api/v2/rss/items", window.location);
url: "api/v2/rss/items", url.search = new URLSearchParams({
method: "get", withData: false
noCache: true, });
data: { fetch(url, {
withData: false method: "GET",
}, cache: "no-store"
onSuccess: (response) => { })
.then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
feedList = []; feedList = [];
const flatten = (root) => { const flatten = (root) => {
for (const child in root) { for (const child in root) {
@ -471,9 +481,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
flatten(root[child]); flatten(root[child]);
} }
}; };
flatten(response); flatten(responseJSON);
} });
}).send();
$("savetoDifferentDir").addEventListener("click", () => { $("savetoDifferentDir").addEventListener("click", () => {
$("saveToText").disabled = !$("savetoDifferentDir").checked; $("saveToText").disabled = !$("savetoDifferentDir").checked;
}); });
@ -482,41 +491,47 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
const updateRulesList = () => { const updateRulesList = () => {
// get all rules // get all rules
new Request.JSON({ fetch("api/v2/rss/rules", {
url: "api/v2/rss/rules", method: "GET",
method: "get", cache: "no-store"
noCache: true, })
onSuccess: (response) => { .then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
rssDownloaderRulesTable.clear(); rssDownloaderRulesTable.clear();
let rowCount = 0; let rowCount = 0;
for (const rule in response) { for (const rule in responseJSON) {
if (!Object.hasOwn(response, rule)) if (!Object.hasOwn(responseJSON, rule))
continue; continue;
rssDownloaderRulesTable.updateRowData({ rssDownloaderRulesTable.updateRowData({
rowId: rowCount++, rowId: rowCount++,
checked: response[rule].enabled, checked: responseJSON[rule].enabled,
name: rule name: rule
}); });
} }
rssDownloaderRulesTable.updateTable(false); rssDownloaderRulesTable.updateTable(false);
rulesList = response; rulesList = responseJSON;
} });
}).send();
}; };
const modifyRuleState = (rule, setting, newState, callback = () => {}) => { const modifyRuleState = (rule, setting, newState, callback = () => {}) => {
rulesList[rule][setting] = newState; rulesList[rule][setting] = newState;
new Request({ fetch("api/v2/rss/setRule", {
url: "api/v2/rss/setRule", method: "POST",
method: "post", body: new URLSearchParams({
data: { ruleName: rule,
ruleName: rule, ruleDef: JSON.stringify(rulesList[rule])
ruleDef: JSON.stringify(rulesList[rule]) })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok)
return;
callback(); callback();
} });
}).send();
}; };
const addRule = () => { const addRule = () => {
@ -639,39 +654,47 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
break; break;
} }
new Request({ fetch("api/v2/rss/setRule", {
url: "api/v2/rss/setRule", method: "POST",
method: "post", body: new URLSearchParams({
data: { ruleName: rule,
ruleName: rule, ruleDef: JSON.stringify(rulesList[rule])
ruleDef: JSON.stringify(rulesList[rule]) })
}, })
onSuccess: () => { .then((response) => {
if (!response.ok)
return;
updateMatchingArticles(rule); updateMatchingArticles(rule);
} });
}).send();
}; };
const updateMatchingArticles = (ruleName) => { const updateMatchingArticles = (ruleName) => {
new Request.JSON({ const url = new URL("api/v2/rss/matchingArticles", window.location);
url: "api/v2/rss/matchingArticles", url.search = new URLSearchParams({
method: "get", ruleName: ruleName
noCache: true, });
data: { fetch(url, {
ruleName: ruleName method: "GET",
}, cache: "no-store"
onSuccess: (response) => { })
.then(async (response) => {
if (!response.ok)
return;
const responseJSON = await response.json();
rssDownloaderArticlesTable.clear(); rssDownloaderArticlesTable.clear();
let rowCount = 0; let rowCount = 0;
for (const feed in response) { for (const feed in responseJSON) {
if (!Object.hasOwn(response, feed)) if (!Object.hasOwn(responseJSON, feed))
continue; continue;
rssDownloaderArticlesTable.updateRowData({ rssDownloaderArticlesTable.updateRowData({
rowId: rowCount++, rowId: rowCount++,
name: feed, name: feed,
isFeed: true isFeed: true
}); });
response[feed].each((article) => { responseJSON[feed].each((article) => {
rssDownloaderArticlesTable.updateRowData({ rssDownloaderArticlesTable.updateRowData({
rowId: rowCount++, rowId: rowCount++,
name: article, name: article,
@ -680,8 +703,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
}); });
} }
rssDownloaderArticlesTable.updateTable(false); rssDownloaderArticlesTable.updateTable(false);
} });
}).send();
}; };
const showRule = (ruleName) => { const showRule = (ruleName) => {

View file

@ -130,15 +130,12 @@
}; };
const uninstallPlugin = () => { const uninstallPlugin = () => {
const plugins = searchPluginsTable.selectedRowsIds().join("|"); fetch("api/v2/search/uninstallPlugin", {
const url = new URI("api/v2/search/uninstallPlugin"); method: "POST",
new Request({ body: new URLSearchParams({
url: url, names: searchPluginsTable.selectedRowsIds().join("|")
method: "post", })
data: { });
names: plugins,
}
}).send();
}; };
const enablePlugin = () => { const enablePlugin = () => {
@ -147,23 +144,19 @@
if (plugins && plugins.length) if (plugins && plugins.length)
enable = !window.qBittorrent.Search.getPlugin(plugins[0]).enabled; enable = !window.qBittorrent.Search.getPlugin(plugins[0]).enabled;
const url = new URI("api/v2/search/enablePlugin"); fetch("api/v2/search/enablePlugin", {
new Request({ method: "POST",
url: url, body: new URLSearchParams({
method: "post",
data: {
names: plugins.join("|"), names: plugins.join("|"),
enable: enable enable: enable
} })
}).send(); });
}; };
const checkForUpdates = () => { const checkForUpdates = () => {
const url = new URI("api/v2/search/updatePlugins"); fetch("api/v2/search/updatePlugins", {
new Request({ method: "POST"
url: url, });
method: "post"
}).send();
}; };
const calculateContextMenuOffsets = () => { const calculateContextMenuOffsets = () => {