From 7b3aa51bb16e242c6bf79f84fbe83f74e2029c38 Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Sat, 12 Apr 2025 11:53:52 +0200 Subject: [PATCH 01/21] WebUI: Eliminate redundant DOM element queries --- src/webui/www/private/scripts/contextmenu.js | 4 ++-- src/webui/www/private/scripts/download.js | 2 +- src/webui/www/private/views/preferences.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js index 7831461bf..094fba5b3 100644 --- a/src/webui/www/private/scripts/contextmenu.js +++ b/src/webui/www/private/scripts/contextmenu.js @@ -190,7 +190,7 @@ window.qBittorrent.ContextMenu ??= (() => { e.stopPropagation(); } // record this as the trigger - this.options.element = $(el); + this.options.element = el; this.adjustMenuPosition(e); // show the menu this.show(); @@ -219,7 +219,7 @@ window.qBittorrent.ContextMenu ??= (() => { }); // hide on body click - $(document.body).addEventListener("click", () => { + document.body.addEventListener("click", () => { this.hide(); this.options.element = null; }); diff --git a/src/webui/www/private/scripts/download.js b/src/webui/www/private/scripts/download.js index e79d97978..38a4ce81e 100644 --- a/src/webui/www/private/scripts/download.js +++ b/src/webui/www/private/scripts/download.js @@ -131,7 +131,7 @@ window.qBittorrent.Download ??= (() => { } }; - $(window).addEventListener("load", async () => { + window.addEventListener("load", async () => { // user might load this page directly (via browser magnet handler) // so wait for crucial initialization to complete await window.parent.qBittorrent.Client.initializeCaches(); diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 07109e68e..883efdbaa 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -3168,7 +3168,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD $("rowMarkOfTheWeb").style.display = "none"; $("networkInterface").addEventListener("change", function() { - updateInterfaceAddresses($(this).value, ""); + updateInterfaceAddresses(this.value, ""); }); loadPreferences(); From 411ca0f6684e3a1354b6c97ac4fc797e447f849b Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Sat, 12 Apr 2025 11:57:27 +0200 Subject: [PATCH 02/21] WebUI: Use native function for selecting elements by ID --- src/webui/www/private/addpeers.html | 6 +- src/webui/www/private/addtrackers.html | 6 +- src/webui/www/private/addwebseeds.html | 6 +- .../www/private/confirmfeeddeletion.html | 6 +- src/webui/www/private/confirmruleclear.html | 6 +- .../www/private/confirmruledeletion.html | 6 +- .../www/private/confirmtrackerdeletion.html | 8 +- src/webui/www/private/download.html | 14 +- src/webui/www/private/downloadlimit.html | 6 +- src/webui/www/private/editfeedurl.html | 16 +- src/webui/www/private/edittracker.html | 10 +- src/webui/www/private/editwebseed.html | 10 +- src/webui/www/private/newcategory.html | 22 +- src/webui/www/private/newfeed.html | 12 +- src/webui/www/private/newfolder.html | 12 +- src/webui/www/private/newrule.html | 10 +- src/webui/www/private/newtag.html | 10 +- src/webui/www/private/rename.html | 10 +- src/webui/www/private/rename_feed.html | 16 +- src/webui/www/private/rename_file.html | 16 +- src/webui/www/private/rename_files.html | 112 +- src/webui/www/private/rename_rule.html | 14 +- src/webui/www/private/scripts/client.js | 280 ++-- src/webui/www/private/scripts/contextmenu.js | 12 +- src/webui/www/private/scripts/download.js | 44 +- src/webui/www/private/scripts/dynamicTable.js | 14 +- src/webui/www/private/scripts/mocha-init.js | 6 +- src/webui/www/private/scripts/piecesbar.js | 2 +- src/webui/www/private/scripts/progressbar.js | 2 +- src/webui/www/private/scripts/prop-files.js | 14 +- src/webui/www/private/scripts/prop-general.js | 122 +- src/webui/www/private/scripts/prop-peers.js | 6 +- .../www/private/scripts/prop-trackers.js | 4 +- .../www/private/scripts/prop-webseeds.js | 4 +- src/webui/www/private/scripts/search.js | 134 +- src/webui/www/private/scripts/speedslider.js | 76 +- src/webui/www/private/setlocation.html | 14 +- src/webui/www/private/shareratio.html | 44 +- src/webui/www/private/upload.html | 14 +- src/webui/www/private/uploadlimit.html | 6 +- src/webui/www/private/views/about.html | 14 +- src/webui/www/private/views/aboutToolbar.html | 24 +- .../private/views/installsearchplugin.html | 4 +- src/webui/www/private/views/log.html | 22 +- src/webui/www/private/views/preferences.html | 1186 ++++++++--------- .../www/private/views/preferencesToolbar.html | 32 +- src/webui/www/private/views/rss.html | 8 +- .../www/private/views/rssDownloader.html | 184 +-- 48 files changed, 1303 insertions(+), 1303 deletions(-) diff --git a/src/webui/www/private/addpeers.html b/src/webui/www/private/addpeers.html index ad645b3d9..cfca9c026 100644 --- a/src/webui/www/private/addpeers.html +++ b/src/webui/www/private/addpeers.html @@ -26,13 +26,13 @@ if (hash === null) return; - $("peers").focus(); + document.getElementById("peers").focus(); - $("addPeersOk").addEventListener("click", (e) => { + document.getElementById("addPeersOk").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); - const peers = $("peers").value.trim().split(/[\r\n]+/); + const peers = document.getElementById("peers").value.trim().split(/[\r\n]+/); if (peers.length === 0) return; diff --git a/src/webui/www/private/addtrackers.html b/src/webui/www/private/addtrackers.html index 818f20f09..b11adf195 100644 --- a/src/webui/www/private/addtrackers.html +++ b/src/webui/www/private/addtrackers.html @@ -22,8 +22,8 @@ } }); - $("trackersUrls").focus(); - $("addTrackersButton").addEventListener("click", (e) => { + document.getElementById("trackersUrls").focus(); + document.getElementById("addTrackersButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); @@ -31,7 +31,7 @@ method: "POST", body: new URLSearchParams({ hash: new URLSearchParams(window.location.search).get("hash"), - urls: $("trackersUrls").value + urls: document.getElementById("trackersUrls").value }) }) .then((response) => { diff --git a/src/webui/www/private/addwebseeds.html b/src/webui/www/private/addwebseeds.html index c87c17146..e43b10fb3 100644 --- a/src/webui/www/private/addwebseeds.html +++ b/src/webui/www/private/addwebseeds.html @@ -22,15 +22,15 @@ } }); - $("urls").focus(); - $("addWebSeedsButton").addEventListener("click", (e) => { + document.getElementById("urls").focus(); + document.getElementById("addWebSeedsButton").addEventListener("click", (e) => { e.stopPropagation(); fetch("api/v2/torrents/addWebSeeds", { method: "POST", body: new URLSearchParams({ hash: new URLSearchParams(window.location.search).get("hash"), - urls: $("urls").value.split("\n").map(w => encodeURIComponent(w.trim())).filter(w => (w.length > 0)).join("|") + urls: document.getElementById("urls").value.split("\n").map(w => encodeURIComponent(w.trim())).filter(w => (w.length > 0)).join("|") }) }) .then((response) => { diff --git a/src/webui/www/private/confirmfeeddeletion.html b/src/webui/www/private/confirmfeeddeletion.html index b0f2abe5c..b4f209b36 100644 --- a/src/webui/www/private/confirmfeeddeletion.html +++ b/src/webui/www/private/confirmfeeddeletion.html @@ -13,13 +13,13 @@ "use strict"; window.addEventListener("DOMContentLoaded", () => { - $("cancelBtn").focus(); - $("cancelBtn").addEventListener("click", (e) => { + document.getElementById("cancelBtn").focus(); + document.getElementById("cancelBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); window.parent.qBittorrent.Client.closeFrameWindow(window); }); - $("confirmBtn").addEventListener("click", (e) => { + document.getElementById("confirmBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); diff --git a/src/webui/www/private/confirmruleclear.html b/src/webui/www/private/confirmruleclear.html index 9817d3c1d..57c3deb6b 100644 --- a/src/webui/www/private/confirmruleclear.html +++ b/src/webui/www/private/confirmruleclear.html @@ -13,13 +13,13 @@ "use strict"; window.addEventListener("DOMContentLoaded", () => { - $("cancelBtn").focus(); - $("cancelBtn").addEventListener("click", (e) => { + document.getElementById("cancelBtn").focus(); + document.getElementById("cancelBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); window.parent.qBittorrent.Client.closeFrameWindow(window); }); - $("confirmBtn").addEventListener("click", (e) => { + document.getElementById("confirmBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); diff --git a/src/webui/www/private/confirmruledeletion.html b/src/webui/www/private/confirmruledeletion.html index cf9f7d874..728c7defc 100644 --- a/src/webui/www/private/confirmruledeletion.html +++ b/src/webui/www/private/confirmruledeletion.html @@ -13,13 +13,13 @@ "use strict"; window.addEventListener("DOMContentLoaded", () => { - $("cancelBtn").focus(); - $("cancelBtn").addEventListener("click", (e) => { + document.getElementById("cancelBtn").focus(); + document.getElementById("cancelBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); window.parent.qBittorrent.Client.closeFrameWindow(window); }); - $("confirmBtn").addEventListener("click", (e) => { + document.getElementById("confirmBtn").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); diff --git a/src/webui/www/private/confirmtrackerdeletion.html b/src/webui/www/private/confirmtrackerdeletion.html index 4324f528f..46ea918e8 100644 --- a/src/webui/www/private/confirmtrackerdeletion.html +++ b/src/webui/www/private/confirmtrackerdeletion.html @@ -16,14 +16,14 @@ const searchParams = new URLSearchParams(window.location.search); const host = searchParams.get("host"); - $("confirmDeleteTrackerText").textContent = "QBT_TR(Are you sure you want to remove tracker %1 from all torrents?)QBT_TR[CONTEXT=TrackersFilterWidget]".replace("%1", host); + document.getElementById("confirmDeleteTrackerText").textContent = "QBT_TR(Are you sure you want to remove tracker %1 from all torrents?)QBT_TR[CONTEXT=TrackersFilterWidget]".replace("%1", host); - $("cancelBtn").focus(); - $("cancelBtn").addEventListener("click", (e) => { + document.getElementById("cancelBtn").focus(); + document.getElementById("cancelBtn").addEventListener("click", (e) => { e.stopPropagation(); window.parent.qBittorrent.Client.closeFrameWindow(window); }); - $("confirmBtn").addEventListener("click", (e) => { + document.getElementById("confirmBtn").addEventListener("click", (e) => { e.stopPropagation(); fetch("api/v2/torrents/removeTrackers", { diff --git a/src/webui/www/private/download.html b/src/webui/www/private/download.html index ecd1bb6bb..ca9a63b79 100644 --- a/src/webui/www/private/download.html +++ b/src/webui/www/private/download.html @@ -167,22 +167,22 @@ if (encodedUrls !== null) { const urls = encodedUrls.split("|").map(decodeURIComponent); if (urls.length > 0) - $("urls").value = urls.join("\n"); + document.getElementById("urls").value = urls.join("\n"); } let submitted = false; - $("downloadForm").addEventListener("submit", () => { - $("startTorrentHidden").value = $("startTorrent").checked ? "false" : "true"; + document.getElementById("downloadForm").addEventListener("submit", () => { + document.getElementById("startTorrentHidden").value = document.getElementById("startTorrent").checked ? "false" : "true"; - $("dlLimitHidden").value = Number($("dlLimitText").value) * 1024; - $("upLimitHidden").value = Number($("upLimitText").value) * 1024; + document.getElementById("dlLimitHidden").value = Number(document.getElementById("dlLimitText").value) * 1024; + document.getElementById("upLimitHidden").value = Number(document.getElementById("upLimitText").value) * 1024; - $("download_spinner").style.display = "block"; + document.getElementById("download_spinner").style.display = "block"; submitted = true; }); - $("download_frame").addEventListener("load", () => { + document.getElementById("download_frame").addEventListener("load", () => { if (submitted) window.parent.qBittorrent.Client.closeFrameWindow(window); }); diff --git a/src/webui/www/private/downloadlimit.html b/src/webui/www/private/downloadlimit.html index d703cf79e..3cc02ebfa 100644 --- a/src/webui/www/private/downloadlimit.html +++ b/src/webui/www/private/downloadlimit.html @@ -37,7 +37,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("applyButton").click(); + document.getElementById("applyButton").click(); break; case "Escape": event.preventDefault(); @@ -48,7 +48,7 @@ const hashes = new URLSearchParams(window.location.search).get("hashes").split("|"); const setDlLimit = () => { - const limit = Number($("dllimitUpdatevalue").value) * 1024; + const limit = Number(document.getElementById("dllimitUpdatevalue").value) * 1024; if (hashes[0] === "global") { fetch("api/v2/transfer/setDownloadLimit", { method: "POST", @@ -81,7 +81,7 @@ } }; - $("dllimitUpdatevalue").focus(); + document.getElementById("dllimitUpdatevalue").focus(); MochaUI.addDlLimitSlider(hashes); diff --git a/src/webui/www/private/editfeedurl.html b/src/webui/www/private/editfeedurl.html index 83618a0b5..c92a0b48f 100644 --- a/src/webui/www/private/editfeedurl.html +++ b/src/webui/www/private/editfeedurl.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("submitButton").click(); + document.getElementById("submitButton").click(); break; case "Escape": event.preventDefault(); @@ -30,16 +30,16 @@ const searchParams = new URLSearchParams(window.location.search); const currentUrl = searchParams.get("url"); - $("url").value = currentUrl; - $("url").focus(); - $("url").setSelectionRange(0, currentUrl.length); + document.getElementById("url").value = currentUrl; + document.getElementById("url").focus(); + document.getElementById("url").setSelectionRange(0, currentUrl.length); - $("submitButton").addEventListener("click", (e) => { + document.getElementById("submitButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const newUrl = $("url").value.trim(); + const newUrl = document.getElementById("url").value.trim(); if (newUrl === "") { alert("QBT_TR(URL cannot be empty)QBT_TR[CONTEXT=RSSWidget]"); return; @@ -50,7 +50,7 @@ return; } - $("submitButton").disabled = true; + document.getElementById("submitButton").disabled = true; fetch("api/v2/rss/setFeedURL", { method: "POST", @@ -64,7 +64,7 @@ alert((response.status === 409) ? await response.text() : "QBT_TR(Unable to update URL)QBT_TR[CONTEXT=RSSWidget]"); - $("submitButton").disabled = false; + document.getElementById("submitButton").disabled = false; return; } diff --git a/src/webui/www/private/edittracker.html b/src/webui/www/private/edittracker.html index 2b4ff2553..fd14c8217 100644 --- a/src/webui/www/private/edittracker.html +++ b/src/webui/www/private/edittracker.html @@ -17,7 +17,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("editTrackerButton").click(); + document.getElementById("editTrackerButton").click(); break; case "Escape": event.preventDefault(); @@ -31,10 +31,10 @@ if (currentUrl === null) return; - $("trackerUrl").value = currentUrl; - $("trackerUrl").focus(); + document.getElementById("trackerUrl").value = currentUrl; + document.getElementById("trackerUrl").focus(); - $("editTrackerButton").addEventListener("click", (e) => { + document.getElementById("editTrackerButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); @@ -43,7 +43,7 @@ body: new URLSearchParams({ hash: searchParams.get("hash"), origUrl: currentUrl, - newUrl: $("trackerUrl").value + newUrl: document.getElementById("trackerUrl").value }) }) .then((response) => { diff --git a/src/webui/www/private/editwebseed.html b/src/webui/www/private/editwebseed.html index ef6b70998..3b4ef53e5 100644 --- a/src/webui/www/private/editwebseed.html +++ b/src/webui/www/private/editwebseed.html @@ -17,7 +17,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("editWebSeedButton").click(); + document.getElementById("editWebSeedButton").click(); break; case "Escape": event.preventDefault(); @@ -28,10 +28,10 @@ const searchParams = new URLSearchParams(window.location.search); const origUrl = searchParams.get("url"); - $("url").value = decodeURIComponent(origUrl); - $("url").focus(); + document.getElementById("url").value = decodeURIComponent(origUrl); + document.getElementById("url").focus(); - $("editWebSeedButton").addEventListener("click", (e) => { + document.getElementById("editWebSeedButton").addEventListener("click", (e) => { e.stopPropagation(); fetch("api/v2/torrents/editWebSeed", { @@ -39,7 +39,7 @@ body: new URLSearchParams({ hash: searchParams.get("hash"), origUrl: origUrl, - newUrl: encodeURIComponent($("url").value.trim()) + newUrl: encodeURIComponent(document.getElementById("url").value.trim()) }) }) .then((response) => { diff --git a/src/webui/www/private/newcategory.html b/src/webui/www/private/newcategory.html index b2ec949fa..ceda85359 100644 --- a/src/webui/www/private/newcategory.html +++ b/src/webui/www/private/newcategory.html @@ -19,7 +19,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("categoryNameButton").click(); + document.getElementById("categoryNameButton").click(); break; case "Escape": event.preventDefault(); @@ -38,25 +38,25 @@ if (!uriCategoryName) return; - $("categoryName").disabled = true; - $("categoryName").value = window.qBittorrent.Misc.escapeHtml(uriCategoryName); - $("savePath").value = window.qBittorrent.Misc.escapeHtml(uriSavePath); - $("savePath").focus(); + document.getElementById("categoryName").disabled = true; + document.getElementById("categoryName").value = window.qBittorrent.Misc.escapeHtml(uriCategoryName); + document.getElementById("savePath").value = window.qBittorrent.Misc.escapeHtml(uriSavePath); + document.getElementById("savePath").focus(); } else if (uriAction === "createSubcategory") { - $("categoryName").value = window.qBittorrent.Misc.escapeHtml(uriCategoryName); - $("categoryName").focus(); + document.getElementById("categoryName").value = window.qBittorrent.Misc.escapeHtml(uriCategoryName); + document.getElementById("categoryName").focus(); } else { - $("categoryName").focus(); + document.getElementById("categoryName").focus(); } - $("categoryNameButton").addEventListener("click", (e) => { + document.getElementById("categoryNameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); - const savePath = $("savePath").value.trim(); - const categoryName = $("categoryName").value.trim(); + const savePath = document.getElementById("savePath").value.trim(); + const categoryName = document.getElementById("categoryName").value.trim(); const verifyCategoryName = (name) => { if ((name === null) || (name === "")) diff --git a/src/webui/www/private/newfeed.html b/src/webui/www/private/newfeed.html index b3815a63e..c126ca068 100644 --- a/src/webui/www/private/newfeed.html +++ b/src/webui/www/private/newfeed.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("submitButton").click(); + document.getElementById("submitButton").click(); break; case "Escape": event.preventDefault(); @@ -27,19 +27,19 @@ } }); - $("feedURL").focus(); - $("submitButton").addEventListener("click", (e) => { + document.getElementById("feedURL").focus(); + document.getElementById("submitButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const feedURL = $("feedURL").value.trim(); + const feedURL = document.getElementById("feedURL").value.trim(); if (feedURL === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; } - $("submitButton").disabled = true; + document.getElementById("submitButton").disabled = true; const path = new URLSearchParams(window.location.search).get("path"); fetch("api/v2/rss/addFeed", { @@ -53,7 +53,7 @@ if (!response.ok) { if (response.status === 409) alert(await response.text()); - $("submitButton").disabled = false; + document.getElementById("submitButton").disabled = false; return; } diff --git a/src/webui/www/private/newfolder.html b/src/webui/www/private/newfolder.html index 30db4c450..c567a7c55 100644 --- a/src/webui/www/private/newfolder.html +++ b/src/webui/www/private/newfolder.html @@ -19,7 +19,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("submitButton").click(); + document.getElementById("submitButton").click(); break; case "Escape": event.preventDefault(); @@ -28,19 +28,19 @@ } }); - $("folderName").focus(); - $("submitButton").addEventListener("click", (e) => { + document.getElementById("folderName").focus(); + document.getElementById("submitButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const folderName = $("folderName").value.trim(); + const folderName = document.getElementById("folderName").value.trim(); if (folderName === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; } - $("submitButton").disabled = true; + document.getElementById("submitButton").disabled = true; const path = new URLSearchParams(window.location.search).get("path"); fetch("api/v2/rss/addFolder", { @@ -53,7 +53,7 @@ if (!response.ok) { if (response.status === 409) alert(await response.text()); - $("submitButton").disabled = false; + document.getElementById("submitButton").disabled = false; return; } diff --git a/src/webui/www/private/newrule.html b/src/webui/www/private/newrule.html index 18f03a154..dc419e112 100644 --- a/src/webui/www/private/newrule.html +++ b/src/webui/www/private/newrule.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("submitButton").click(); + document.getElementById("submitButton").click(); break; case "Escape": event.preventDefault(); @@ -27,18 +27,18 @@ } }); - $("name").focus(); - $("submitButton").addEventListener("click", (e) => { + document.getElementById("name").focus(); + document.getElementById("submitButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const name = $("name").value.trim(); + const name = document.getElementById("name").value.trim(); if (name === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; } - $("submitButton").disabled = true; + document.getElementById("submitButton").disabled = true; fetch("api/v2/rss/setRule", { method: "POST", diff --git a/src/webui/www/private/newtag.html b/src/webui/www/private/newtag.html index a8067fecc..cab3b26cf 100644 --- a/src/webui/www/private/newtag.html +++ b/src/webui/www/private/newtag.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("tagNameButton").click(); + document.getElementById("tagNameButton").click(); break; case "Escape": event.preventDefault(); @@ -31,15 +31,15 @@ const uriAction = window.qBittorrent.Misc.safeTrim(searchParams.get("action")); if (uriAction === "create") - $("legendText").textContent = "QBT_TR(Tag:)QBT_TR[CONTEXT=TagFilterWidget]"; + document.getElementById("legendText").textContent = "QBT_TR(Tag:)QBT_TR[CONTEXT=TagFilterWidget]"; - $("tagName").focus(); + document.getElementById("tagName").focus(); - $("tagNameButton").addEventListener("click", (e) => { + document.getElementById("tagNameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); - const tagName = $("tagName").value.trim(); + const tagName = document.getElementById("tagName").value.trim(); const verifyTagName = (name) => { if ((name === null) || (name === "")) diff --git a/src/webui/www/private/rename.html b/src/webui/www/private/rename.html index f3f1d119f..e4debb24b 100644 --- a/src/webui/www/private/rename.html +++ b/src/webui/www/private/rename.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("renameButton").click(); + document.getElementById("renameButton").click(); break; case "Escape": event.preventDefault(); @@ -31,15 +31,15 @@ const name = searchParams.get("name"); // set text field to current value if (name !== null) - $("rename").value = name; + document.getElementById("rename").value = name; - $("rename").focus(); - $("renameButton").addEventListener("click", (e) => { + document.getElementById("rename").focus(); + document.getElementById("renameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const name = $("rename").value.trim(); + const name = document.getElementById("rename").value.trim(); if ((name === null) || (name === "")) return; diff --git a/src/webui/www/private/rename_feed.html b/src/webui/www/private/rename_feed.html index d11f41935..356ca9dd1 100644 --- a/src/webui/www/private/rename_feed.html +++ b/src/webui/www/private/rename_feed.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("renameButton").click(); + document.getElementById("renameButton").click(); break; case "Escape": event.preventDefault(); @@ -29,16 +29,16 @@ const oldPath = new URLSearchParams(window.location.search).get("oldPath"); - $("rename").value = oldPath; - $("rename").focus(); - $("rename").setSelectionRange(0, oldPath.length); + document.getElementById("rename").value = oldPath; + document.getElementById("rename").focus(); + document.getElementById("rename").setSelectionRange(0, oldPath.length); - $("renameButton").addEventListener("click", (e) => { + document.getElementById("renameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const newPath = $("rename").value.trim(); + const newPath = document.getElementById("rename").value.trim(); if (newPath === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; @@ -49,7 +49,7 @@ return; } - $("renameButton").disabled = true; + document.getElementById("renameButton").disabled = true; fetch("api/v2/rss/moveItem", { method: "POST", @@ -62,7 +62,7 @@ if (!response.ok) { if (response.status === 409) alert(await response.text()); - $("renameButton").disabled = false; + document.getElementById("renameButton").disabled = false; return; } diff --git a/src/webui/www/private/rename_file.html b/src/webui/www/private/rename_file.html index 8cddc935b..dfe5d0cdb 100644 --- a/src/webui/www/private/rename_file.html +++ b/src/webui/www/private/rename_file.html @@ -19,7 +19,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("renameButton").click(); + document.getElementById("renameButton").click(); break; case "Escape": event.preventDefault(); @@ -34,17 +34,17 @@ const isFolder = ((searchParams.get("isFolder")) === "true"); const oldName = window.qBittorrent.Filesystem.fileName(oldPath); - $("rename").value = oldName; - $("rename").focus(); + document.getElementById("rename").value = oldName; + document.getElementById("rename").focus(); if (!isFolder) - $("rename").setSelectionRange(0, oldName.lastIndexOf(".")); + document.getElementById("rename").setSelectionRange(0, oldName.lastIndexOf(".")); - $("renameButton").addEventListener("click", (e) => { + document.getElementById("renameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const newName = $("rename").value.trim(); + const newName = document.getElementById("rename").value.trim(); if (newName === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; @@ -55,7 +55,7 @@ return; } - $("renameButton").disabled = true; + document.getElementById("renameButton").disabled = true; const parentPath = window.qBittorrent.Filesystem.folderName(oldPath); const newPath = parentPath @@ -72,7 +72,7 @@ .then((response) => { if (!response.ok) { alert("QBT_TR(Failed to update name)QBT_TR[CONTEXT=HttpServer]"); - $("renameButton").disabled = false; + document.getElementById("renameButton").disabled = false; return; } diff --git a/src/webui/www/private/rename_files.html b/src/webui/www/private/rename_files.html index 37a15b3a7..55f461b6f 100644 --- a/src/webui/www/private/rename_files.html +++ b/src/webui/www/private/rename_files.html @@ -80,50 +80,50 @@ // Load Multi Rename Preferences const multiRenamePrefChecked = LocalPreferences.get("multirename_rememberPreferences", "true") === "true"; - $("multirename_rememberprefs_checkbox").checked = multiRenamePrefChecked; + document.getElementById("multirename_rememberprefs_checkbox").checked = multiRenamePrefChecked; if (multiRenamePrefChecked) { const multirename_search = LocalPreferences.get("multirename_search", ""); fileRenamer.setSearch(multirename_search); - $("multiRenameSearch").value = multirename_search; + document.getElementById("multiRenameSearch").value = multirename_search; const multirename_useRegex = LocalPreferences.get("multirename_useRegex", false); fileRenamer.useRegex = multirename_useRegex === "true"; - $("use_regex_search").checked = fileRenamer.useRegex; + document.getElementById("use_regex_search").checked = fileRenamer.useRegex; const multirename_matchAllOccurrences = LocalPreferences.get("multirename_matchAllOccurrences", false); fileRenamer.matchAllOccurrences = multirename_matchAllOccurrences === "true"; - $("match_all_occurrences").checked = fileRenamer.matchAllOccurrences; + document.getElementById("match_all_occurrences").checked = fileRenamer.matchAllOccurrences; const multirename_caseSensitive = LocalPreferences.get("multirename_caseSensitive", false); fileRenamer.caseSensitive = multirename_caseSensitive === "true"; - $("case_sensitive").checked = fileRenamer.caseSensitive; + document.getElementById("case_sensitive").checked = fileRenamer.caseSensitive; const multirename_replace = LocalPreferences.get("multirename_replace", ""); fileRenamer.setReplacement(multirename_replace); - $("multiRenameReplace").value = multirename_replace; + document.getElementById("multiRenameReplace").value = multirename_replace; const multirename_appliesTo = LocalPreferences.get("multirename_appliesTo", window.qBittorrent.MultiRename.AppliesTo.FilenameExtension); fileRenamer.appliesTo = window.qBittorrent.MultiRename.AppliesTo[multirename_appliesTo]; - $("applies_to_option").value = fileRenamer.appliesTo; + document.getElementById("applies_to_option").value = fileRenamer.appliesTo; const multirename_includeFiles = LocalPreferences.get("multirename_includeFiles", true); fileRenamer.includeFiles = multirename_includeFiles === "true"; - $("include_files").checked = fileRenamer.includeFiles; + document.getElementById("include_files").checked = fileRenamer.includeFiles; const multirename_includeFolders = LocalPreferences.get("multirename_includeFolders", false); fileRenamer.includeFolders = multirename_includeFolders === "true"; - $("include_folders").checked = fileRenamer.includeFolders; + document.getElementById("include_folders").checked = fileRenamer.includeFolders; const multirename_fileEnumerationStart = LocalPreferences.get("multirename_fileEnumerationStart", 0); fileRenamer.fileEnumerationStart = Number(multirename_fileEnumerationStart); - $("file_counter").value = fileRenamer.fileEnumerationStart; + document.getElementById("file_counter").value = fileRenamer.fileEnumerationStart; const multirename_replaceAll = LocalPreferences.get("multirename_replaceAll", false); fileRenamer.replaceAll = multirename_replaceAll === "true"; const renameButtonValue = fileRenamer.replaceAll ? "Replace All" : "Replace"; - $("renameOptions").value = renameButtonValue; - $("renameButton").value = renameButtonValue; + document.getElementById("renameOptions").value = renameButtonValue; + document.getElementById("renameButton").value = renameButtonValue; } // Fires every time a row's selection changes @@ -133,26 +133,26 @@ }; // Setup Search Events that control renaming - $("multiRenameSearch").addEventListener("input", (e) => { + document.getElementById("multiRenameSearch").addEventListener("input", (e) => { const sanitized = e.target.value.replace(/\n/g, ""); - $("multiRenameSearch").value = sanitized; + document.getElementById("multiRenameSearch").value = sanitized; // Search input has changed - $("multiRenameSearch").style["border-color"] = ""; + document.getElementById("multiRenameSearch").style["border-color"] = ""; LocalPreferences.set("multirename_search", sanitized); fileRenamer.setSearch(sanitized); }); - $("use_regex_search").addEventListener("change", (e) => { + document.getElementById("use_regex_search").addEventListener("change", (e) => { fileRenamer.useRegex = e.target.checked; LocalPreferences.set("multirename_useRegex", e.target.checked); fileRenamer.update(); }); - $("match_all_occurrences").addEventListener("change", (e) => { + document.getElementById("match_all_occurrences").addEventListener("change", (e) => { fileRenamer.matchAllOccurrences = e.target.checked; LocalPreferences.set("multirename_matchAllOccurrences", e.target.checked); fileRenamer.update(); }); - $("case_sensitive").addEventListener("change", (e) => { + document.getElementById("case_sensitive").addEventListener("change", (e) => { fileRenamer.caseSensitive = e.target.checked; LocalPreferences.set("multirename_caseSensitive", e.target.checked); fileRenamer.update(); @@ -179,35 +179,35 @@ } }; fileRenamer.onInvalidRegex = (err) => { - $("multiRenameSearch").style["border-color"] = "#CC0033"; + document.getElementById("multiRenameSearch").style["border-color"] = "#CC0033"; }; // Setup Replace Events that control renaming - $("multiRenameReplace").addEventListener("input", (e) => { + document.getElementById("multiRenameReplace").addEventListener("input", (e) => { const sanitized = e.target.value.replace(/\n/g, ""); - $("multiRenameReplace").value = sanitized; + document.getElementById("multiRenameReplace").value = sanitized; // Replace input has changed - $("multiRenameReplace").style["border-color"] = ""; + document.getElementById("multiRenameReplace").style["border-color"] = ""; LocalPreferences.set("multirename_replace", sanitized); fileRenamer.setReplacement(sanitized); }); - $("applies_to_option").addEventListener("change", (e) => { + document.getElementById("applies_to_option").addEventListener("change", (e) => { fileRenamer.appliesTo = e.target.value; LocalPreferences.set("multirename_appliesTo", e.target.value); fileRenamer.update(); }); - $("include_files").addEventListener("change", (e) => { + document.getElementById("include_files").addEventListener("change", (e) => { fileRenamer.includeFiles = e.target.checked; LocalPreferences.set("multirename_includeFiles", e.target.checked); fileRenamer.update(); }); - $("include_folders").addEventListener("change", (e) => { + document.getElementById("include_folders").addEventListener("change", (e) => { fileRenamer.includeFolders = e.target.checked; LocalPreferences.set("multirename_includeFolders", e.target.checked); fileRenamer.update(); }); - $("file_counter").addEventListener("input", (e) => { + document.getElementById("file_counter").addEventListener("input", (e) => { let value = e.target.valueAsNumber; if (!value) value = 0; @@ -216,46 +216,46 @@ if (value > 99999999) value = 99999999; fileRenamer.fileEnumerationStart = value; - $("file_counter").value = value; + document.getElementById("file_counter").value = value; LocalPreferences.set("multirename_fileEnumerationStart", value); fileRenamer.update(); }); // Setup Rename Operation Events - $("renameButton").addEventListener("click", (e) => { + document.getElementById("renameButton").addEventListener("click", (e) => { // Disable Search Options - $("multiRenameSearch").disabled = true; - $("use_regex_search").disabled = true; - $("match_all_occurrences").disabled = true; - $("case_sensitive").disabled = true; + document.getElementById("multiRenameSearch").disabled = true; + document.getElementById("use_regex_search").disabled = true; + document.getElementById("match_all_occurrences").disabled = true; + document.getElementById("case_sensitive").disabled = true; // Disable Replace Options - $("multiRenameReplace").disabled = true; - $("applies_to_option").disabled = true; - $("include_files").disabled = true; - $("include_folders").disabled = true; - $("file_counter").disabled = true; + document.getElementById("multiRenameReplace").disabled = true; + document.getElementById("applies_to_option").disabled = true; + document.getElementById("include_files").disabled = true; + document.getElementById("include_folders").disabled = true; + document.getElementById("file_counter").disabled = true; // Disable Rename Buttons - $("renameButton").disabled = true; - $("renameOptions").disabled = true; + document.getElementById("renameButton").disabled = true; + document.getElementById("renameOptions").disabled = true; // Clear error text - $("rename_error").textContent = ""; + document.getElementById("rename_error").textContent = ""; fileRenamer.rename(); }); fileRenamer.onRenamed = (rows) => { // Disable Search Options - $("multiRenameSearch").disabled = false; - $("use_regex_search").disabled = false; - $("match_all_occurrences").disabled = false; - $("case_sensitive").disabled = false; + document.getElementById("multiRenameSearch").disabled = false; + document.getElementById("use_regex_search").disabled = false; + document.getElementById("match_all_occurrences").disabled = false; + document.getElementById("case_sensitive").disabled = false; // Disable Replace Options - $("multiRenameReplace").disabled = false; - $("applies_to_option").disabled = false; - $("include_files").disabled = false; - $("include_folders").disabled = false; - $("file_counter").disabled = false; + document.getElementById("multiRenameReplace").disabled = false; + document.getElementById("applies_to_option").disabled = false; + document.getElementById("include_files").disabled = false; + document.getElementById("include_folders").disabled = false; + document.getElementById("file_counter").disabled = false; // Disable Rename Buttons - $("renameButton").disabled = false; - $("renameOptions").disabled = false; + document.getElementById("renameButton").disabled = false; + document.getElementById("renameOptions").disabled = false; // Recreate table let selectedRows = bulkRenameFilesTable.getSelectedRows().map(row => row.rowId.toString()); @@ -266,15 +266,15 @@ // Adjust file enumeration count by 1 when replacing single files to prevent naming conflicts if (!fileRenamer.replaceAll) { fileRenamer.fileEnumerationStart++; - $("file_counter").value = fileRenamer.fileEnumerationStart; + document.getElementById("file_counter").value = fileRenamer.fileEnumerationStart; } setupTable(selectedRows); }; fileRenamer.onRenameError = (response, row) => { if (response.status === 409) - $("rename_error").textContent = `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``; + document.getElementById("rename_error").textContent = `QBT_TR(Rename failed: file or folder already exists)QBT_TR[CONTEXT=PropertiesWidget] \`${row.renamed}\``; }; - $("renameOptions").addEventListener("change", (e) => { + document.getElementById("renameOptions").addEventListener("change", (e) => { const combobox = e.target; const replaceOperation = combobox.value; if (replaceOperation === "Replace") @@ -284,9 +284,9 @@ else fileRenamer.replaceAll = false; LocalPreferences.set("multirename_replaceAll", fileRenamer.replaceAll); - $("renameButton").value = replaceOperation; + document.getElementById("renameButton").value = replaceOperation; }); - $("closeButton").addEventListener("click", (event) => { + document.getElementById("closeButton").addEventListener("click", (event) => { event.preventDefault(); window.qBittorrent.Client.closeWindow(windowEl); }); diff --git a/src/webui/www/private/rename_rule.html b/src/webui/www/private/rename_rule.html index dc0c39b75..c67d81026 100644 --- a/src/webui/www/private/rename_rule.html +++ b/src/webui/www/private/rename_rule.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("renameButton").click(); + document.getElementById("renameButton").click(); break; case "Escape": event.preventDefault(); @@ -29,16 +29,16 @@ const oldName = new URLSearchParams(window.location.search).get("rule"); - $("rename").value = oldName; - $("rename").focus(); - $("rename").setSelectionRange(0, oldName.length); + document.getElementById("rename").value = oldName; + document.getElementById("rename").focus(); + document.getElementById("rename").setSelectionRange(0, oldName.length); - $("renameButton").addEventListener("click", (e) => { + document.getElementById("renameButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const newName = $("rename").value.trim(); + const newName = document.getElementById("rename").value.trim(); if (newName === "") { alert("QBT_TR(Name cannot be empty)QBT_TR[CONTEXT=HttpServer]"); return; @@ -49,7 +49,7 @@ return; } - $("renameButton").disabled = true; + document.getElementById("renameButton").disabled = true; fetch("api/v2/rss/renameRule", { method: "POST", diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 15e7af365..382b09a26 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -180,15 +180,15 @@ window.addEventListener("DOMContentLoaded", () => { let isRssPanelLoaded = false; const saveColumnSizes = () => { - const filters_width = $("Filters").getSize().x; + const filters_width = document.getElementById("Filters").getSize().x; LocalPreferences.set("filters_width", filters_width); - const properties_height_rel = $("propertiesPanel").getSize().y / Window.getSize().y; + const properties_height_rel = document.getElementById("propertiesPanel").getSize().y / Window.getSize().y; LocalPreferences.set("properties_height_rel", properties_height_rel); }; window.addEventListener("resize", window.qBittorrent.Misc.createDebounceHandler(500, (e) => { // only save sizes if the columns are visible - if (!$("mainColumn").classList.contains("invisible")) + if (!document.getElementById("mainColumn").classList.contains("invisible")) saveColumnSizes(); })); @@ -221,7 +221,7 @@ window.addEventListener("DOMContentLoaded", () => { }); // start off hidden - $("searchTabColumn").classList.add("invisible"); + document.getElementById("searchTabColumn").classList.add("invisible"); }; const buildRssTab = () => { @@ -232,7 +232,7 @@ window.addEventListener("DOMContentLoaded", () => { }); // start off hidden - $("rssTabColumn").classList.add("invisible"); + document.getElementById("rssTabColumn").classList.add("invisible"); }; const buildLogTab = () => { @@ -243,7 +243,7 @@ window.addEventListener("DOMContentLoaded", () => { }); // start off hidden - $("logTabColumn").classList.add("invisible"); + document.getElementById("logTabColumn").classList.add("invisible"); }; buildTransfersTab(); @@ -342,28 +342,28 @@ window.addEventListener("DOMContentLoaded", () => { // Show Top Toolbar is enabled by default let showTopToolbar = LocalPreferences.get("show_top_toolbar", "true") === "true"; if (!showTopToolbar) { - $("showTopToolbarLink").firstElementChild.style.opacity = "0"; - $("mochaToolbar").classList.add("invisible"); + document.getElementById("showTopToolbarLink").firstElementChild.style.opacity = "0"; + document.getElementById("mochaToolbar").classList.add("invisible"); } // Show Status Bar is enabled by default let showStatusBar = LocalPreferences.get("show_status_bar", "true") === "true"; if (!showStatusBar) { - $("showStatusBarLink").firstElementChild.style.opacity = "0"; - $("desktopFooterWrapper").classList.add("invisible"); + document.getElementById("showStatusBarLink").firstElementChild.style.opacity = "0"; + document.getElementById("desktopFooterWrapper").classList.add("invisible"); } // Show Filters Sidebar is enabled by default let showFiltersSidebar = LocalPreferences.get("show_filters_sidebar", "true") === "true"; if (!showFiltersSidebar) { - $("showFiltersSidebarLink").firstElementChild.style.opacity = "0"; - $("filtersColumn").classList.add("invisible"); - $("filtersColumn_handle").classList.add("invisible"); + document.getElementById("showFiltersSidebarLink").firstElementChild.style.opacity = "0"; + document.getElementById("filtersColumn").classList.add("invisible"); + document.getElementById("filtersColumn_handle").classList.add("invisible"); } let speedInTitle = LocalPreferences.get("speed_in_browser_title_bar") === "true"; if (!speedInTitle) - $("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "0"; + document.getElementById("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "0"; // After showing/hiding the toolbar + status bar window.qBittorrent.Client.showSearchEngine(LocalPreferences.get("show_search_engine") !== "false"); @@ -614,7 +614,7 @@ window.addEventListener("DOMContentLoaded", () => { }; const updateTagList = () => { - const tagFilterList = $("tagFilterList"); + const tagFilterList = document.getElementById("tagFilterList"); if (tagFilterList === null) return; @@ -667,7 +667,7 @@ window.addEventListener("DOMContentLoaded", () => { }; const updateTrackerList = () => { - const trackerFilterList = $("trackerFilterList"); + const trackerFilterList = document.getElementById("trackerFilterList"); if (trackerFilterList === null) return; @@ -763,7 +763,7 @@ window.addEventListener("DOMContentLoaded", () => { }) .then(async (response) => { if (response.ok) { - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; const responseJSON = await response.json(); @@ -933,7 +933,7 @@ window.addEventListener("DOMContentLoaded", () => { syncData(window.qBittorrent.Client.getSyncMainDataInterval()); }, (error) => { - const errorDiv = $("error_div"); + const errorDiv = document.getElementById("error_div"); if (errorDiv) errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; syncRequestInProgress = false; @@ -964,12 +964,12 @@ window.addEventListener("DOMContentLoaded", () => { if (serverState.dl_rate_limit > 0) transfer_info += ` [${window.qBittorrent.Misc.friendlyUnit(serverState.dl_rate_limit, true)}]`; transfer_info += ` (${window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_data, false)})`; - $("DlInfos").textContent = transfer_info; + document.getElementById("DlInfos").textContent = transfer_info; transfer_info = window.qBittorrent.Misc.friendlyUnit(serverState.up_info_speed, true); if (serverState.up_rate_limit > 0) transfer_info += ` [${window.qBittorrent.Misc.friendlyUnit(serverState.up_rate_limit, true)}]`; transfer_info += ` (${window.qBittorrent.Misc.friendlyUnit(serverState.up_info_data, false)})`; - $("UpInfos").textContent = transfer_info; + document.getElementById("UpInfos").textContent = transfer_info; document.title = (speedInTitle ? (`QBT_TR([D: %1, U: %2])QBT_TR[CONTEXT=MainWindow] ` @@ -978,7 +978,7 @@ window.addEventListener("DOMContentLoaded", () => { : "") + window.qBittorrent.Client.mainTitle(); - $("freeSpaceOnDisk").textContent = "QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]".replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.free_space_on_disk)); + document.getElementById("freeSpaceOnDisk").textContent = "QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]".replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.free_space_on_disk)); const externalIPsElement = document.getElementById("externalIPs"); if (window.qBittorrent.Cache.preferences.get().status_bar_external_ip) { @@ -1015,35 +1015,35 @@ window.addEventListener("DOMContentLoaded", () => { // Statistics dialog if (document.getElementById("statisticsContent")) { - $("AlltimeDL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_dl, false); - $("AlltimeUL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_ul, false); - $("TotalWastedSession").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_wasted_session, false); - $("GlobalRatio").textContent = serverState.global_ratio; - $("TotalPeerConnections").textContent = serverState.total_peer_connections; - $("ReadCacheHits").textContent = `${serverState.read_cache_hits}%`; - $("TotalBuffersSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_buffers_size, false); - $("WriteCacheOverload").textContent = `${serverState.write_cache_overload}%`; - $("ReadCacheOverload").textContent = `${serverState.read_cache_overload}%`; - $("QueuedIOJobs").textContent = serverState.queued_io_jobs; - $("AverageTimeInQueue").textContent = `${serverState.average_time_queue} ms`; - $("TotalQueuedSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_queued_size, false); + document.getElementById("AlltimeDL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_dl, false); + document.getElementById("AlltimeUL").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.alltime_ul, false); + document.getElementById("TotalWastedSession").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_wasted_session, false); + document.getElementById("GlobalRatio").textContent = serverState.global_ratio; + document.getElementById("TotalPeerConnections").textContent = serverState.total_peer_connections; + document.getElementById("ReadCacheHits").textContent = `${serverState.read_cache_hits}%`; + document.getElementById("TotalBuffersSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_buffers_size, false); + document.getElementById("WriteCacheOverload").textContent = `${serverState.write_cache_overload}%`; + document.getElementById("ReadCacheOverload").textContent = `${serverState.read_cache_overload}%`; + document.getElementById("QueuedIOJobs").textContent = serverState.queued_io_jobs; + document.getElementById("AverageTimeInQueue").textContent = `${serverState.average_time_queue} ms`; + document.getElementById("TotalQueuedSize").textContent = window.qBittorrent.Misc.friendlyUnit(serverState.total_queued_size, false); } switch (serverState.connection_status) { case "connected": - $("connectionStatus").src = "images/connected.svg"; - $("connectionStatus").alt = "QBT_TR(Connection status: Connected)QBT_TR[CONTEXT=MainWindow]"; - $("connectionStatus").title = "QBT_TR(Connection status: Connected)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").src = "images/connected.svg"; + document.getElementById("connectionStatus").alt = "QBT_TR(Connection status: Connected)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").title = "QBT_TR(Connection status: Connected)QBT_TR[CONTEXT=MainWindow]"; break; case "firewalled": - $("connectionStatus").src = "images/firewalled.svg"; - $("connectionStatus").alt = "QBT_TR(Connection status: Firewalled)QBT_TR[CONTEXT=MainWindow]"; - $("connectionStatus").title = "QBT_TR(Connection status: Firewalled)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").src = "images/firewalled.svg"; + document.getElementById("connectionStatus").alt = "QBT_TR(Connection status: Firewalled)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").title = "QBT_TR(Connection status: Firewalled)QBT_TR[CONTEXT=MainWindow]"; break; default: - $("connectionStatus").src = "images/disconnected.svg"; - $("connectionStatus").alt = "QBT_TR(Connection status: Disconnected)QBT_TR[CONTEXT=MainWindow]"; - $("connectionStatus").title = "QBT_TR(Connection status: Disconnected)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").src = "images/disconnected.svg"; + document.getElementById("connectionStatus").alt = "QBT_TR(Connection status: Disconnected)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("connectionStatus").title = "QBT_TR(Connection status: Disconnected)QBT_TR[CONTEXT=MainWindow]"; break; } @@ -1052,20 +1052,20 @@ window.addEventListener("DOMContentLoaded", () => { torrentsTable.columns["priority"].force_hide = !queueing_enabled; torrentsTable.updateColumn("priority"); if (queueing_enabled) { - $("topQueuePosItem").classList.remove("invisible"); - $("increaseQueuePosItem").classList.remove("invisible"); - $("decreaseQueuePosItem").classList.remove("invisible"); - $("bottomQueuePosItem").classList.remove("invisible"); - $("queueingButtons").classList.remove("invisible"); - $("queueingMenuItems").classList.remove("invisible"); + document.getElementById("topQueuePosItem").classList.remove("invisible"); + document.getElementById("increaseQueuePosItem").classList.remove("invisible"); + document.getElementById("decreaseQueuePosItem").classList.remove("invisible"); + document.getElementById("bottomQueuePosItem").classList.remove("invisible"); + document.getElementById("queueingButtons").classList.remove("invisible"); + document.getElementById("queueingMenuItems").classList.remove("invisible"); } else { - $("topQueuePosItem").classList.add("invisible"); - $("increaseQueuePosItem").classList.add("invisible"); - $("decreaseQueuePosItem").classList.add("invisible"); - $("bottomQueuePosItem").classList.add("invisible"); - $("queueingButtons").classList.add("invisible"); - $("queueingMenuItems").classList.add("invisible"); + document.getElementById("topQueuePosItem").classList.add("invisible"); + document.getElementById("increaseQueuePosItem").classList.add("invisible"); + document.getElementById("decreaseQueuePosItem").classList.add("invisible"); + document.getElementById("bottomQueuePosItem").classList.add("invisible"); + document.getElementById("queueingButtons").classList.add("invisible"); + document.getElementById("queueingMenuItems").classList.add("invisible"); } } @@ -1084,18 +1084,18 @@ window.addEventListener("DOMContentLoaded", () => { const updateAltSpeedIcon = (enabled) => { if (enabled) { - $("alternativeSpeedLimits").src = "images/slow.svg"; - $("alternativeSpeedLimits").alt = "QBT_TR(Alternative speed limits: On)QBT_TR[CONTEXT=MainWindow]"; - $("alternativeSpeedLimits").title = "QBT_TR(Alternative speed limits: On)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("alternativeSpeedLimits").src = "images/slow.svg"; + document.getElementById("alternativeSpeedLimits").alt = "QBT_TR(Alternative speed limits: On)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("alternativeSpeedLimits").title = "QBT_TR(Alternative speed limits: On)QBT_TR[CONTEXT=MainWindow]"; } else { - $("alternativeSpeedLimits").src = "images/slow_off.svg"; - $("alternativeSpeedLimits").alt = "QBT_TR(Alternative speed limits: Off)QBT_TR[CONTEXT=MainWindow]"; - $("alternativeSpeedLimits").title = "QBT_TR(Alternative speed limits: Off)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("alternativeSpeedLimits").src = "images/slow_off.svg"; + document.getElementById("alternativeSpeedLimits").alt = "QBT_TR(Alternative speed limits: Off)QBT_TR[CONTEXT=MainWindow]"; + document.getElementById("alternativeSpeedLimits").title = "QBT_TR(Alternative speed limits: Off)QBT_TR[CONTEXT=MainWindow]"; } }; - $("alternativeSpeedLimits").addEventListener("click", () => { + document.getElementById("alternativeSpeedLimits").addEventListener("click", () => { // Change icon immediately to give some feedback updateAltSpeedIcon(!alternativeSpeedLimits); @@ -1114,33 +1114,33 @@ window.addEventListener("DOMContentLoaded", () => { }); }); - $("DlInfos").addEventListener("click", () => { globalDownloadLimitFN(); }); - $("UpInfos").addEventListener("click", () => { globalUploadLimitFN(); }); + document.getElementById("DlInfos").addEventListener("click", () => { globalDownloadLimitFN(); }); + document.getElementById("UpInfos").addEventListener("click", () => { globalUploadLimitFN(); }); - $("showTopToolbarLink").addEventListener("click", (e) => { + document.getElementById("showTopToolbarLink").addEventListener("click", (e) => { showTopToolbar = !showTopToolbar; LocalPreferences.set("show_top_toolbar", showTopToolbar.toString()); if (showTopToolbar) { - $("showTopToolbarLink").firstElementChild.style.opacity = "1"; - $("mochaToolbar").classList.remove("invisible"); + document.getElementById("showTopToolbarLink").firstElementChild.style.opacity = "1"; + document.getElementById("mochaToolbar").classList.remove("invisible"); } else { - $("showTopToolbarLink").firstElementChild.style.opacity = "0"; - $("mochaToolbar").classList.add("invisible"); + document.getElementById("showTopToolbarLink").firstElementChild.style.opacity = "0"; + document.getElementById("mochaToolbar").classList.add("invisible"); } MochaUI.Desktop.setDesktopSize(); }); - $("showStatusBarLink").addEventListener("click", (e) => { + document.getElementById("showStatusBarLink").addEventListener("click", (e) => { showStatusBar = !showStatusBar; LocalPreferences.set("show_status_bar", showStatusBar.toString()); if (showStatusBar) { - $("showStatusBarLink").firstElementChild.style.opacity = "1"; - $("desktopFooterWrapper").classList.remove("invisible"); + document.getElementById("showStatusBarLink").firstElementChild.style.opacity = "1"; + document.getElementById("desktopFooterWrapper").classList.remove("invisible"); } else { - $("showStatusBarLink").firstElementChild.style.opacity = "0"; - $("desktopFooterWrapper").classList.add("invisible"); + document.getElementById("showStatusBarLink").firstElementChild.style.opacity = "0"; + document.getElementById("desktopFooterWrapper").classList.add("invisible"); } MochaUI.Desktop.setDesktopSize(); }); @@ -1164,49 +1164,49 @@ window.addEventListener("DOMContentLoaded", () => { navigator.registerProtocolHandler("magnet", templateUrl, "qBittorrent WebUI magnet handler"); }; - $("registerMagnetHandlerLink").addEventListener("click", (e) => { + document.getElementById("registerMagnetHandlerLink").addEventListener("click", (e) => { registerMagnetHandler(); }); - $("showFiltersSidebarLink").addEventListener("click", (e) => { + document.getElementById("showFiltersSidebarLink").addEventListener("click", (e) => { showFiltersSidebar = !showFiltersSidebar; LocalPreferences.set("show_filters_sidebar", showFiltersSidebar.toString()); if (showFiltersSidebar) { - $("showFiltersSidebarLink").firstElementChild.style.opacity = "1"; - $("filtersColumn").classList.remove("invisible"); - $("filtersColumn_handle").classList.remove("invisible"); + document.getElementById("showFiltersSidebarLink").firstElementChild.style.opacity = "1"; + document.getElementById("filtersColumn").classList.remove("invisible"); + document.getElementById("filtersColumn_handle").classList.remove("invisible"); } else { - $("showFiltersSidebarLink").firstElementChild.style.opacity = "0"; - $("filtersColumn").classList.add("invisible"); - $("filtersColumn_handle").classList.add("invisible"); + document.getElementById("showFiltersSidebarLink").firstElementChild.style.opacity = "0"; + document.getElementById("filtersColumn").classList.add("invisible"); + document.getElementById("filtersColumn_handle").classList.add("invisible"); } MochaUI.Desktop.setDesktopSize(); }); - $("speedInBrowserTitleBarLink").addEventListener("click", (e) => { + document.getElementById("speedInBrowserTitleBarLink").addEventListener("click", (e) => { speedInTitle = !speedInTitle; LocalPreferences.set("speed_in_browser_title_bar", speedInTitle.toString()); if (speedInTitle) - $("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "1"; + document.getElementById("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "1"; else - $("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "0"; + document.getElementById("speedInBrowserTitleBarLink").firstElementChild.style.opacity = "0"; processServerState(); }); - $("showSearchEngineLink").addEventListener("click", (e) => { + document.getElementById("showSearchEngineLink").addEventListener("click", (e) => { window.qBittorrent.Client.showSearchEngine(!window.qBittorrent.Client.isShowSearchEngine()); LocalPreferences.set("show_search_engine", window.qBittorrent.Client.isShowSearchEngine().toString()); updateTabDisplay(); }); - $("showRssReaderLink").addEventListener("click", (e) => { + document.getElementById("showRssReaderLink").addEventListener("click", (e) => { window.qBittorrent.Client.showRssReader(!window.qBittorrent.Client.isShowRssReader()); LocalPreferences.set("show_rss_reader", window.qBittorrent.Client.isShowRssReader().toString()); updateTabDisplay(); }); - $("showLogViewerLink").addEventListener("click", (e) => { + document.getElementById("showLogViewerLink").addEventListener("click", (e) => { window.qBittorrent.Client.showLogViewer(!window.qBittorrent.Client.isShowLogViewer()); LocalPreferences.set("show_log_viewer", window.qBittorrent.Client.isShowLogViewer().toString()); updateTabDisplay(); @@ -1214,64 +1214,64 @@ window.addEventListener("DOMContentLoaded", () => { const updateTabDisplay = () => { if (window.qBittorrent.Client.isShowRssReader()) { - $("showRssReaderLink").firstElementChild.style.opacity = "1"; - $("mainWindowTabs").classList.remove("invisible"); - $("rssTabLink").classList.remove("invisible"); + document.getElementById("showRssReaderLink").firstElementChild.style.opacity = "1"; + document.getElementById("mainWindowTabs").classList.remove("invisible"); + document.getElementById("rssTabLink").classList.remove("invisible"); if (!MochaUI.Panels.instances.RssPanel) addRssPanel(); } else { - $("showRssReaderLink").firstElementChild.style.opacity = "0"; - $("rssTabLink").classList.add("invisible"); - if ($("rssTabLink").classList.contains("selected")) - $("transfersTabLink").click(); + document.getElementById("showRssReaderLink").firstElementChild.style.opacity = "0"; + document.getElementById("rssTabLink").classList.add("invisible"); + if (document.getElementById("rssTabLink").classList.contains("selected")) + document.getElementById("transfersTabLink").click(); } if (window.qBittorrent.Client.isShowSearchEngine()) { - $("showSearchEngineLink").firstElementChild.style.opacity = "1"; - $("mainWindowTabs").classList.remove("invisible"); - $("searchTabLink").classList.remove("invisible"); + document.getElementById("showSearchEngineLink").firstElementChild.style.opacity = "1"; + document.getElementById("mainWindowTabs").classList.remove("invisible"); + document.getElementById("searchTabLink").classList.remove("invisible"); if (!MochaUI.Panels.instances.SearchPanel) addSearchPanel(); } else { - $("showSearchEngineLink").firstElementChild.style.opacity = "0"; - $("searchTabLink").classList.add("invisible"); - if ($("searchTabLink").classList.contains("selected")) - $("transfersTabLink").click(); + document.getElementById("showSearchEngineLink").firstElementChild.style.opacity = "0"; + document.getElementById("searchTabLink").classList.add("invisible"); + if (document.getElementById("searchTabLink").classList.contains("selected")) + document.getElementById("transfersTabLink").click(); } if (window.qBittorrent.Client.isShowLogViewer()) { - $("showLogViewerLink").firstElementChild.style.opacity = "1"; - $("mainWindowTabs").classList.remove("invisible"); - $("logTabLink").classList.remove("invisible"); + document.getElementById("showLogViewerLink").firstElementChild.style.opacity = "1"; + document.getElementById("mainWindowTabs").classList.remove("invisible"); + document.getElementById("logTabLink").classList.remove("invisible"); if (!MochaUI.Panels.instances.LogPanel) addLogPanel(); } else { - $("showLogViewerLink").firstElementChild.style.opacity = "0"; - $("logTabLink").classList.add("invisible"); - if ($("logTabLink").classList.contains("selected")) - $("transfersTabLink").click(); + document.getElementById("showLogViewerLink").firstElementChild.style.opacity = "0"; + document.getElementById("logTabLink").classList.add("invisible"); + if (document.getElementById("logTabLink").classList.contains("selected")) + document.getElementById("transfersTabLink").click(); } // display no tabs if (!window.qBittorrent.Client.isShowRssReader() && !window.qBittorrent.Client.isShowSearchEngine() && !window.qBittorrent.Client.isShowLogViewer()) - $("mainWindowTabs").classList.add("invisible"); + document.getElementById("mainWindowTabs").classList.add("invisible"); }; - $("StatisticsLink").addEventListener("click", () => { StatisticsLinkFN(); }); + document.getElementById("StatisticsLink").addEventListener("click", () => { StatisticsLinkFN(); }); // main window tabs const showTransfersTab = () => { const showFiltersSidebar = LocalPreferences.get("show_filters_sidebar", "true") === "true"; if (showFiltersSidebar) { - $("filtersColumn").classList.remove("invisible"); - $("filtersColumn_handle").classList.remove("invisible"); + document.getElementById("filtersColumn").classList.remove("invisible"); + document.getElementById("filtersColumn_handle").classList.remove("invisible"); } - $("mainColumn").classList.remove("invisible"); - $("torrentsFilterToolbar").classList.remove("invisible"); + document.getElementById("mainColumn").classList.remove("invisible"); + document.getElementById("torrentsFilterToolbar").classList.remove("invisible"); customSyncMainDataInterval = null; syncData(100); @@ -1284,10 +1284,10 @@ window.addEventListener("DOMContentLoaded", () => { }; const hideTransfersTab = () => { - $("filtersColumn").classList.add("invisible"); - $("filtersColumn_handle").classList.add("invisible"); - $("mainColumn").classList.add("invisible"); - $("torrentsFilterToolbar").classList.add("invisible"); + document.getElementById("filtersColumn").classList.add("invisible"); + document.getElementById("filtersColumn_handle").classList.add("invisible"); + document.getElementById("mainColumn").classList.add("invisible"); + document.getElementById("torrentsFilterToolbar").classList.add("invisible"); MochaUI.Desktop.resizePanels(); }; @@ -1310,7 +1310,7 @@ window.addEventListener("DOMContentLoaded", () => { searchTabInitialized = true; } - $("searchTabColumn").classList.remove("invisible"); + document.getElementById("searchTabColumn").classList.remove("invisible"); customSyncMainDataInterval = 30000; hideTransfersTab(); hideRssTab(); @@ -1321,7 +1321,7 @@ window.addEventListener("DOMContentLoaded", () => { })(); const hideSearchTab = () => { - $("searchTabColumn").classList.add("invisible"); + document.getElementById("searchTabColumn").classList.add("invisible"); MochaUI.Desktop.resizePanels(); }; @@ -1347,7 +1347,7 @@ window.addEventListener("DOMContentLoaded", () => { window.qBittorrent.Rss.load(); } - $("rssTabColumn").classList.remove("invisible"); + document.getElementById("rssTabColumn").classList.remove("invisible"); customSyncMainDataInterval = 30000; hideTransfersTab(); hideSearchTab(); @@ -1358,7 +1358,7 @@ window.addEventListener("DOMContentLoaded", () => { })(); const hideRssTab = () => { - $("rssTabColumn").classList.add("invisible"); + document.getElementById("rssTabColumn").classList.add("invisible"); window.qBittorrent.Rss && window.qBittorrent.Rss.unload(); MochaUI.Desktop.resizePanels(); }; @@ -1385,7 +1385,7 @@ window.addEventListener("DOMContentLoaded", () => { window.qBittorrent.Log.load(); } - $("logTabColumn").classList.remove("invisible"); + document.getElementById("logTabColumn").classList.remove("invisible"); customSyncMainDataInterval = 30000; hideTransfersTab(); hideSearchTab(); @@ -1396,7 +1396,7 @@ window.addEventListener("DOMContentLoaded", () => { })(); const hideLogTab = () => { - $("logTabColumn").classList.add("invisible"); + document.getElementById("logTabColumn").classList.add("invisible"); MochaUI.Desktop.resizePanels(); window.qBittorrent.Log && window.qBittorrent.Log.unload(); }; @@ -1472,11 +1472,11 @@ window.addEventListener("DOMContentLoaded", () => { tabsOnload: () => { MochaUI.initializeTabs("panelTabs"); - $("logMessageLink").addEventListener("click", (e) => { + document.getElementById("logMessageLink").addEventListener("click", (e) => { window.qBittorrent.Log.setCurrentTab("main"); }); - $("logPeerLink").addEventListener("click", (e) => { + document.getElementById("logPeerLink").addEventListener("click", (e) => { window.qBittorrent.Log.setCurrentTab("peer"); }); }, @@ -1618,7 +1618,7 @@ window.addEventListener("DOMContentLoaded", () => { // listen for changes to torrentsFilterInput let torrentsFilterInputTimer = -1; - $("torrentsFilterInput").addEventListener("input", () => { + document.getElementById("torrentsFilterInput").addEventListener("input", () => { clearTimeout(torrentsFilterInputTimer); torrentsFilterInputTimer = setTimeout(() => { torrentsFilterInputTimer = -1; @@ -1628,24 +1628,24 @@ window.addEventListener("DOMContentLoaded", () => { document.getElementById("torrentsFilterToolbar").addEventListener("change", (e) => { torrentsTable.updateTable(); }); - $("transfersTabLink").addEventListener("click", () => { showTransfersTab(); }); - $("searchTabLink").addEventListener("click", () => { showSearchTab(); }); - $("rssTabLink").addEventListener("click", () => { showRssTab(); }); - $("logTabLink").addEventListener("click", () => { showLogTab(); }); + document.getElementById("transfersTabLink").addEventListener("click", () => { showTransfersTab(); }); + document.getElementById("searchTabLink").addEventListener("click", () => { showSearchTab(); }); + document.getElementById("rssTabLink").addEventListener("click", () => { showRssTab(); }); + document.getElementById("logTabLink").addEventListener("click", () => { showLogTab(); }); updateTabDisplay(); const registerDragAndDrop = () => { - $("desktop").addEventListener("dragover", (ev) => { + document.getElementById("desktop").addEventListener("dragover", (ev) => { if (ev.preventDefault) ev.preventDefault(); }); - $("desktop").addEventListener("dragenter", (ev) => { + document.getElementById("desktop").addEventListener("dragenter", (ev) => { if (ev.preventDefault) ev.preventDefault(); }); - $("desktop").addEventListener("drop", (ev) => { + document.getElementById("desktop").addEventListener("drop", (ev) => { if (ev.preventDefault) ev.preventDefault(); @@ -1679,7 +1679,7 @@ window.addEventListener("DOMContentLoaded", () => { saveWindowSize(id); }), onContentLoaded: () => { - const fileInput = $(`${id}_iframe`).contentDocument.getElementById("fileselect"); + const fileInput = document.getElementById(`${id}_iframe`).contentDocument.getElementById("fileselect"); fileInput.files = droppedFiles; } }); @@ -1801,22 +1801,22 @@ window.addEventListener("load", async () => { switch (previouslyUsedTab) { case "search": if (window.qBittorrent.Client.isShowSearchEngine()) - $("searchTabLink").click(); + document.getElementById("searchTabLink").click(); break; case "rss": if (window.qBittorrent.Client.isShowRssReader()) - $("rssTabLink").click(); + document.getElementById("rssTabLink").click(); break; case "log": if (window.qBittorrent.Client.isShowLogViewer()) - $("logTabLink").click(); + document.getElementById("logTabLink").click(); break; case "transfers": - $("transfersTabLink").click(); + document.getElementById("transfersTabLink").click(); break; default: console.error(`Unexpected 'selected_window_tab' value: ${previouslyUsedTab}`); - $("transfersTabLink").click(); + document.getElementById("transfersTabLink").click(); break; }; }); diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js index 094fba5b3..c56f1712f 100644 --- a/src/webui/www/private/scripts/contextmenu.js +++ b/src/webui/www/private/scripts/contextmenu.js @@ -66,7 +66,7 @@ window.qBittorrent.ContextMenu ??= (() => { }; // option diffs menu - this.menu = $(this.options.menu); + this.menu = document.getElementById(this.options.menu); // fx this.fx = new Fx.Tween(this.menu, { @@ -457,7 +457,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.setEnabled("copyInfohash1", thereAreV1Hashes); this.setEnabled("copyInfohash2", thereAreV2Hashes); - const contextTagList = $("contextTagList"); + const contextTagList = document.getElementById("contextTagList"); for (const tag of tagMap.keys()) { const checkbox = contextTagList.querySelector(`a[href="#Tag/${tag}"] input[type="checkbox"]`); const count = tagCount.get(tag); @@ -477,7 +477,7 @@ window.qBittorrent.ContextMenu ??= (() => { } updateCategoriesSubMenu(categories) { - const contextCategoryList = $("contextCategoryList"); + const contextCategoryList = document.getElementById("contextCategoryList"); [...contextCategoryList.children].forEach((el) => { el.destroy(); }); const createMenuItem = (text, imgURL, clickFn) => { @@ -527,7 +527,7 @@ window.qBittorrent.ContextMenu ??= (() => { } updateTagsSubMenu(tags) { - const contextTagList = $("contextTagList"); + const contextTagList = document.getElementById("contextTagList"); contextTagList.replaceChildren(); const createMenuItem = (text, imgURL, clickFn) => { @@ -727,8 +727,8 @@ window.qBittorrent.ContextMenu ??= (() => { this.menu.style.left = "-999em"; this.menu.style.top = "-999em"; // position the menu - let xPosMenu = e.pageX + this.options.offsets.x - $("rssdownloaderpage").offsetLeft; - let yPosMenu = e.pageY + this.options.offsets.y - $("rssdownloaderpage").offsetTop; + let xPosMenu = e.pageX + this.options.offsets.x - document.getElementById("rssdownloaderpage").offsetLeft; + let yPosMenu = e.pageY + this.options.offsets.y - document.getElementById("rssdownloaderpage").offsetTop; if ((xPosMenu + this.menu.offsetWidth) > document.documentElement.clientWidth) xPosMenu -= this.menu.offsetWidth; if ((yPosMenu + this.menu.offsetHeight) > document.documentElement.clientHeight) diff --git a/src/webui/www/private/scripts/download.js b/src/webui/www/private/scripts/download.js index 38a4ce81e..2b6df21ad 100644 --- a/src/webui/www/private/scripts/download.js +++ b/src/webui/www/private/scripts/download.js @@ -55,7 +55,7 @@ window.qBittorrent.Download ??= (() => { const option = document.createElement("option"); option.value = category.name; option.textContent = category.name; - $("categorySelect").appendChild(option); + document.getElementById("categorySelect").appendChild(option); } }); }; @@ -64,31 +64,31 @@ window.qBittorrent.Download ??= (() => { const pref = window.parent.qBittorrent.Cache.preferences.get(); defaultSavePath = pref.save_path; - $("savepath").value = defaultSavePath; - $("startTorrent").checked = !pref.add_stopped_enabled; - $("addToTopOfQueue").checked = pref.add_to_top_of_queue; + document.getElementById("savepath").value = defaultSavePath; + document.getElementById("startTorrent").checked = !pref.add_stopped_enabled; + document.getElementById("addToTopOfQueue").checked = pref.add_to_top_of_queue; if (pref.auto_tmm_enabled) { - $("autoTMM").selectedIndex = 1; - $("savepath").disabled = true; + document.getElementById("autoTMM").selectedIndex = 1; + document.getElementById("savepath").disabled = true; } else { - $("autoTMM").selectedIndex = 0; + document.getElementById("autoTMM").selectedIndex = 0; } if (pref.torrent_stop_condition === "MetadataReceived") - $("stopCondition").selectedIndex = 1; + document.getElementById("stopCondition").selectedIndex = 1; else if (pref.torrent_stop_condition === "FilesChecked") - $("stopCondition").selectedIndex = 2; + document.getElementById("stopCondition").selectedIndex = 2; else - $("stopCondition").selectedIndex = 0; + document.getElementById("stopCondition").selectedIndex = 0; if (pref.torrent_content_layout === "Subfolder") - $("contentLayout").selectedIndex = 1; + document.getElementById("contentLayout").selectedIndex = 1; else if (pref.torrent_content_layout === "NoSubfolder") - $("contentLayout").selectedIndex = 2; + document.getElementById("contentLayout").selectedIndex = 2; else - $("contentLayout").selectedIndex = 0; + document.getElementById("contentLayout").selectedIndex = 0; }; const changeCategorySelect = (item) => { @@ -97,37 +97,37 @@ window.qBittorrent.Download ??= (() => { item.nextElementSibling.value = ""; item.nextElementSibling.select(); - if ($("autoTMM").selectedIndex === 1) - $("savepath").value = defaultSavePath; + if (document.getElementById("autoTMM").selectedIndex === 1) + document.getElementById("savepath").value = defaultSavePath; } else { item.nextElementSibling.hidden = true; const text = item.options[item.selectedIndex].textContent; item.nextElementSibling.value = text; - if ($("autoTMM").selectedIndex === 1) { + if (document.getElementById("autoTMM").selectedIndex === 1) { const categoryName = item.value; const category = categories[categoryName]; let savePath = defaultSavePath; if (category !== undefined) savePath = (category["savePath"] !== "") ? category["savePath"] : `${defaultSavePath}/${categoryName}`; - $("savepath").value = savePath; + document.getElementById("savepath").value = savePath; } } }; const changeTMM = (item) => { if (item.selectedIndex === 1) { - $("savepath").disabled = true; + document.getElementById("savepath").disabled = true; - const categorySelect = $("categorySelect"); + const categorySelect = document.getElementById("categorySelect"); const categoryName = categorySelect.options[categorySelect.selectedIndex].value; const category = categories[categoryName]; - $("savepath").value = (category === undefined) ? "" : category["savePath"]; + document.getElementById("savepath").value = (category === undefined) ? "" : category["savePath"]; } else { - $("savepath").disabled = false; - $("savepath").value = defaultSavePath; + document.getElementById("savepath").disabled = false; + document.getElementById("savepath").value = defaultSavePath; } }; diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index d05cd8c53..ea9d46d41 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -1762,8 +1762,8 @@ window.qBittorrent.DynamicTable ??= (() => { getFilteredAndSortedRows: function() { const filteredRows = []; - const useRegex = $("torrentsFilterRegexBox").checked; - const filterText = $("torrentsFilterInput").value.trim().toLowerCase(); + const useRegex = document.getElementById("torrentsFilterRegexBox").checked; + const filterText = document.getElementById("torrentsFilterInput").value.trim().toLowerCase(); let filterTerms; try { filterTerms = (filterText.length > 0) @@ -2021,7 +2021,7 @@ window.qBittorrent.DynamicTable ??= (() => { const filterTerms = window.qBittorrent.Search.searchText.filterPattern.toLowerCase().split(" "); const sizeFilters = getSizeFilters(); const seedsFilters = getSeedsFilters(); - const searchInTorrentName = $("searchInTorrentName").value === "names"; + const searchInTorrentName = document.getElementById("searchInTorrentName").value === "names"; if (searchInTorrentName || (filterTerms.length > 0) || (window.qBittorrent.Search.searchSizeFilter.min > 0.00) || (window.qBittorrent.Search.searchSizeFilter.max > 0.00)) { for (const row of this.getRowValues()) { @@ -3263,7 +3263,7 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("name", "", "", -1, true); this.columns["checked"].updateTd = function(td, row) { - if ($(`cbRssDlRule${row.rowId}`) === null) { + if (document.getElementById(`cbRssDlRule${row.rowId}`) === null) { const checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.id = `cbRssDlRule${row.rowId}`; @@ -3281,7 +3281,7 @@ window.qBittorrent.DynamicTable ??= (() => { td.append(checkbox); } else { - $(`cbRssDlRule${row.rowId}`).checked = row.full_data.checked; + document.getElementById(`cbRssDlRule${row.rowId}`).checked = row.full_data.checked; } }; this.columns["checked"].staticWidth = 50; @@ -3361,7 +3361,7 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("name", "", "", -1, true); this.columns["checked"].updateTd = function(td, row) { - if ($(`cbRssDlFeed${row.rowId}`) === null) { + if (document.getElementById(`cbRssDlFeed${row.rowId}`) === null) { const checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.id = `cbRssDlFeed${row.rowId}`; @@ -3378,7 +3378,7 @@ window.qBittorrent.DynamicTable ??= (() => { td.append(checkbox); } else { - $(`cbRssDlFeed${row.rowId}`).checked = row.full_data.checked; + document.getElementById(`cbRssDlFeed${row.rowId}`).checked = row.full_data.checked; } }; this.columns["checked"].staticWidth = 50; diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js index 52bba2d4d..314d84d22 100644 --- a/src/webui/www/private/scripts/mocha-init.js +++ b/src/webui/www/private/scripts/mocha-init.js @@ -151,7 +151,7 @@ let exportTorrentFN = () => {}; const initializeWindows = () => { saveWindowSize = (windowId) => { - const size = $(windowId).getSize(); + const size = document.getElementById(windowId).getSize(); LocalPreferences.set(`window_${windowId}_width`, size.x); LocalPreferences.set(`window_${windowId}_height`, size.y); }; @@ -166,8 +166,8 @@ const initializeWindows = () => { const addClickEvent = (el, fn) => { ["Link", "Button"].each((item) => { - if ($(el + item)) - $(el + item).addEventListener("click", fn); + if (document.getElementById(el + item)) + document.getElementById(el + item).addEventListener("click", fn); }); }; diff --git a/src/webui/www/private/scripts/piecesbar.js b/src/webui/www/private/scripts/piecesbar.js index 49d159cb1..803087f24 100644 --- a/src/webui/www/private/scripts/piecesbar.js +++ b/src/webui/www/private/scripts/piecesbar.js @@ -251,7 +251,7 @@ window.qBittorrent.PiecesBar ??= (() => { } const checkForParent = (id) => { - const obj = $(id); + const obj = document.getElementById(id); if (!obj) return; if (!obj.parentNode) diff --git a/src/webui/www/private/scripts/progressbar.js b/src/webui/www/private/scripts/progressbar.js index 5489b8877..0812024cf 100644 --- a/src/webui/www/private/scripts/progressbar.js +++ b/src/webui/www/private/scripts/progressbar.js @@ -142,7 +142,7 @@ window.qBittorrent.ProgressBar ??= (() => { } const ProgressBar_checkForParent = (id) => { - const obj = $(id); + const obj = document.getElementById(id); if (!obj) return; if (!obj.parentNode) diff --git a/src/webui/www/private/scripts/prop-files.js b/src/webui/www/private/scripts/prop-files.js index 1aa2665b9..0d9ce76b9 100644 --- a/src/webui/www/private/scripts/prop-files.js +++ b/src/webui/www/private/scripts/prop-files.js @@ -208,7 +208,7 @@ window.qBittorrent.PropFiles ??= (() => { const rowIds = []; const fileIds = []; let priority = FilePriority.Ignored; - const checkbox = $("tristate_cb"); + const checkbox = document.getElementById("tristate_cb"); if (checkbox.state === "checked") { setCheckboxUnchecked(checkbox); @@ -245,7 +245,7 @@ window.qBittorrent.PropFiles ??= (() => { }; const updateGlobalCheckbox = () => { - const checkbox = $("tristate_cb"); + const checkbox = document.getElementById("tristate_cb"); if (torrentFilesTable.isAllCheckboxesChecked()) setCheckboxChecked(checkbox); else if (torrentFilesTable.isAllCheckboxesUnchecked()) @@ -297,7 +297,7 @@ window.qBittorrent.PropFiles ??= (() => { ids.forEach((id) => { torrentFilesTable.setIgnored(id, ignore); - const combobox = $(`comboPrio${id}`); + const combobox = document.getElementById(`comboPrio${id}`); if (combobox !== null) selectComboboxPriority(combobox, priority); }); @@ -307,8 +307,8 @@ window.qBittorrent.PropFiles ??= (() => { const loadTorrentFilesData = () => { if (document.hidden) return; - if ($("propFiles").classList.contains("invisible") - || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { + if (document.getElementById("propFiles").classList.contains("invisible") + || document.getElementById("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { // Tab changed, don't do anything return; } @@ -586,10 +586,10 @@ window.qBittorrent.PropFiles ??= (() => { // listen for changes to torrentFilesFilterInput let torrentFilesFilterInputTimer = -1; - $("torrentFilesFilterInput").addEventListener("input", () => { + document.getElementById("torrentFilesFilterInput").addEventListener("input", () => { clearTimeout(torrentFilesFilterInputTimer); - const value = $("torrentFilesFilterInput").value; + const value = document.getElementById("torrentFilesFilterInput").value; torrentFilesTable.setFilter(value); torrentFilesFilterInputTimer = setTimeout(() => { diff --git a/src/webui/www/private/scripts/prop-general.js b/src/webui/www/private/scripts/prop-general.js index d93c9b746..fce3c84a6 100644 --- a/src/webui/www/private/scripts/prop-general.js +++ b/src/webui/www/private/scripts/prop-general.js @@ -40,37 +40,37 @@ window.qBittorrent.PropGeneral ??= (() => { const piecesBar = new window.qBittorrent.PiecesBar.PiecesBar([], { height: 18 }); - $("progress").appendChild(piecesBar); + document.getElementById("progress").appendChild(piecesBar); const clearData = () => { document.getElementById("progressPercentage").textContent = ""; - $("time_elapsed").textContent = ""; - $("eta").textContent = ""; - $("nb_connections").textContent = ""; - $("total_downloaded").textContent = ""; - $("total_uploaded").textContent = ""; - $("dl_speed").textContent = ""; - $("up_speed").textContent = ""; - $("dl_limit").textContent = ""; - $("up_limit").textContent = ""; - $("total_wasted").textContent = ""; - $("seeds").textContent = ""; - $("peers").textContent = ""; - $("share_ratio").textContent = ""; - $("popularity").textContent = ""; - $("reannounce").textContent = ""; - $("last_seen").textContent = ""; - $("total_size").textContent = ""; - $("pieces").textContent = ""; - $("created_by").textContent = ""; - $("addition_date").textContent = ""; - $("completion_date").textContent = ""; - $("creation_date").textContent = ""; - $("torrent_hash_v1").textContent = ""; - $("torrent_hash_v2").textContent = ""; - $("save_path").textContent = ""; - $("comment").textContent = ""; - $("private").textContent = ""; + document.getElementById("time_elapsed").textContent = ""; + document.getElementById("eta").textContent = ""; + document.getElementById("nb_connections").textContent = ""; + document.getElementById("total_downloaded").textContent = ""; + document.getElementById("total_uploaded").textContent = ""; + document.getElementById("dl_speed").textContent = ""; + document.getElementById("up_speed").textContent = ""; + document.getElementById("dl_limit").textContent = ""; + document.getElementById("up_limit").textContent = ""; + document.getElementById("total_wasted").textContent = ""; + document.getElementById("seeds").textContent = ""; + document.getElementById("peers").textContent = ""; + document.getElementById("share_ratio").textContent = ""; + document.getElementById("popularity").textContent = ""; + document.getElementById("reannounce").textContent = ""; + document.getElementById("last_seen").textContent = ""; + document.getElementById("total_size").textContent = ""; + document.getElementById("pieces").textContent = ""; + document.getElementById("created_by").textContent = ""; + document.getElementById("addition_date").textContent = ""; + document.getElementById("completion_date").textContent = ""; + document.getElementById("creation_date").textContent = ""; + document.getElementById("torrent_hash_v1").textContent = ""; + document.getElementById("torrent_hash_v2").textContent = ""; + document.getElementById("save_path").textContent = ""; + document.getElementById("comment").textContent = ""; + document.getElementById("private").textContent = ""; piecesBar.clear(); }; @@ -78,8 +78,8 @@ window.qBittorrent.PropGeneral ??= (() => { const loadTorrentData = () => { if (document.hidden) return; - if ($("propGeneral").classList.contains("invisible") - || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { + if (document.getElementById("propGeneral").classList.contains("invisible") + || document.getElementById("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { // Tab changed, don't do anything return; } @@ -100,13 +100,13 @@ window.qBittorrent.PropGeneral ??= (() => { }) .then(async (response) => { if (!response.ok) { - $("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; + document.getElementById("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; clearTimeout(loadTorrentDataTimer); loadTorrentDataTimer = loadTorrentData.delay(10000); return; } - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; const data = await response.json(); if (data) { @@ -119,70 +119,70 @@ window.qBittorrent.PropGeneral ??= (() => { .replace("%1", window.qBittorrent.Misc.friendlyDuration(data.time_elapsed)) .replace("%2", window.qBittorrent.Misc.friendlyDuration(data.seeding_time)) : window.qBittorrent.Misc.friendlyDuration(data.time_elapsed); - $("time_elapsed").textContent = timeElapsed; + document.getElementById("time_elapsed").textContent = timeElapsed; - $("eta").textContent = window.qBittorrent.Misc.friendlyDuration(data.eta, window.qBittorrent.Misc.MAX_ETA); + document.getElementById("eta").textContent = window.qBittorrent.Misc.friendlyDuration(data.eta, window.qBittorrent.Misc.MAX_ETA); const nbConnections = "QBT_TR(%1 (%2 max))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", data.nb_connections) .replace("%2", ((data.nb_connections_limit < 0) ? "∞" : data.nb_connections_limit)); - $("nb_connections").textContent = nbConnections; + document.getElementById("nb_connections").textContent = nbConnections; const totalDownloaded = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", window.qBittorrent.Misc.friendlyUnit(data.total_downloaded)) .replace("%2", window.qBittorrent.Misc.friendlyUnit(data.total_downloaded_session)); - $("total_downloaded").textContent = totalDownloaded; + document.getElementById("total_downloaded").textContent = totalDownloaded; const totalUploaded = "QBT_TR(%1 (%2 this session))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", window.qBittorrent.Misc.friendlyUnit(data.total_uploaded)) .replace("%2", window.qBittorrent.Misc.friendlyUnit(data.total_uploaded_session)); - $("total_uploaded").textContent = totalUploaded; + document.getElementById("total_uploaded").textContent = totalUploaded; const dlSpeed = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", window.qBittorrent.Misc.friendlyUnit(data.dl_speed, true)) .replace("%2", window.qBittorrent.Misc.friendlyUnit(data.dl_speed_avg, true)); - $("dl_speed").textContent = dlSpeed; + document.getElementById("dl_speed").textContent = dlSpeed; const upSpeed = "QBT_TR(%1 (%2 avg.))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", window.qBittorrent.Misc.friendlyUnit(data.up_speed, true)) .replace("%2", window.qBittorrent.Misc.friendlyUnit(data.up_speed_avg, true)); - $("up_speed").textContent = upSpeed; + document.getElementById("up_speed").textContent = upSpeed; const dlLimit = (data.dl_limit === -1) ? "∞" : window.qBittorrent.Misc.friendlyUnit(data.dl_limit, true); - $("dl_limit").textContent = dlLimit; + document.getElementById("dl_limit").textContent = dlLimit; const upLimit = (data.up_limit === -1) ? "∞" : window.qBittorrent.Misc.friendlyUnit(data.up_limit, true); - $("up_limit").textContent = upLimit; + document.getElementById("up_limit").textContent = upLimit; - $("total_wasted").textContent = window.qBittorrent.Misc.friendlyUnit(data.total_wasted); + document.getElementById("total_wasted").textContent = window.qBittorrent.Misc.friendlyUnit(data.total_wasted); const seeds = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", data.seeds) .replace("%2", data.seeds_total); - $("seeds").textContent = seeds; + document.getElementById("seeds").textContent = seeds; const peers = "QBT_TR(%1 (%2 total))QBT_TR[CONTEXT=PropertiesWidget]" .replace("%1", data.peers) .replace("%2", data.peers_total); - $("peers").textContent = peers; + document.getElementById("peers").textContent = peers; - $("share_ratio").textContent = data.share_ratio.toFixed(2); + document.getElementById("share_ratio").textContent = data.share_ratio.toFixed(2); - $("popularity").textContent = data.popularity.toFixed(2); + document.getElementById("popularity").textContent = data.popularity.toFixed(2); - $("reannounce").textContent = window.qBittorrent.Misc.friendlyDuration(data.reannounce); + document.getElementById("reannounce").textContent = window.qBittorrent.Misc.friendlyDuration(data.reannounce); const lastSeen = (data.last_seen >= 0) ? new Date(data.last_seen * 1000).toLocaleString() : "QBT_TR(Never)QBT_TR[CONTEXT=PropertiesWidget]"; - $("last_seen").textContent = lastSeen; + document.getElementById("last_seen").textContent = lastSeen; const totalSize = (data.total_size >= 0) ? window.qBittorrent.Misc.friendlyUnit(data.total_size) : ""; - $("total_size").textContent = totalSize; + document.getElementById("total_size").textContent = totalSize; const pieces = (data.pieces_num >= 0) ? "QBT_TR(%1 x %2 (have %3))QBT_TR[CONTEXT=PropertiesWidget]" @@ -190,40 +190,40 @@ window.qBittorrent.PropGeneral ??= (() => { .replace("%2", window.qBittorrent.Misc.friendlyUnit(data.piece_size)) .replace("%3", data.pieces_have) : ""; - $("pieces").textContent = pieces; + document.getElementById("pieces").textContent = pieces; - $("created_by").textContent = data.created_by; + document.getElementById("created_by").textContent = data.created_by; const additionDate = (data.addition_date >= 0) ? new Date(data.addition_date * 1000).toLocaleString() : "QBT_TR(Unknown)QBT_TR[CONTEXT=HttpServer]"; - $("addition_date").textContent = additionDate; + document.getElementById("addition_date").textContent = additionDate; const completionDate = (data.completion_date >= 0) ? new Date(data.completion_date * 1000).toLocaleString() : ""; - $("completion_date").textContent = completionDate; + document.getElementById("completion_date").textContent = completionDate; const creationDate = (data.creation_date >= 0) ? new Date(data.creation_date * 1000).toLocaleString() : ""; - $("creation_date").textContent = creationDate; + document.getElementById("creation_date").textContent = creationDate; const torrentHashV1 = (data.infohash_v1 !== "") ? data.infohash_v1 : "QBT_TR(N/A)QBT_TR[CONTEXT=PropertiesWidget]"; - $("torrent_hash_v1").textContent = torrentHashV1; + document.getElementById("torrent_hash_v1").textContent = torrentHashV1; const torrentHashV2 = (data.infohash_v2 !== "") ? data.infohash_v2 : "QBT_TR(N/A)QBT_TR[CONTEXT=PropertiesWidget]"; - $("torrent_hash_v2").textContent = torrentHashV2; + document.getElementById("torrent_hash_v2").textContent = torrentHashV2; - $("save_path").textContent = data.save_path; + document.getElementById("save_path").textContent = data.save_path; - $("comment").innerHTML = window.qBittorrent.Misc.parseHtmlLinks(window.qBittorrent.Misc.escapeHtml(data.comment)); + document.getElementById("comment").innerHTML = window.qBittorrent.Misc.parseHtmlLinks(window.qBittorrent.Misc.escapeHtml(data.comment)); - $("private").textContent = (data.has_metadata + document.getElementById("private").textContent = (data.has_metadata ? (data.private ? "QBT_TR(Yes)QBT_TR[CONTEXT=PropertiesWidget]" : "QBT_TR(No)QBT_TR[CONTEXT=PropertiesWidget]") @@ -246,13 +246,13 @@ window.qBittorrent.PropGeneral ??= (() => { }) .then(async (response) => { if (!response.ok) { - $("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; + document.getElementById("error_div").textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; clearTimeout(loadTorrentDataTimer); loadTorrentDataTimer = loadTorrentData.delay(10000); return; } - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; const data = await response.json(); if (data) diff --git a/src/webui/www/private/scripts/prop-peers.js b/src/webui/www/private/scripts/prop-peers.js index 8ccb2cbd1..f718d04e6 100644 --- a/src/webui/www/private/scripts/prop-peers.js +++ b/src/webui/www/private/scripts/prop-peers.js @@ -45,8 +45,8 @@ window.qBittorrent.PropPeers ??= (() => { const loadTorrentPeersData = () => { if (document.hidden) return; - if ($("propPeers").classList.contains("invisible") - || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { + if (document.getElementById("propPeers").classList.contains("invisible") + || document.getElementById("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { syncTorrentPeersLastResponseId = 0; torrentPeersTable.clear(); return; @@ -73,7 +73,7 @@ window.qBittorrent.PropPeers ??= (() => { const responseJSON = await response.json(); - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; if (responseJSON) { const full_update = (responseJSON["full_update"] === true); if (full_update) diff --git a/src/webui/www/private/scripts/prop-trackers.js b/src/webui/www/private/scripts/prop-trackers.js index e75709724..05a5de700 100644 --- a/src/webui/www/private/scripts/prop-trackers.js +++ b/src/webui/www/private/scripts/prop-trackers.js @@ -45,8 +45,8 @@ window.qBittorrent.PropTrackers ??= (() => { const loadTrackersData = () => { if (document.hidden) return; - if ($("propTrackers").classList.contains("invisible") - || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { + if (document.getElementById("propTrackers").classList.contains("invisible") + || document.getElementById("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { // Tab changed, don't do anything return; } diff --git a/src/webui/www/private/scripts/prop-webseeds.js b/src/webui/www/private/scripts/prop-webseeds.js index 7fd517597..737642f69 100644 --- a/src/webui/www/private/scripts/prop-webseeds.js +++ b/src/webui/www/private/scripts/prop-webseeds.js @@ -45,8 +45,8 @@ window.qBittorrent.PropWebseeds ??= (() => { const loadWebSeedsData = () => { if (document.hidden) return; - if ($("propWebSeeds").classList.contains("invisible") - || $("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { + if (document.getElementById("propWebSeeds").classList.contains("invisible") + || document.getElementById("propertiesPanel_collapseToggle").classList.contains("panel-expand")) { // Tab changed, don't do anything return; } diff --git a/src/webui/www/private/scripts/search.js b/src/webui/www/private/scripts/search.js index 3dc0b454b..5d9d8c946 100644 --- a/src/webui/www/private/scripts/search.js +++ b/src/webui/www/private/scripts/search.js @@ -107,7 +107,7 @@ window.qBittorrent.Search ??= (() => { const init = () => { // load "Search in" preference from local storage - $("searchInTorrentName").value = (LocalPreferences.get("search_in_filter") === "names") ? "names" : "everywhere"; + document.getElementById("searchInTorrentName").value = (LocalPreferences.get("search_in_filter") === "names") ? "names" : "everywhere"; const searchResultsTableContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({ targets: "#searchResultsTableDiv tbody tr", menu: "searchResultsTableMenu", @@ -128,12 +128,12 @@ window.qBittorrent.Search ??= (() => { // listen for changes to searchInNameFilter let searchInNameFilterTimer = -1; - $("searchInNameFilter").addEventListener("input", () => { + document.getElementById("searchInNameFilter").addEventListener("input", () => { clearTimeout(searchInNameFilterTimer); searchInNameFilterTimer = setTimeout(() => { searchInNameFilterTimer = -1; - const value = $("searchInNameFilter").value; + const value = document.getElementById("searchInNameFilter").value; searchText.filterPattern = value; searchFilterChanged(); }, window.qBittorrent.Misc.FILTER_INPUT_DELAY); @@ -200,15 +200,15 @@ window.qBittorrent.Search ??= (() => { document.getElementById("startSearchButton").lastChild.textContent = "QBT_TR(Search)QBT_TR[CONTEXT=SearchEngineWidget]"; }); listItem.appendChild(tabElem); - $("searchTabs").appendChild(listItem); + document.getElementById("searchTabs").appendChild(listItem); searchResultsTabsContextMenu.addTarget(listItem); // unhide the results elements if (numSearchTabs() >= 1) { - $("searchResultsNoSearches").classList.add("invisible"); - $("searchResultsFilters").classList.remove("invisible"); - $("searchResultsTableContainer").classList.remove("invisible"); - $("searchTabsToolbar").classList.remove("invisible"); + document.getElementById("searchResultsNoSearches").classList.add("invisible"); + document.getElementById("searchResultsFilters").classList.remove("invisible"); + document.getElementById("searchResultsTableContainer").classList.remove("invisible"); + document.getElementById("searchTabsToolbar").classList.remove("invisible"); } // select new tab @@ -268,12 +268,12 @@ window.qBittorrent.Search ??= (() => { resetSearchState(); resetFilters(); - $("numSearchResultsVisible").textContent = 0; - $("numSearchResultsTotal").textContent = 0; - $("searchResultsNoSearches").classList.remove("invisible"); - $("searchResultsFilters").classList.add("invisible"); - $("searchResultsTableContainer").classList.add("invisible"); - $("searchTabsToolbar").classList.add("invisible"); + document.getElementById("numSearchResultsVisible").textContent = 0; + document.getElementById("numSearchResultsTotal").textContent = 0; + document.getElementById("searchResultsNoSearches").classList.remove("invisible"); + document.getElementById("searchResultsFilters").classList.add("invisible"); + document.getElementById("searchResultsTableContainer").classList.add("invisible"); + document.getElementById("searchTabsToolbar").classList.add("invisible"); } else if (isTabSelected && newTabToSelect) { setActiveTab(newTabToSelect); @@ -335,23 +335,23 @@ window.qBittorrent.Search ??= (() => { // restore filters searchText.pattern = state.searchPattern; searchText.filterPattern = state.filterPattern; - $("searchInNameFilter").value = state.filterPattern; + document.getElementById("searchInNameFilter").value = state.filterPattern; searchSeedsFilter.min = state.seedsFilter.min; searchSeedsFilter.max = state.seedsFilter.max; - $("searchMinSeedsFilter").value = state.seedsFilter.min; - $("searchMaxSeedsFilter").value = state.seedsFilter.max; + document.getElementById("searchMinSeedsFilter").value = state.seedsFilter.min; + document.getElementById("searchMaxSeedsFilter").value = state.seedsFilter.max; searchSizeFilter.min = state.sizeFilter.min; searchSizeFilter.minUnit = state.sizeFilter.minUnit; searchSizeFilter.max = state.sizeFilter.max; searchSizeFilter.maxUnit = state.sizeFilter.maxUnit; - $("searchMinSizeFilter").value = state.sizeFilter.min; - $("searchMinSizePrefix").value = state.sizeFilter.minUnit; - $("searchMaxSizeFilter").value = state.sizeFilter.max; - $("searchMaxSizePrefix").value = state.sizeFilter.maxUnit; + document.getElementById("searchMinSizeFilter").value = state.sizeFilter.min; + document.getElementById("searchMinSizePrefix").value = state.sizeFilter.minUnit; + document.getElementById("searchMaxSizeFilter").value = state.sizeFilter.max; + document.getElementById("searchMaxSizePrefix").value = state.sizeFilter.maxUnit; - const currentSearchPattern = $("searchPattern").value.trim(); + const currentSearchPattern = document.getElementById("searchPattern").value.trim(); if (state.running && (state.searchPattern === currentSearchPattern)) { // allow search to be stopped document.getElementById("startSearchButton").lastChild.textContent = "QBT_TR(Stop)QBT_TR[CONTEXT=SearchEngineWidget]"; @@ -360,7 +360,7 @@ window.qBittorrent.Search ??= (() => { searchResultsTable.setSortedColumn(state.sort.column, state.sort.reverse); - $("searchInTorrentName").value = state.searchIn; + document.getElementById("searchInTorrentName").value = state.searchIn; } // must restore all filters before calling updateTable @@ -370,8 +370,8 @@ window.qBittorrent.Search ??= (() => { if (rowsToSelect.length > 0) searchResultsTable.reselectRows(rowsToSelect); - $("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; - $("numSearchResultsTotal").textContent = searchResultsTable.getRowSize(); + document.getElementById("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; + document.getElementById("numSearchResultsTotal").textContent = searchResultsTable.getRowSize(); }; const getStatusIconElement = (text, image) => { @@ -386,7 +386,7 @@ window.qBittorrent.Search ??= (() => { }; const updateStatusIconElement = (searchId, text, image) => { - const searchTab = $(`${searchTabIdPrefix}${searchId}`); + const searchTab = document.getElementById(`${searchTabIdPrefix}${searchId}`); if (searchTab) { const statusIcon = searchTab.querySelector(".statusIcon"); statusIcon.alt = text; @@ -439,7 +439,7 @@ window.qBittorrent.Search ??= (() => { }; const getSelectedSearchId = () => { - const selectedTab = $("searchTabs").querySelector("li.selected"); + const selectedTab = document.getElementById("searchTabs").querySelector("li.selected"); return selectedTab ? getSearchIdFromTab(selectedTab) : null; }; @@ -448,9 +448,9 @@ window.qBittorrent.Search ??= (() => { const state = searchState.get(currentSearchId); const isSearchRunning = state && state.running; if (!isSearchRunning || searchPatternChanged) { - const pattern = $("searchPattern").value.trim(); - const category = $("categorySelect").value; - const plugins = $("pluginsSelect").value; + const pattern = document.getElementById("searchPattern").value.trim(); + const category = document.getElementById("categorySelect").value; + const plugins = document.getElementById("pluginsSelect").value; if (!pattern || !category || !plugins) return; @@ -506,7 +506,7 @@ window.qBittorrent.Search ??= (() => { const manageSearchPlugins = () => { const id = "searchPlugins"; - if (!$(id)) { + if (!document.getElementById(id)) { new MochaUI.Window({ id: id, title: "QBT_TR(Search plugins)QBT_TR[CONTEXT=PluginSelectDlg]", @@ -541,7 +541,7 @@ window.qBittorrent.Search ??= (() => { const onSearchPatternChanged = () => { const currentSearchId = getSelectedSearchId(); const state = searchState.get(currentSearchId); - const currentSearchPattern = $("searchPattern").value.trim(); + const currentSearchPattern = document.getElementById("searchPattern").value.trim(); // start a new search if pattern has changed, otherwise allow the search to be stopped if (state && (state.searchPattern === currentSearchPattern)) { searchPatternChanged = false; @@ -554,11 +554,11 @@ window.qBittorrent.Search ??= (() => { }; const categorySelected = () => { - selectedCategory = $("categorySelect").value; + selectedCategory = document.getElementById("categorySelect").value; }; const pluginSelected = () => { - selectedPlugin = $("pluginsSelect").value; + selectedPlugin = document.getElementById("pluginsSelect").value; if (selectedPlugin !== prevSelectedPlugin) { prevSelectedPlugin = selectedPlugin; @@ -567,18 +567,18 @@ window.qBittorrent.Search ??= (() => { }; const reselectCategory = () => { - for (let i = 0; i < $("categorySelect").options.length; ++i) { - if ($("categorySelect").options[i].get("value") === selectedCategory) - $("categorySelect").options[i].selected = true; + for (let i = 0; i < document.getElementById("categorySelect").options.length; ++i) { + if (document.getElementById("categorySelect").options[i].get("value") === selectedCategory) + document.getElementById("categorySelect").options[i].selected = true; } categorySelected(); }; const reselectPlugin = () => { - for (let i = 0; i < $("pluginsSelect").options.length; ++i) { - if ($("pluginsSelect").options[i].get("value") === selectedPlugin) - $("pluginsSelect").options[i].selected = true; + for (let i = 0; i < document.getElementById("pluginsSelect").options.length; ++i) { + if (document.getElementById("pluginsSelect").options[i].get("value") === selectedPlugin) + document.getElementById("pluginsSelect").options[i].selected = true; } pluginSelected(); @@ -614,10 +614,10 @@ window.qBittorrent.Search ??= (() => { categoryOptions.splice(1, 0, option); } - $("categorySelect").replaceChildren(...categoryOptions); + document.getElementById("categorySelect").replaceChildren(...categoryOptions); }; - const selectedPlugin = $("pluginsSelect").value; + const selectedPlugin = document.getElementById("pluginsSelect").value; if ((selectedPlugin === "all") || (selectedPlugin === "enabled")) { const uniqueCategories = {}; @@ -675,9 +675,9 @@ window.qBittorrent.Search ??= (() => { const searchPluginsEmpty = (searchPlugins.length === 0); if (!searchPluginsEmpty) { - $("searchResultsNoPlugins").classList.add("invisible"); + document.getElementById("searchResultsNoPlugins").classList.add("invisible"); if (numSearchTabs() === 0) - $("searchResultsNoSearches").classList.remove("invisible"); + document.getElementById("searchResultsNoSearches").classList.remove("invisible"); // sort plugins alphabetically const allPlugins = searchPlugins.sort((left, right) => { @@ -695,11 +695,11 @@ window.qBittorrent.Search ??= (() => { pluginOptions.splice(2, 0, createOption("──────────", undefined, true)); } - $("pluginsSelect").replaceChildren(...pluginOptions); + document.getElementById("pluginsSelect").replaceChildren(...pluginOptions); - $("searchPattern").disabled = searchPluginsEmpty; - $("categorySelect").disabled = searchPluginsEmpty; - $("pluginsSelect").disabled = searchPluginsEmpty; + document.getElementById("searchPattern").disabled = searchPluginsEmpty; + document.getElementById("categorySelect").disabled = searchPluginsEmpty; + document.getElementById("pluginsSelect").disabled = searchPluginsEmpty; document.getElementById("startSearchButton").disabled = searchPluginsEmpty; if (window.qBittorrent.SearchPlugins !== undefined) @@ -721,25 +721,25 @@ window.qBittorrent.Search ??= (() => { const resetFilters = () => { searchText.filterPattern = ""; - $("searchInNameFilter").value = ""; + document.getElementById("searchInNameFilter").value = ""; searchSeedsFilter.min = 0; searchSeedsFilter.max = 0; - $("searchMinSeedsFilter").value = searchSeedsFilter.min; - $("searchMaxSeedsFilter").value = searchSeedsFilter.max; + document.getElementById("searchMinSeedsFilter").value = searchSeedsFilter.min; + document.getElementById("searchMaxSeedsFilter").value = searchSeedsFilter.max; searchSizeFilter.min = 0.00; searchSizeFilter.minUnit = 2; // B = 0, KiB = 1, MiB = 2, GiB = 3, TiB = 4, PiB = 5, EiB = 6 searchSizeFilter.max = 0.00; searchSizeFilter.maxUnit = 3; - $("searchMinSizeFilter").value = searchSizeFilter.min; - $("searchMinSizePrefix").value = searchSizeFilter.minUnit; - $("searchMaxSizeFilter").value = searchSizeFilter.max; - $("searchMaxSizePrefix").value = searchSizeFilter.maxUnit; + document.getElementById("searchMinSizeFilter").value = searchSizeFilter.min; + document.getElementById("searchMinSizePrefix").value = searchSizeFilter.minUnit; + document.getElementById("searchMaxSizeFilter").value = searchSizeFilter.max; + document.getElementById("searchMaxSizePrefix").value = searchSizeFilter.maxUnit; }; const getSearchInTorrentName = () => { - return ($("searchInTorrentName").value === "names") ? "names" : "everywhere"; + return (document.getElementById("searchInTorrentName").value === "names") ? "names" : "everywhere"; }; const searchInTorrentName = () => { @@ -748,29 +748,29 @@ window.qBittorrent.Search ??= (() => { }; const searchSeedsFilterChanged = () => { - searchSeedsFilter.min = $("searchMinSeedsFilter").value; - searchSeedsFilter.max = $("searchMaxSeedsFilter").value; + searchSeedsFilter.min = document.getElementById("searchMinSeedsFilter").value; + searchSeedsFilter.max = document.getElementById("searchMaxSeedsFilter").value; searchFilterChanged(); }; const searchSizeFilterChanged = () => { - searchSizeFilter.min = $("searchMinSizeFilter").value; - searchSizeFilter.minUnit = $("searchMinSizePrefix").value; - searchSizeFilter.max = $("searchMaxSizeFilter").value; - searchSizeFilter.maxUnit = $("searchMaxSizePrefix").value; + searchSizeFilter.min = document.getElementById("searchMinSizeFilter").value; + searchSizeFilter.minUnit = document.getElementById("searchMinSizePrefix").value; + searchSizeFilter.max = document.getElementById("searchMaxSizeFilter").value; + searchSizeFilter.maxUnit = document.getElementById("searchMaxSizePrefix").value; searchFilterChanged(); }; const searchSizeFilterPrefixChanged = () => { - if ((Number($("searchMinSizeFilter").value) !== 0) || (Number($("searchMaxSizeFilter").value) !== 0)) + if ((Number(document.getElementById("searchMinSizeFilter").value) !== 0) || (Number(document.getElementById("searchMaxSizeFilter").value) !== 0)) searchSizeFilterChanged(); }; const searchFilterChanged = () => { searchResultsTable.updateTable(); - $("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; + document.getElementById("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; }; const loadSearchResultsData = function(searchId) { @@ -799,7 +799,7 @@ window.qBittorrent.Search ??= (() => { return; } - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; const state = searchState.get(searchId); // check if user stopped the search prior to receiving the response @@ -842,8 +842,8 @@ window.qBittorrent.Search ??= (() => { for (const row of newRows) searchResultsTable.updateRowData(row); - $("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; - $("numSearchResultsTotal").textContent = searchResultsTable.getRowSize(); + document.getElementById("numSearchResultsVisible").textContent = searchResultsTable.getFilteredAndSortedRows().length; + document.getElementById("numSearchResultsTotal").textContent = searchResultsTable.getRowSize(); searchResultsTable.updateTable(); } diff --git a/src/webui/www/private/scripts/speedslider.js b/src/webui/www/private/scripts/speedslider.js index 24544a8d1..f2c96f66a 100644 --- a/src/webui/www/private/scripts/speedslider.js +++ b/src/webui/www/private/scripts/speedslider.js @@ -30,7 +30,7 @@ MochaUI.extend({ addUpLimitSlider: (hashes) => { - if ($("uplimitSliderarea")) { + if (document.getElementById("uplimitSliderarea")) { // Get global upload limit fetch("api/v2/transfer/uploadLimit", { method: "GET", @@ -61,29 +61,29 @@ MochaUI.extend({ if (up_limit < 0) up_limit = 0; maximum = 10000; - new Slider($("uplimitSliderarea"), $("uplimitSliderknob"), { + new Slider(document.getElementById("uplimitSliderarea"), document.getElementById("uplimitSliderknob"), { steps: maximum, offset: 0, initialStep: Math.round(up_limit), onChange: (pos) => { if (pos > 0) { - $("uplimitUpdatevalue").value = pos; - $("upLimitUnit").style.visibility = "visible"; + document.getElementById("uplimitUpdatevalue").value = pos; + document.getElementById("upLimitUnit").style.visibility = "visible"; } else { - $("uplimitUpdatevalue").value = "∞"; - $("upLimitUnit").style.visibility = "hidden"; + document.getElementById("uplimitUpdatevalue").value = "∞"; + document.getElementById("upLimitUnit").style.visibility = "hidden"; } } }); // Set default value if (up_limit === 0) { - $("uplimitUpdatevalue").value = "∞"; - $("upLimitUnit").style.visibility = "hidden"; + document.getElementById("uplimitUpdatevalue").value = "∞"; + document.getElementById("upLimitUnit").style.visibility = "hidden"; } else { - $("uplimitUpdatevalue").value = Math.round(up_limit); - $("upLimitUnit").style.visibility = "visible"; + document.getElementById("uplimitUpdatevalue").value = Math.round(up_limit); + document.getElementById("upLimitUnit").style.visibility = "visible"; } } else { @@ -108,29 +108,29 @@ MochaUI.extend({ } if (up_limit < 0) up_limit = 0; - new Slider($("uplimitSliderarea"), $("uplimitSliderknob"), { + new Slider(document.getElementById("uplimitSliderarea"), document.getElementById("uplimitSliderknob"), { steps: maximum, offset: 0, initialStep: Math.round(up_limit / 1024), onChange: (pos) => { if (pos > 0) { - $("uplimitUpdatevalue").value = pos; - $("upLimitUnit").style.visibility = "visible"; + document.getElementById("uplimitUpdatevalue").value = pos; + document.getElementById("upLimitUnit").style.visibility = "visible"; } else { - $("uplimitUpdatevalue").value = "∞"; - $("upLimitUnit").style.visibility = "hidden"; + document.getElementById("uplimitUpdatevalue").value = "∞"; + document.getElementById("upLimitUnit").style.visibility = "hidden"; } } }); // Set default value if (up_limit === 0) { - $("uplimitUpdatevalue").value = "∞"; - $("upLimitUnit").style.visibility = "hidden"; + document.getElementById("uplimitUpdatevalue").value = "∞"; + document.getElementById("upLimitUnit").style.visibility = "hidden"; } else { - $("uplimitUpdatevalue").value = Math.round(up_limit / 1024); - $("upLimitUnit").style.visibility = "visible"; + document.getElementById("uplimitUpdatevalue").value = Math.round(up_limit / 1024); + document.getElementById("upLimitUnit").style.visibility = "visible"; } }); } @@ -139,7 +139,7 @@ MochaUI.extend({ }, addDlLimitSlider: (hashes) => { - if ($("dllimitSliderarea")) { + if (document.getElementById("dllimitSliderarea")) { // Get global upload limit fetch("api/v2/transfer/downloadLimit", { method: "GET", @@ -170,29 +170,29 @@ MochaUI.extend({ if (dl_limit < 0) dl_limit = 0; maximum = 10000; - new Slider($("dllimitSliderarea"), $("dllimitSliderknob"), { + new Slider(document.getElementById("dllimitSliderarea"), document.getElementById("dllimitSliderknob"), { steps: maximum, offset: 0, initialStep: Math.round(dl_limit), onChange: (pos) => { if (pos > 0) { - $("dllimitUpdatevalue").value = pos; - $("dlLimitUnit").style.visibility = "visible"; + document.getElementById("dllimitUpdatevalue").value = pos; + document.getElementById("dlLimitUnit").style.visibility = "visible"; } else { - $("dllimitUpdatevalue").value = "∞"; - $("dlLimitUnit").style.visibility = "hidden"; + document.getElementById("dllimitUpdatevalue").value = "∞"; + document.getElementById("dlLimitUnit").style.visibility = "hidden"; } } }); // Set default value if (dl_limit === 0) { - $("dllimitUpdatevalue").value = "∞"; - $("dlLimitUnit").style.visibility = "hidden"; + document.getElementById("dllimitUpdatevalue").value = "∞"; + document.getElementById("dlLimitUnit").style.visibility = "hidden"; } else { - $("dllimitUpdatevalue").value = Math.round(dl_limit); - $("dlLimitUnit").style.visibility = "visible"; + document.getElementById("dllimitUpdatevalue").value = Math.round(dl_limit); + document.getElementById("dlLimitUnit").style.visibility = "visible"; } } else { @@ -217,29 +217,29 @@ MochaUI.extend({ } if (dl_limit < 0) dl_limit = 0; - new Slider($("dllimitSliderarea"), $("dllimitSliderknob"), { + new Slider(document.getElementById("dllimitSliderarea"), document.getElementById("dllimitSliderknob"), { steps: maximum, offset: 0, initialStep: Math.round(dl_limit / 1024), onChange: (pos) => { if (pos > 0) { - $("dllimitUpdatevalue").value = pos; - $("dlLimitUnit").style.visibility = "visible"; + document.getElementById("dllimitUpdatevalue").value = pos; + document.getElementById("dlLimitUnit").style.visibility = "visible"; } else { - $("dllimitUpdatevalue").value = "∞"; - $("dlLimitUnit").style.visibility = "hidden"; + document.getElementById("dllimitUpdatevalue").value = "∞"; + document.getElementById("dlLimitUnit").style.visibility = "hidden"; } } }); // Set default value if (dl_limit === 0) { - $("dllimitUpdatevalue").value = "∞"; - $("dlLimitUnit").style.visibility = "hidden"; + document.getElementById("dllimitUpdatevalue").value = "∞"; + document.getElementById("dlLimitUnit").style.visibility = "hidden"; } else { - $("dllimitUpdatevalue").value = Math.round(dl_limit / 1024); - $("dlLimitUnit").style.visibility = "visible"; + document.getElementById("dllimitUpdatevalue").value = Math.round(dl_limit / 1024); + document.getElementById("dlLimitUnit").style.visibility = "visible"; } }); } diff --git a/src/webui/www/private/setlocation.html b/src/webui/www/private/setlocation.html index 1455340df..e9095fc83 100644 --- a/src/webui/www/private/setlocation.html +++ b/src/webui/www/private/setlocation.html @@ -18,7 +18,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("setLocationButton").click(); + document.getElementById("setLocationButton").click(); break; case "Escape": event.preventDefault(); @@ -32,17 +32,17 @@ // set text field to current value if (path !== null) - $("setLocation").value = decodeURIComponent(path); + document.getElementById("setLocation").value = decodeURIComponent(path); - $("setLocation").focus(); - $("setLocationButton").addEventListener("click", (e) => { + document.getElementById("setLocation").focus(); + document.getElementById("setLocationButton").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); // check field - const location = $("setLocation").value.trim(); + const location = document.getElementById("setLocation").value.trim(); if ((location === null) || (location === "")) { - $("error_div").textContent = "QBT_TR(Save path is empty)QBT_TR[CONTEXT=TorrentsController]"; + document.getElementById("error_div").textContent = "QBT_TR(Save path is empty)QBT_TR[CONTEXT=TorrentsController]"; return; } @@ -55,7 +55,7 @@ }) .then(async (response) => { if (!response.ok) { - $("error_div").textContent = await response.text(); + document.getElementById("error_div").textContent = await response.text(); return; } diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index b106e72b8..cf2993675 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -20,7 +20,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("save").click(); + document.getElementById("save").click(); break; case "Escape": event.preventDefault(); @@ -56,23 +56,23 @@ else { setSelectedRadioValue("shareLimit", "custom"); if (values.ratioLimit >= 0) { - $("setRatio").checked = true; - $("ratio").value = values.ratioLimit.toFixed(2); + document.getElementById("setRatio").checked = true; + document.getElementById("ratio").value = values.ratioLimit.toFixed(2); } if (values.seedingTimeLimit >= 0) { - $("setTotalMinutes").checked = true; - $("totalMinutes").value = values.seedingTimeLimit; + document.getElementById("setTotalMinutes").checked = true; + document.getElementById("totalMinutes").value = values.seedingTimeLimit; } if (values.inactiveSeedingTimeLimit >= 0) { - $("setInactiveMinutes").checked = true; - $("inactiveMinutes").value = values.inactiveSeedingTimeLimit; + document.getElementById("setInactiveMinutes").checked = true; + document.getElementById("inactiveMinutes").value = values.inactiveSeedingTimeLimit; } } shareLimitChanged(); - $("default").focus(); - $("save").addEventListener("click", (e) => { + document.getElementById("default").focus(); + document.getElementById("save").addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); @@ -91,9 +91,9 @@ ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = NoLimit; } else if (shareLimit === "custom") { - ratioLimitValue = $("setRatio").checked ? $("ratio").value : -1; - seedingTimeLimitValue = $("setTotalMinutes").checked ? $("totalMinutes").value : -1; - inactiveSeedingTimeLimitValue = $("setInactiveMinutes").checked ? $("inactiveMinutes").value : -1; + ratioLimitValue = document.getElementById("setRatio").checked ? document.getElementById("ratio").value : -1; + seedingTimeLimitValue = document.getElementById("setTotalMinutes").checked ? document.getElementById("totalMinutes").value : -1; + inactiveSeedingTimeLimitValue = document.getElementById("setInactiveMinutes").checked ? document.getElementById("inactiveMinutes").value : -1; } else { return; @@ -139,26 +139,26 @@ const shareLimitChanged = () => { const customShareLimit = getSelectedRadioValue("shareLimit") === "custom"; - $("setRatio").disabled = !customShareLimit; - $("setTotalMinutes").disabled = !customShareLimit; - $("setInactiveMinutes").disabled = !customShareLimit; + document.getElementById("setRatio").disabled = !customShareLimit; + document.getElementById("setTotalMinutes").disabled = !customShareLimit; + document.getElementById("setInactiveMinutes").disabled = !customShareLimit; enableInputBoxes(); - $("save").disabled = !isFormValid(); + document.getElementById("save").disabled = !isFormValid(); }; const enableInputBoxes = () => { - $("ratio").disabled = $("setRatio").disabled || !$("setRatio").checked; - $("totalMinutes").disabled = $("setTotalMinutes").disabled || !$("setTotalMinutes").checked; - $("inactiveMinutes").disabled = $("setInactiveMinutes").disabled || !$("setInactiveMinutes").checked; + document.getElementById("ratio").disabled = document.getElementById("setRatio").disabled || !document.getElementById("setRatio").checked; + document.getElementById("totalMinutes").disabled = document.getElementById("setTotalMinutes").disabled || !document.getElementById("setTotalMinutes").checked; + document.getElementById("inactiveMinutes").disabled = document.getElementById("setInactiveMinutes").disabled || !document.getElementById("setInactiveMinutes").checked; - $("save").disabled = !isFormValid(); + document.getElementById("save").disabled = !isFormValid(); }; const isFormValid = () => { - return !((getSelectedRadioValue("shareLimit") === "custom") && !$("setRatio").checked - && !$("setTotalMinutes").checked && !$("setInactiveMinutes").checked); + return !((getSelectedRadioValue("shareLimit") === "custom") && !document.getElementById("setRatio").checked + && !document.getElementById("setTotalMinutes").checked && !document.getElementById("setInactiveMinutes").checked); }; diff --git a/src/webui/www/private/upload.html b/src/webui/www/private/upload.html index d7a065a26..74c4c65e0 100644 --- a/src/webui/www/private/upload.html +++ b/src/webui/www/private/upload.html @@ -160,23 +160,23 @@ let submitted = false; - $("uploadForm").addEventListener("submit", () => { - $("startTorrentHidden").value = $("startTorrent").checked ? "false" : "true"; + document.getElementById("uploadForm").addEventListener("submit", () => { + document.getElementById("startTorrentHidden").value = document.getElementById("startTorrent").checked ? "false" : "true"; - $("dlLimitHidden").value = Number($("dlLimitText").value) * 1024; - $("upLimitHidden").value = Number($("upLimitText").value) * 1024; + document.getElementById("dlLimitHidden").value = Number(document.getElementById("dlLimitText").value) * 1024; + document.getElementById("upLimitHidden").value = Number(document.getElementById("upLimitText").value) * 1024; - $("upload_spinner").style.display = "block"; + document.getElementById("upload_spinner").style.display = "block"; submitted = true; }); - $("upload_frame").addEventListener("load", () => { + document.getElementById("upload_frame").addEventListener("load", () => { if (submitted) window.parent.qBittorrent.Client.closeFrameWindow(window); }); if ((Browser.platform === "ios") || ((Browser.platform === "mac") && (navigator.maxTouchPoints > 1))) - $("fileselect").accept = ".torrent"; + document.getElementById("fileselect").accept = ".torrent"; window.qBittorrent.pathAutofill.attachPathAutofill(); diff --git a/src/webui/www/private/uploadlimit.html b/src/webui/www/private/uploadlimit.html index ed672cd47..fb60da531 100644 --- a/src/webui/www/private/uploadlimit.html +++ b/src/webui/www/private/uploadlimit.html @@ -37,7 +37,7 @@ switch (event.key) { case "Enter": event.preventDefault(); - $("applyButton").click(); + document.getElementById("applyButton").click(); break; case "Escape": event.preventDefault(); @@ -48,7 +48,7 @@ const hashes = new URLSearchParams(window.location.search).get("hashes").split("|"); const setUpLimit = () => { - const limit = Number($("uplimitUpdatevalue").value) * 1024; + const limit = Number(document.getElementById("uplimitUpdatevalue").value) * 1024; if (hashes[0] === "global") { fetch("api/v2/transfer/setUploadLimit", { method: "POST", @@ -81,7 +81,7 @@ } }; - $("uplimitUpdatevalue").focus(); + document.getElementById("uplimitUpdatevalue").focus(); MochaUI.addUpLimitSlider(hashes); diff --git a/src/webui/www/private/views/about.html b/src/webui/www/private/views/about.html index cf265f585..c5a67ed83 100644 --- a/src/webui/www/private/views/about.html +++ b/src/webui/www/private/views/about.html @@ -855,12 +855,12 @@ const qbtVersion = window.parent.qBittorrent.Cache.qbtVersion.get(); const buildInfo = window.parent.qBittorrent.Cache.buildInfo.get(); - $("qbittorrentVersion").textContent = `qBittorrent ${qbtVersion} QBT_TR(WebUI)QBT_TR[CONTEXT=OptionsDialog]`; - $("qtVersion").textContent = buildInfo.qt; - $("libtorrentVersion").textContent = buildInfo.libtorrent; - $("boostVersion").textContent = buildInfo.boost; - $("opensslVersion").textContent = buildInfo.openssl; - $("zlibVersion").textContent = buildInfo.zlib; - $("qbittorrentVersion").textContent += ` (${buildInfo.bitness}-bit)`; + document.getElementById("qbittorrentVersion").textContent = `qBittorrent ${qbtVersion} QBT_TR(WebUI)QBT_TR[CONTEXT=OptionsDialog]`; + document.getElementById("qtVersion").textContent = buildInfo.qt; + document.getElementById("libtorrentVersion").textContent = buildInfo.libtorrent; + document.getElementById("boostVersion").textContent = buildInfo.boost; + document.getElementById("opensslVersion").textContent = buildInfo.openssl; + document.getElementById("zlibVersion").textContent = buildInfo.zlib; + document.getElementById("qbittorrentVersion").textContent += ` (${buildInfo.bitness}-bit)`; })(); diff --git a/src/webui/www/private/views/aboutToolbar.html b/src/webui/www/private/views/aboutToolbar.html index 3557a11e5..5e358890b 100644 --- a/src/webui/www/private/views/aboutToolbar.html +++ b/src/webui/www/private/views/aboutToolbar.html @@ -16,34 +16,34 @@ (() => { MochaUI.initializeTabs("aboutTabs"); - $("aboutAboutLink").addEventListener("click", () => { + document.getElementById("aboutAboutLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutAboutContent").classList.remove("invisible"); + document.getElementById("aboutAboutContent").classList.remove("invisible"); }); - $("aboutAuthorLink").addEventListener("click", () => { + document.getElementById("aboutAuthorLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutAuthorContent").classList.remove("invisible"); + document.getElementById("aboutAuthorContent").classList.remove("invisible"); }); - $("aboutSpecialThanksLink").addEventListener("click", () => { + document.getElementById("aboutSpecialThanksLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutSpecialThanksContent").classList.remove("invisible"); + document.getElementById("aboutSpecialThanksContent").classList.remove("invisible"); }); - $("aboutTranslatorsLink").addEventListener("click", () => { + document.getElementById("aboutTranslatorsLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutTranslatorsContent").classList.remove("invisible"); + document.getElementById("aboutTranslatorsContent").classList.remove("invisible"); }); - $("aboutLicenseLink").addEventListener("click", () => { + document.getElementById("aboutLicenseLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutLicenseContent").classList.remove("invisible"); + document.getElementById("aboutLicenseContent").classList.remove("invisible"); }); - $("aboutSoftwareUsedLink").addEventListener("click", () => { + document.getElementById("aboutSoftwareUsedLink").addEventListener("click", () => { Array.prototype.forEach.call(document.querySelectorAll(".aboutTabContent"), (tab => tab.classList.add("invisible"))); - $("aboutSoftwareUsedContent").classList.remove("invisible"); + document.getElementById("aboutSoftwareUsedContent").classList.remove("invisible"); }); })(); diff --git a/src/webui/www/private/views/installsearchplugin.html b/src/webui/www/private/views/installsearchplugin.html index de77a46e1..74e1b7aaa 100644 --- a/src/webui/www/private/views/installsearchplugin.html +++ b/src/webui/www/private/views/installsearchplugin.html @@ -61,11 +61,11 @@ } }); - $("newPluginPath").select(); + document.getElementById("newPluginPath").select(); }; const newPluginOk = () => { - const path = $("newPluginPath").value.trim(); + const path = document.getElementById("newPluginPath").value.trim(); if (path) { fetch("api/v2/search/installPlugin", { method: "POST", diff --git a/src/webui/www/private/views/log.html b/src/webui/www/private/views/log.html index bbafca8cc..b7944b784 100644 --- a/src/webui/www/private/views/log.html +++ b/src/webui/www/private/views/log.html @@ -188,7 +188,7 @@ let selectedLogLevels = JSON.parse(LocalPreferences.get("qbt_selected_log_levels")) || ["1", "2", "4", "8"]; const init = () => { - for (const option of $("logLevelSelect").options) + for (const option of document.getElementById("logLevelSelect").options) option.toggleAttribute("selected", selectedLogLevels.includes(option.value)); selectBox = new vanillaSelectBox("#logLevelSelect", { @@ -282,7 +282,7 @@ }; const filterTextChanged = () => { - const value = $("filterTextInput").value.trim(); + const value = document.getElementById("filterTextInput").value.trim(); if (inputtedFilterText !== value) { inputtedFilterText = value; logFilterChanged(); @@ -306,14 +306,14 @@ currentSelectedTab = tab; if (currentSelectedTab === "main") { selectBox.enable(); - $("logMessageView").classList.remove("invisible"); - $("logPeerView").classList.add("invisible"); + document.getElementById("logMessageView").classList.remove("invisible"); + document.getElementById("logPeerView").classList.add("invisible"); resetTableTimer("peer"); } else { selectBox.disable(); - $("logMessageView").classList.add("invisible"); - $("logPeerView").classList.remove("invisible"); + document.getElementById("logMessageView").classList.add("invisible"); + document.getElementById("logPeerView").classList.remove("invisible"); resetTableTimer("main"); } @@ -331,8 +331,8 @@ if (curTab === undefined) curTab = currentSelectedTab; - $("numFilteredLogs").textContent = tableInfo[curTab].instance.filteredLength; - $("numTotalLogs").textContent = tableInfo[curTab].instance.getRowSize(); + document.getElementById("numFilteredLogs").textContent = tableInfo[curTab].instance.filteredLength; + document.getElementById("numTotalLogs").textContent = tableInfo[curTab].instance.getRowSize(); }; const syncLogData = (curTab) => { @@ -368,7 +368,7 @@ }) .then(async (response) => { if (!response.ok) { - const errorDiv = $("error_div"); + const errorDiv = document.getElementById("error_div"); if (errorDiv) errorDiv.textContent = "QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]"; tableInfo[curTab].progress = false; @@ -376,9 +376,9 @@ return; } - $("error_div").textContent = ""; + document.getElementById("error_div").textContent = ""; - if ($("logTabColumn").classList.contains("invisible")) + if (document.getElementById("logTabColumn").classList.contains("invisible")) return; const responseJSON = await response.json(); diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 883efdbaa..60903e70c 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -1801,32 +1801,32 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD }; const updateFileLogEnabled = () => { - const isFileLogEnabled = $("filelog_checkbox").checked; - $("filelog_save_path_input").disabled = !isFileLogEnabled; - $("filelog_backup_checkbox").disabled = !isFileLogEnabled; - $("filelog_delete_old_checkbox").disabled = !isFileLogEnabled; + const isFileLogEnabled = document.getElementById("filelog_checkbox").checked; + document.getElementById("filelog_save_path_input").disabled = !isFileLogEnabled; + document.getElementById("filelog_backup_checkbox").disabled = !isFileLogEnabled; + document.getElementById("filelog_delete_old_checkbox").disabled = !isFileLogEnabled; updateFileLogBackupEnabled(); updateFileLogDeleteEnabled(); }; const updateFileLogBackupEnabled = () => { - const pros = $("filelog_backup_checkbox").getProperties("disabled", "checked"); - $("filelog_max_size_input").disabled = pros.disabled || !pros.checked; + const pros = document.getElementById("filelog_backup_checkbox").getProperties("disabled", "checked"); + document.getElementById("filelog_max_size_input").disabled = pros.disabled || !pros.checked; }; const updateFileLogDeleteEnabled = () => { - const pros = $("filelog_delete_old_checkbox").getProperties("disabled", "checked"); - $("filelog_age_input").disabled = pros.disabled || !pros.checked; - $("filelog_age_type_select").disabled = pros.disabled || !pros.checked; + const pros = document.getElementById("filelog_delete_old_checkbox").getProperties("disabled", "checked"); + document.getElementById("filelog_age_input").disabled = pros.disabled || !pros.checked; + document.getElementById("filelog_age_type_select").disabled = pros.disabled || !pros.checked; }; // Downloads tab let watchedFoldersTable; const updateTempDirEnabled = () => { - const isTempDirEnabled = $("temppath_checkbox").checked; - $("temppath_text").disabled = !isTempDirEnabled; + const isTempDirEnabled = document.getElementById("temppath_checkbox").checked; + document.getElementById("temppath_text").disabled = !isTempDirEnabled; }; const changeWatchFolderSelect = (item) => { @@ -1843,7 +1843,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD }; const addWatchFolder = (folder = "", sel = "default_folder", other = "") => { - const pos = $("watched_folders_tab").getChildren("tbody")[0].getChildren("tr").length; + const pos = document.getElementById("watched_folders_tab").getChildren("tbody")[0].getChildren("tr").length; const myinput = ``; const disableInput = (sel !== "other"); const mycb = `
` @@ -1857,28 +1857,28 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD + `
`; watchedFoldersTable.push([myinput, mycb]); - $(`cb_watch_${pos}`).value = sel; + document.getElementById(`cb_watch_${pos}`).value = sel; if (disableInput) { - const elt = $(`cb_watch_${pos}`); + const elt = document.getElementById(`cb_watch_${pos}`); other = elt.options[elt.selectedIndex].textContent; } - $(`cb_watch_txt_${pos}`).value = other; + document.getElementById(`cb_watch_txt_${pos}`).value = other; // hide previous img if (pos > 0) - $(`addFolderImg_${pos - 1}`).style.display = "none"; + document.getElementById(`addFolderImg_${pos - 1}`).style.display = "none"; }; const getWatchedFolders = () => { const folders = {}; - const entryCount = $("watched_folders_tab").getChildren("tbody")[0].getChildren("tr").length; + const entryCount = document.getElementById("watched_folders_tab").getChildren("tbody")[0].getChildren("tr").length; for (let i = 0; i < entryCount; ++i) { - const fpath = $(`text_watch_${i}`).value.trim(); + const fpath = document.getElementById(`text_watch_${i}`).value.trim(); if (fpath.length <= 0) continue; - const sel = $(`cb_watch_${i}`).value.trim(); + const sel = document.getElementById(`cb_watch_${i}`).value.trim(); let other; switch (sel) { @@ -1889,7 +1889,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD other = 1; break; case "other": - other = $(`cb_watch_txt_${i}`).value.trim(); + other = document.getElementById(`cb_watch_txt_${i}`).value.trim(); break; }; @@ -1900,39 +1900,39 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD }; const updateExcludedFileNamesEnabled = () => { - const isAExcludedFileNamesEnabled = $("excludedFileNamesCheckbox").checked; - $("excludedFileNamesTextarea").disabled = !isAExcludedFileNamesEnabled; + const isAExcludedFileNamesEnabled = document.getElementById("excludedFileNamesCheckbox").checked; + document.getElementById("excludedFileNamesTextarea").disabled = !isAExcludedFileNamesEnabled; }; const updateExportDirEnabled = () => { - const isExportDirEnabled = $("exportdir_checkbox").checked; - $("exportdir_text").disabled = !isExportDirEnabled; + const isExportDirEnabled = document.getElementById("exportdir_checkbox").checked; + document.getElementById("exportdir_text").disabled = !isExportDirEnabled; }; const updateExportDirFinEnabled = () => { - const isExportDirFinEnabled = $("exportdirfin_checkbox").checked; - $("exportdirfin_text").disabled = !isExportDirFinEnabled; + const isExportDirFinEnabled = document.getElementById("exportdirfin_checkbox").checked; + document.getElementById("exportdirfin_text").disabled = !isExportDirFinEnabled; }; const updateMailNotification = () => { - const isMailNotificationEnabled = $("mail_notification_checkbox").checked; - $("src_email_txt").disabled = !isMailNotificationEnabled; - $("dest_email_txt").disabled = !isMailNotificationEnabled; - $("smtp_server_txt").disabled = !isMailNotificationEnabled; - $("mail_ssl_checkbox").disabled = !isMailNotificationEnabled; - $("mail_auth_checkbox").disabled = !isMailNotificationEnabled; - $("mail_test_button").disabled = !isMailNotificationEnabled; + const isMailNotificationEnabled = document.getElementById("mail_notification_checkbox").checked; + document.getElementById("src_email_txt").disabled = !isMailNotificationEnabled; + document.getElementById("dest_email_txt").disabled = !isMailNotificationEnabled; + document.getElementById("smtp_server_txt").disabled = !isMailNotificationEnabled; + document.getElementById("mail_ssl_checkbox").disabled = !isMailNotificationEnabled; + document.getElementById("mail_auth_checkbox").disabled = !isMailNotificationEnabled; + document.getElementById("mail_test_button").disabled = !isMailNotificationEnabled; if (!isMailNotificationEnabled) { - $("mail_auth_checkbox").checked = !isMailNotificationEnabled; + document.getElementById("mail_auth_checkbox").checked = !isMailNotificationEnabled; updateMailAuthSettings(); } }; const updateMailAuthSettings = () => { - const isMailAuthEnabled = $("mail_auth_checkbox").checked; - $("mail_username_text").disabled = !isMailAuthEnabled; - $("mail_password_text").disabled = !isMailAuthEnabled; + const isMailAuthEnabled = document.getElementById("mail_auth_checkbox").checked; + document.getElementById("mail_username_text").disabled = !isMailAuthEnabled; + document.getElementById("mail_password_text").disabled = !isMailAuthEnabled; }; const sendTestEmail = () => { @@ -1950,167 +1950,167 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD }; const updateAutoRunOnTorrentAdded = () => { - const isAutoRunOnTorrentAddedEnabled = $("autorunOnTorrentAddedCheckbox").checked; - $("autorunOnTorrentAddedProgram").disabled = !isAutoRunOnTorrentAddedEnabled; + const isAutoRunOnTorrentAddedEnabled = document.getElementById("autorunOnTorrentAddedCheckbox").checked; + document.getElementById("autorunOnTorrentAddedProgram").disabled = !isAutoRunOnTorrentAddedEnabled; }; const updateAutoRun = () => { - const isAutoRunEnabled = $("autorun_checkbox").checked; - $("autorunProg_txt").disabled = !isAutoRunEnabled; + const isAutoRunEnabled = document.getElementById("autorun_checkbox").checked; + document.getElementById("autorunProg_txt").disabled = !isAutoRunEnabled; }; // Connection tab const updateMaxConnecEnabled = () => { - const isMaxConnecEnabled = $("maxConnectionsCheckbox").checked; - $("maxConnectionsValue").disabled = !isMaxConnecEnabled; + const isMaxConnecEnabled = document.getElementById("maxConnectionsCheckbox").checked; + document.getElementById("maxConnectionsValue").disabled = !isMaxConnecEnabled; }; const updateMaxConnecPerTorrentEnabled = () => { - const isMaxConnecPerTorrentEnabled = $("maxConnectionsPerTorrentCheckbox").checked; - $("maxConnectionsPerTorrentValue").disabled = !isMaxConnecPerTorrentEnabled; + const isMaxConnecPerTorrentEnabled = document.getElementById("maxConnectionsPerTorrentCheckbox").checked; + document.getElementById("maxConnectionsPerTorrentValue").disabled = !isMaxConnecPerTorrentEnabled; }; const updateMaxUploadsEnabled = () => { - const isMaxUploadsEnabled = $("maxUploadsCheckbox").checked; - $("max_uploads_value").disabled = !isMaxUploadsEnabled; + const isMaxUploadsEnabled = document.getElementById("maxUploadsCheckbox").checked; + document.getElementById("max_uploads_value").disabled = !isMaxUploadsEnabled; }; const updateMaxUploadsPerTorrentEnabled = () => { - const isMaxUploadsPerTorrentEnabled = $("maxUploadsPerTorrentCheckbox").checked; - $("maxUploadsPerTorrentValue").disabled = !isMaxUploadsPerTorrentEnabled; + const isMaxUploadsPerTorrentEnabled = document.getElementById("maxUploadsPerTorrentCheckbox").checked; + document.getElementById("maxUploadsPerTorrentValue").disabled = !isMaxUploadsPerTorrentEnabled; }; const updateI2PSettingsEnabled = () => { - const isI2PEnabled = $("i2pEnabledCheckbox").checked; - $("i2pAddress").disabled = !isI2PEnabled; - $("i2pPort").disabled = !isI2PEnabled; - $("i2pMixedMode").disabled = !isI2PEnabled; + const isI2PEnabled = document.getElementById("i2pEnabledCheckbox").checked; + document.getElementById("i2pAddress").disabled = !isI2PEnabled; + document.getElementById("i2pPort").disabled = !isI2PEnabled; + document.getElementById("i2pMixedMode").disabled = !isI2PEnabled; }; const updatePeerProxySettings = () => { - const proxyType = $("peer_proxy_type_select").value; + const proxyType = document.getElementById("peer_proxy_type_select").value; const isProxyDisabled = (proxyType === "None"); const isProxySocks4 = (proxyType === "SOCKS4"); - $("peer_proxy_host_text").disabled = isProxyDisabled; - $("peer_proxy_port_value").disabled = isProxyDisabled; + document.getElementById("peer_proxy_host_text").disabled = isProxyDisabled; + document.getElementById("peer_proxy_port_value").disabled = isProxyDisabled; - $("peer_proxy_auth_checkbox").disabled = (isProxyDisabled || isProxySocks4); - $("proxy_bittorrent_checkbox").disabled = isProxyDisabled; - $("use_peer_proxy_checkbox").disabled = (isProxyDisabled || !$("proxy_bittorrent_checkbox").checked); - $("proxyHostnameLookupCheckbox").disabled = (isProxyDisabled || isProxySocks4); - $("proxy_rss_checkbox").disabled = (isProxyDisabled || isProxySocks4); - $("proxy_misc_checkbox").disabled = (isProxyDisabled || isProxySocks4); + document.getElementById("peer_proxy_auth_checkbox").disabled = (isProxyDisabled || isProxySocks4); + document.getElementById("proxy_bittorrent_checkbox").disabled = isProxyDisabled; + document.getElementById("use_peer_proxy_checkbox").disabled = (isProxyDisabled || !document.getElementById("proxy_bittorrent_checkbox").checked); + document.getElementById("proxyHostnameLookupCheckbox").disabled = (isProxyDisabled || isProxySocks4); + document.getElementById("proxy_rss_checkbox").disabled = (isProxyDisabled || isProxySocks4); + document.getElementById("proxy_misc_checkbox").disabled = (isProxyDisabled || isProxySocks4); updatePeerProxyAuthSettings(); }; const updatePeerProxyAuthSettings = () => { - const proxyType = $("peer_proxy_type_select").value; + const proxyType = document.getElementById("peer_proxy_type_select").value; const isProxyDisabled = (proxyType === "None"); - const isPeerProxyAuthEnabled = (!$("peer_proxy_auth_checkbox").disabled && $("peer_proxy_auth_checkbox").checked); - $("peer_proxy_username_text").disabled = (isProxyDisabled || !isPeerProxyAuthEnabled); - $("peer_proxy_password_text").disabled = (isProxyDisabled || !isPeerProxyAuthEnabled); + const isPeerProxyAuthEnabled = (!document.getElementById("peer_proxy_auth_checkbox").disabled && document.getElementById("peer_proxy_auth_checkbox").checked); + document.getElementById("peer_proxy_username_text").disabled = (isProxyDisabled || !isPeerProxyAuthEnabled); + document.getElementById("peer_proxy_password_text").disabled = (isProxyDisabled || !isPeerProxyAuthEnabled); }; const updateFilterSettings = () => { - const isIPFilterEnabled = $("ipfilter_text_checkbox").checked; - $("ipfilter_text").disabled = !isIPFilterEnabled; + const isIPFilterEnabled = document.getElementById("ipfilter_text_checkbox").checked; + document.getElementById("ipfilter_text").disabled = !isIPFilterEnabled; }; // Speed tab const updateSchedulingEnabled = () => { - const isLimitSchedulingEnabled = $("limitSchedulingCheckbox").checked; - $("schedule_from_hour").disabled = !isLimitSchedulingEnabled; - $("schedule_from_min").disabled = !isLimitSchedulingEnabled; - $("schedule_to_hour").disabled = !isLimitSchedulingEnabled; - $("schedule_to_min").disabled = !isLimitSchedulingEnabled; - $("schedule_freq_select").disabled = !isLimitSchedulingEnabled; + const isLimitSchedulingEnabled = document.getElementById("limitSchedulingCheckbox").checked; + document.getElementById("schedule_from_hour").disabled = !isLimitSchedulingEnabled; + document.getElementById("schedule_from_min").disabled = !isLimitSchedulingEnabled; + document.getElementById("schedule_to_hour").disabled = !isLimitSchedulingEnabled; + document.getElementById("schedule_to_min").disabled = !isLimitSchedulingEnabled; + document.getElementById("schedule_freq_select").disabled = !isLimitSchedulingEnabled; }; // Bittorrent tab const updateQueueingSystem = () => { - const isQueueingEnabled = $("queueingCheckbox").checked; - $("maxActiveDlValue").disabled = !isQueueingEnabled; - $("maxActiveUpValue").disabled = !isQueueingEnabled; - $("maxActiveToValue").disabled = !isQueueingEnabled; - $("dontCountSlowTorrentsCheckbox").disabled = !isQueueingEnabled; + const isQueueingEnabled = document.getElementById("queueingCheckbox").checked; + document.getElementById("maxActiveDlValue").disabled = !isQueueingEnabled; + document.getElementById("maxActiveUpValue").disabled = !isQueueingEnabled; + document.getElementById("maxActiveToValue").disabled = !isQueueingEnabled; + document.getElementById("dontCountSlowTorrentsCheckbox").disabled = !isQueueingEnabled; updateSlowTorrentsSettings(); }; const updateSlowTorrentsSettings = () => { - const isDontCountSlowTorrentsEnabled = (!$("dontCountSlowTorrentsCheckbox").disabled) && $("dontCountSlowTorrentsCheckbox").checked; - $("dlRateThresholdValue").disabled = !isDontCountSlowTorrentsEnabled; - $("ulRateThresholdValue").disabled = !isDontCountSlowTorrentsEnabled; - $("torrentInactiveTimerValue").disabled = !isDontCountSlowTorrentsEnabled; + const isDontCountSlowTorrentsEnabled = (!document.getElementById("dontCountSlowTorrentsCheckbox").disabled) && document.getElementById("dontCountSlowTorrentsCheckbox").checked; + document.getElementById("dlRateThresholdValue").disabled = !isDontCountSlowTorrentsEnabled; + document.getElementById("ulRateThresholdValue").disabled = !isDontCountSlowTorrentsEnabled; + document.getElementById("torrentInactiveTimerValue").disabled = !isDontCountSlowTorrentsEnabled; }; const updateMaxRatioTimeEnabled = () => { - const isMaxRatioEnabled = $("maxRatioCheckbox").checked; - $("maxRatioValue").disabled = !isMaxRatioEnabled; + const isMaxRatioEnabled = document.getElementById("maxRatioCheckbox").checked; + document.getElementById("maxRatioValue").disabled = !isMaxRatioEnabled; - const isMaxSeedingTimeEnabled = $("maxSeedingTimeCheckbox").checked; - $("maxSeedingTimeValue").disabled = !isMaxSeedingTimeEnabled; + const isMaxSeedingTimeEnabled = document.getElementById("maxSeedingTimeCheckbox").checked; + document.getElementById("maxSeedingTimeValue").disabled = !isMaxSeedingTimeEnabled; - const isMaxInactiveSeedingTimeEnabled = $("maxInactiveSeedingTimeCheckbox").checked; - $("maxInactiveSeedingTimeValue").disabled = !isMaxInactiveSeedingTimeEnabled; + const isMaxInactiveSeedingTimeEnabled = document.getElementById("maxInactiveSeedingTimeCheckbox").checked; + document.getElementById("maxInactiveSeedingTimeValue").disabled = !isMaxInactiveSeedingTimeEnabled; - $("maxRatioSelect").disabled = !(isMaxRatioEnabled || isMaxSeedingTimeEnabled || isMaxInactiveSeedingTimeEnabled); + document.getElementById("maxRatioSelect").disabled = !(isMaxRatioEnabled || isMaxSeedingTimeEnabled || isMaxInactiveSeedingTimeEnabled); }; const updateAddTrackersEnabled = () => { - const isAddTrackersEnabled = $("add_trackers_checkbox").checked; - $("add_trackers_textarea").disabled = !isAddTrackersEnabled; + const isAddTrackersEnabled = document.getElementById("add_trackers_checkbox").checked; + document.getElementById("add_trackers_textarea").disabled = !isAddTrackersEnabled; }; const updateAddTrackersFromURLEnabled = () => { - const isAddTrackersFromURLEnabled = $("addTrackersFromURLCheckbox").checked; - $("addTrackersURL").disabled = !isAddTrackersFromURLEnabled; + const isAddTrackersFromURLEnabled = document.getElementById("addTrackersFromURLCheckbox").checked; + document.getElementById("addTrackersURL").disabled = !isAddTrackersFromURLEnabled; }; // WebUI tab const updateHttpsSettings = () => { - const isUseHttpsEnabled = $("use_https_checkbox").checked; - $("ssl_cert_text").disabled = !isUseHttpsEnabled; - $("ssl_key_text").disabled = !isUseHttpsEnabled; + const isUseHttpsEnabled = document.getElementById("use_https_checkbox").checked; + document.getElementById("ssl_cert_text").disabled = !isUseHttpsEnabled; + document.getElementById("ssl_key_text").disabled = !isUseHttpsEnabled; }; const updateBypasssAuthSettings = () => { - const isBypassAuthSubnetWhitelistEnabled = $("bypass_auth_subnet_whitelist_checkbox").checked; - $("bypass_auth_subnet_whitelist_textarea").disabled = !isBypassAuthSubnetWhitelistEnabled; + const isBypassAuthSubnetWhitelistEnabled = document.getElementById("bypass_auth_subnet_whitelist_checkbox").checked; + document.getElementById("bypass_auth_subnet_whitelist_textarea").disabled = !isBypassAuthSubnetWhitelistEnabled; }; const updateAlternativeWebUISettings = () => { - const isUseAlternativeWebUIEnabled = $("use_alt_webui_checkbox").checked; - $("webui_files_location_textarea").disabled = !isUseAlternativeWebUIEnabled; + const isUseAlternativeWebUIEnabled = document.getElementById("use_alt_webui_checkbox").checked; + document.getElementById("webui_files_location_textarea").disabled = !isUseAlternativeWebUIEnabled; }; const updateHostHeaderValidationSettings = () => { - const isHostHeaderValidationEnabled = $("host_header_validation_checkbox").checked; - $("webuiDomainTextarea").disabled = !isHostHeaderValidationEnabled; + const isHostHeaderValidationEnabled = document.getElementById("host_header_validation_checkbox").checked; + document.getElementById("webuiDomainTextarea").disabled = !isHostHeaderValidationEnabled; }; const updateWebUICustomHTTPHeadersSettings = () => { - const isEnabled = $("webUIUseCustomHTTPHeadersCheckbox").checked; - $("webUICustomHTTPHeadersTextarea").disabled = !isEnabled; + const isEnabled = document.getElementById("webUIUseCustomHTTPHeadersCheckbox").checked; + document.getElementById("webUICustomHTTPHeadersTextarea").disabled = !isEnabled; }; const updateWebUIReverseProxySettings = () => { - const isEnabled = $("webUIReverseProxySupportCheckbox").checked; - $("webUIReverseProxiesListTextarea").disabled = !isEnabled; + const isEnabled = document.getElementById("webUIReverseProxySupportCheckbox").checked; + document.getElementById("webUIReverseProxiesListTextarea").disabled = !isEnabled; }; const updateDynDnsSettings = () => { - const isDynDnsEnabled = $("use_dyndns_checkbox").checked; - $("dyndns_select").disabled = !isDynDnsEnabled; - $("dyndns_domain_text").disabled = !isDynDnsEnabled; - $("dyndns_username_text").disabled = !isDynDnsEnabled; - $("dyndns_password_text").disabled = !isDynDnsEnabled; + const isDynDnsEnabled = document.getElementById("use_dyndns_checkbox").checked; + document.getElementById("dyndns_select").disabled = !isDynDnsEnabled; + document.getElementById("dyndns_domain_text").disabled = !isDynDnsEnabled; + document.getElementById("dyndns_username_text").disabled = !isDynDnsEnabled; + document.getElementById("dyndns_password_text").disabled = !isDynDnsEnabled; }; const registerDynDns = () => { - if (Number($("dyndns_select").value) === 1) + if (Number(document.getElementById("dyndns_select").value) === 1) window.open("http://www.no-ip.com/services/managed_dns/free_dynamic_dns.html", "NO-IP Registration"); else window.open("https://www.dyndns.com/account/services/hosts/add.html", "DynDNS Registration"); @@ -2120,7 +2120,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD const min = 1024; const max = 65535; const port = Math.floor(Math.random() * (max - min + 1) + min); - $("portValue").value = port; + document.getElementById("portValue").value = port; }; const time_padding = (val) => { @@ -2152,11 +2152,11 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD if (default_iface && !ifaces.some((item) => item.value === default_iface)) ifaces.push({ name: default_iface_name || default_iface, value: default_iface }); - $("networkInterface").options.add(new Option("QBT_TR(Any interface)QBT_TR[CONTEXT=OptionsDialog]", "")); + document.getElementById("networkInterface").options.add(new Option("QBT_TR(Any interface)QBT_TR[CONTEXT=OptionsDialog]", "")); ifaces.forEach((item, index) => { - $("networkInterface").options.add(new Option(item.name, item.value)); + document.getElementById("networkInterface").options.add(new Option(item.name, item.value)); }); - $("networkInterface").value = default_iface; + document.getElementById("networkInterface").value = default_iface; }); }; @@ -2181,26 +2181,26 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD if (!addresses) return; - $("optionalIPAddressToBind").options.add(new Option("QBT_TR(All addresses)QBT_TR[CONTEXT=OptionDialog]", "")); - $("optionalIPAddressToBind").options.add(new Option("QBT_TR(All IPv4 addresses)QBT_TR[CONTEXT=OptionDialog]", "0.0.0.0")); - $("optionalIPAddressToBind").options.add(new Option("QBT_TR(All IPv6 addresses)QBT_TR[CONTEXT=OptionDialog]", "::")); + document.getElementById("optionalIPAddressToBind").options.add(new Option("QBT_TR(All addresses)QBT_TR[CONTEXT=OptionDialog]", "")); + document.getElementById("optionalIPAddressToBind").options.add(new Option("QBT_TR(All IPv4 addresses)QBT_TR[CONTEXT=OptionDialog]", "0.0.0.0")); + document.getElementById("optionalIPAddressToBind").options.add(new Option("QBT_TR(All IPv6 addresses)QBT_TR[CONTEXT=OptionDialog]", "::")); addresses.forEach((item, index) => { - $("optionalIPAddressToBind").options.add(new Option(item, item)); + document.getElementById("optionalIPAddressToBind").options.add(new Option(item, item)); }); - $("optionalIPAddressToBind").value = default_addr; + document.getElementById("optionalIPAddressToBind").value = default_addr; }); }; const updateWebuiLocaleSelect = (selected) => { const languages = []; - for (let i = 0; i < $("locale_select").options.length; i++) - languages.push($("locale_select").options[i].value); + for (let i = 0; i < document.getElementById("locale_select").options.length; i++) + languages.push(document.getElementById("locale_select").options[i].value); if (!languages.includes(selected)) { const lang = selected.split("_", 1)[0]; selected = languages.includes(lang) ? lang : "en"; } - $("locale_select").value = selected; + document.getElementById("locale_select").value = selected; }; const updateColoSchemeSelect = () => { @@ -2222,22 +2222,22 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD // Language updateWebuiLocaleSelect(pref.locale); updateColoSchemeSelect(); - $("statusBarExternalIP").checked = pref.status_bar_external_ip; - $("performanceWarning").checked = pref.performance_warning; + document.getElementById("statusBarExternalIP").checked = pref.status_bar_external_ip; + document.getElementById("performanceWarning").checked = pref.performance_warning; document.getElementById("displayFullURLTrackerColumn").checked = (LocalPreferences.get("full_url_tracker_column", "false") === "true"); document.getElementById("useVirtualList").checked = (LocalPreferences.get("use_virtual_list", "false") === "true"); document.getElementById("hideZeroFiltersCheckbox").checked = (LocalPreferences.get("hide_zero_status_filters", "false") === "true"); - $("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1"); - $("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1"); + document.getElementById("dblclickDownloadSelect").value = LocalPreferences.get("dblclick_download", "1"); + document.getElementById("dblclickCompleteSelect").value = LocalPreferences.get("dblclick_complete", "1"); document.getElementById("confirmTorrentDeletion").checked = pref.confirm_torrent_deletion; document.getElementById("useAltRowColorsInput").checked = (LocalPreferences.get("use_alt_row_colors", "true") === "true"); - $("filelog_checkbox").checked = pref.file_log_enabled; - $("filelog_save_path_input").value = pref.file_log_path; - $("filelog_backup_checkbox").checked = pref.file_log_backup_enabled; - $("filelog_max_size_input").value = pref.file_log_max_size; - $("filelog_delete_old_checkbox").checked = pref.file_log_delete_old; - $("filelog_age_input").value = pref.file_log_age; - $("filelog_age_type_select").value = pref.file_log_age_type; + document.getElementById("filelog_checkbox").checked = pref.file_log_enabled; + document.getElementById("filelog_save_path_input").value = pref.file_log_path; + document.getElementById("filelog_backup_checkbox").checked = pref.file_log_backup_enabled; + document.getElementById("filelog_max_size_input").value = pref.file_log_max_size; + document.getElementById("filelog_delete_old_checkbox").checked = pref.file_log_delete_old; + document.getElementById("filelog_age_input").value = pref.file_log_age; + document.getElementById("filelog_age_type_select").value = pref.file_log_age_type; updateFileLogEnabled(); // Downloads tab @@ -2254,9 +2254,9 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD index = 2; break; } - $("contentlayout_select").getChildren("option")[index].selected = true; - $("addToTopOfQueueCheckbox").checked = pref.add_to_top_of_queue; - $("dontstartdownloads_checkbox").checked = pref.add_stopped_enabled; + document.getElementById("contentlayout_select").getChildren("option")[index].selected = true; + document.getElementById("addToTopOfQueueCheckbox").checked = pref.add_to_top_of_queue; + document.getElementById("dontstartdownloads_checkbox").checked = pref.add_stopped_enabled; switch (pref.torrent_stop_condition) { case "None": index = 0; @@ -2268,41 +2268,41 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD index = 2; break; } - $("stopConditionSelect").getChildren("option")[index].selected = true; + document.getElementById("stopConditionSelect").getChildren("option")[index].selected = true; document.getElementById("mergeTrackersInput").checked = pref.merge_trackers; - $("deletetorrentfileafter_checkbox").checked = pref.auto_delete_mode; + document.getElementById("deletetorrentfileafter_checkbox").checked = pref.auto_delete_mode; - $("preallocateall_checkbox").checked = pref.preallocate_all; - $("appendext_checkbox").checked = pref.incomplete_files_ext; - $("unwantedfolder_checkbox").checked = pref.use_unwanted_folder; + document.getElementById("preallocateall_checkbox").checked = pref.preallocate_all; + document.getElementById("appendext_checkbox").checked = pref.incomplete_files_ext; + document.getElementById("unwantedfolder_checkbox").checked = pref.use_unwanted_folder; // Saving Management - $("default_tmm_combobox").value = pref.auto_tmm_enabled; - $("torrent_changed_tmm_combobox").value = pref.torrent_changed_tmm_enabled; - $("save_path_changed_tmm_combobox").value = pref.save_path_changed_tmm_enabled; - $("category_changed_tmm_combobox").value = pref.category_changed_tmm_enabled; - $("use_subcategories_checkbox").checked = pref.use_subcategories; + document.getElementById("default_tmm_combobox").value = pref.auto_tmm_enabled; + document.getElementById("torrent_changed_tmm_combobox").value = pref.torrent_changed_tmm_enabled; + document.getElementById("save_path_changed_tmm_combobox").value = pref.save_path_changed_tmm_enabled; + document.getElementById("category_changed_tmm_combobox").value = pref.category_changed_tmm_enabled; + document.getElementById("use_subcategories_checkbox").checked = pref.use_subcategories; document.getElementById("categoryPathsManualModeCheckbox").checked = pref.use_category_paths_in_manual_mode; - $("savepath_text").value = pref.save_path; - $("temppath_checkbox").checked = pref.temp_path_enabled; - $("temppath_text").value = pref.temp_path; + document.getElementById("savepath_text").value = pref.save_path; + document.getElementById("temppath_checkbox").checked = pref.temp_path_enabled; + document.getElementById("temppath_text").value = pref.temp_path; updateTempDirEnabled(); if (pref.export_dir !== "") { - $("exportdir_checkbox").checked = true; - $("exportdir_text").value = pref.export_dir; + document.getElementById("exportdir_checkbox").checked = true; + document.getElementById("exportdir_text").value = pref.export_dir; } else { - $("exportdir_checkbox").checked = false; - $("exportdir_text").value = ""; + document.getElementById("exportdir_checkbox").checked = false; + document.getElementById("exportdir_text").value = ""; } updateExportDirEnabled(); if (pref.export_dir_fin !== "") { - $("exportdirfin_checkbox").checked = true; - $("exportdirfin_text").value = pref.export_dir_fin; + document.getElementById("exportdirfin_checkbox").checked = true; + document.getElementById("exportdirfin_text").value = pref.export_dir_fin; } else { - $("exportdirfin_checkbox").checked = false; - $("exportdirfin_text").value = ""; + document.getElementById("exportdirfin_checkbox").checked = false; + document.getElementById("exportdirfin_text").value = ""; } updateExportDirFinEnabled(); @@ -2323,159 +2323,159 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD addWatchFolder(); // Excluded file names - $("excludedFileNamesCheckbox").checked = pref.excluded_file_names_enabled; - $("excludedFileNamesTextarea").value = pref.excluded_file_names; + document.getElementById("excludedFileNamesCheckbox").checked = pref.excluded_file_names_enabled; + document.getElementById("excludedFileNamesTextarea").value = pref.excluded_file_names; // Email notification upon download completion - $("mail_notification_checkbox").checked = pref.mail_notification_enabled; - $("src_email_txt").value = pref.mail_notification_sender; - $("dest_email_txt").value = pref.mail_notification_email; - $("smtp_server_txt").value = pref.mail_notification_smtp; - $("mail_ssl_checkbox").checked = pref.mail_notification_ssl_enabled; - $("mail_auth_checkbox").checked = pref.mail_notification_auth_enabled; - $("mail_username_text").value = pref.mail_notification_username; - $("mail_password_text").value = pref.mail_notification_password; + document.getElementById("mail_notification_checkbox").checked = pref.mail_notification_enabled; + document.getElementById("src_email_txt").value = pref.mail_notification_sender; + document.getElementById("dest_email_txt").value = pref.mail_notification_email; + document.getElementById("smtp_server_txt").value = pref.mail_notification_smtp; + document.getElementById("mail_ssl_checkbox").checked = pref.mail_notification_ssl_enabled; + document.getElementById("mail_auth_checkbox").checked = pref.mail_notification_auth_enabled; + document.getElementById("mail_username_text").value = pref.mail_notification_username; + document.getElementById("mail_password_text").value = pref.mail_notification_password; updateMailNotification(); updateMailAuthSettings(); // Run an external program on torrent added - $("autorunOnTorrentAddedCheckbox").checked = pref.autorun_on_torrent_added_enabled; - $("autorunOnTorrentAddedProgram").value = pref.autorun_on_torrent_added_program; + document.getElementById("autorunOnTorrentAddedCheckbox").checked = pref.autorun_on_torrent_added_enabled; + document.getElementById("autorunOnTorrentAddedProgram").value = pref.autorun_on_torrent_added_program; updateAutoRunOnTorrentAdded(); // Run an external program on torrent finished - $("autorun_checkbox").checked = pref.autorun_enabled; - $("autorunProg_txt").value = pref.autorun_program; + document.getElementById("autorun_checkbox").checked = pref.autorun_enabled; + document.getElementById("autorunProg_txt").value = pref.autorun_program; updateAutoRun(); // Connection tab // Listening Port - $("portValue").value = Number(pref.listen_port); - $("upnpCheckbox").checked = pref.upnp; + document.getElementById("portValue").value = Number(pref.listen_port); + document.getElementById("upnpCheckbox").checked = pref.upnp; // Connections Limits const maxConnec = Number(pref.max_connec); if (maxConnec <= 0) { - $("maxConnectionsCheckbox").checked = false; - $("maxConnectionsValue").value = 500; + document.getElementById("maxConnectionsCheckbox").checked = false; + document.getElementById("maxConnectionsValue").value = 500; } else { - $("maxConnectionsCheckbox").checked = true; - $("maxConnectionsValue").value = maxConnec; + document.getElementById("maxConnectionsCheckbox").checked = true; + document.getElementById("maxConnectionsValue").value = maxConnec; } updateMaxConnecEnabled(); const maxConnecPerTorrent = Number(pref.max_connec_per_torrent); if (maxConnecPerTorrent <= 0) { - $("maxConnectionsPerTorrentCheckbox").checked = false; - $("maxConnectionsPerTorrentValue").value = 100; + document.getElementById("maxConnectionsPerTorrentCheckbox").checked = false; + document.getElementById("maxConnectionsPerTorrentValue").value = 100; } else { - $("maxConnectionsPerTorrentCheckbox").checked = true; - $("maxConnectionsPerTorrentValue").value = maxConnecPerTorrent; + document.getElementById("maxConnectionsPerTorrentCheckbox").checked = true; + document.getElementById("maxConnectionsPerTorrentValue").value = maxConnecPerTorrent; } updateMaxConnecPerTorrentEnabled(); const maxUploads = Number(pref.max_uploads); if (maxUploads <= 0) { - $("maxUploadsCheckbox").checked = false; - $("max_uploads_value").value = 8; + document.getElementById("maxUploadsCheckbox").checked = false; + document.getElementById("max_uploads_value").value = 8; } else { - $("maxUploadsCheckbox").checked = true; - $("max_uploads_value").value = maxUploads; + document.getElementById("maxUploadsCheckbox").checked = true; + document.getElementById("max_uploads_value").value = maxUploads; } updateMaxUploadsEnabled(); const maxUploadsPerTorrent = Number(pref.max_uploads_per_torrent); if (maxUploadsPerTorrent <= 0) { - $("maxUploadsPerTorrentCheckbox").checked = false; - $("maxUploadsPerTorrentValue").value = 4; + document.getElementById("maxUploadsPerTorrentCheckbox").checked = false; + document.getElementById("maxUploadsPerTorrentValue").value = 4; } else { - $("maxUploadsPerTorrentCheckbox").checked = true; - $("maxUploadsPerTorrentValue").value = maxUploadsPerTorrent; + document.getElementById("maxUploadsPerTorrentCheckbox").checked = true; + document.getElementById("maxUploadsPerTorrentValue").value = maxUploadsPerTorrent; } updateMaxUploadsPerTorrentEnabled(); // I2P - $("i2pEnabledCheckbox").checked = pref.i2p_enabled; - $("i2pAddress").value = pref.i2p_address; - $("i2pPort").value = pref.i2p_port; - $("i2pMixedMode").checked = pref.i2p_mixed_mode; + document.getElementById("i2pEnabledCheckbox").checked = pref.i2p_enabled; + document.getElementById("i2pAddress").value = pref.i2p_address; + document.getElementById("i2pPort").value = pref.i2p_port; + document.getElementById("i2pMixedMode").checked = pref.i2p_mixed_mode; updateI2PSettingsEnabled(); // Proxy Server - $("peer_proxy_type_select").value = pref.proxy_type; - $("peer_proxy_host_text").value = pref.proxy_ip; - $("peer_proxy_port_value").value = pref.proxy_port; - $("peer_proxy_auth_checkbox").checked = pref.proxy_auth_enabled; - $("peer_proxy_username_text").value = pref.proxy_username; - $("peer_proxy_password_text").value = pref.proxy_password; - $("proxyHostnameLookupCheckbox").checked = pref.proxy_hostname_lookup; - $("proxy_bittorrent_checkbox").checked = pref.proxy_bittorrent; - $("use_peer_proxy_checkbox").checked = pref.proxy_peer_connections; - $("proxy_rss_checkbox").checked = pref.proxy_rss; - $("proxy_misc_checkbox").checked = pref.proxy_misc; + document.getElementById("peer_proxy_type_select").value = pref.proxy_type; + document.getElementById("peer_proxy_host_text").value = pref.proxy_ip; + document.getElementById("peer_proxy_port_value").value = pref.proxy_port; + document.getElementById("peer_proxy_auth_checkbox").checked = pref.proxy_auth_enabled; + document.getElementById("peer_proxy_username_text").value = pref.proxy_username; + document.getElementById("peer_proxy_password_text").value = pref.proxy_password; + document.getElementById("proxyHostnameLookupCheckbox").checked = pref.proxy_hostname_lookup; + document.getElementById("proxy_bittorrent_checkbox").checked = pref.proxy_bittorrent; + document.getElementById("use_peer_proxy_checkbox").checked = pref.proxy_peer_connections; + document.getElementById("proxy_rss_checkbox").checked = pref.proxy_rss; + document.getElementById("proxy_misc_checkbox").checked = pref.proxy_misc; updatePeerProxySettings(); // IP Filtering - $("ipfilter_text_checkbox").checked = pref.ip_filter_enabled; - $("ipfilter_text").value = pref.ip_filter_path; - $("ipfilter_trackers_checkbox").checked = pref.ip_filter_trackers; - $("banned_IPs_textarea").value = pref.banned_IPs; + document.getElementById("ipfilter_text_checkbox").checked = pref.ip_filter_enabled; + document.getElementById("ipfilter_text").value = pref.ip_filter_path; + document.getElementById("ipfilter_trackers_checkbox").checked = pref.ip_filter_trackers; + document.getElementById("banned_IPs_textarea").value = pref.banned_IPs; updateFilterSettings(); // Speed tab // Global Rate Limits - $("upLimitValue").value = (Number(pref.up_limit) / 1024); - $("dlLimitValue").value = (Number(pref.dl_limit) / 1024); + document.getElementById("upLimitValue").value = (Number(pref.up_limit) / 1024); + document.getElementById("dlLimitValue").value = (Number(pref.dl_limit) / 1024); // Alternative Global Rate Limits - $("altUpLimitValue").value = (Number(pref.alt_up_limit) / 1024); - $("altDlLimitValue").value = (Number(pref.alt_dl_limit) / 1024); + document.getElementById("altUpLimitValue").value = (Number(pref.alt_up_limit) / 1024); + document.getElementById("altDlLimitValue").value = (Number(pref.alt_dl_limit) / 1024); - $("enable_protocol_combobox").value = pref.bittorrent_protocol; - $("limit_utp_rate_checkbox").checked = pref.limit_utp_rate; - $("limit_tcp_overhead_checkbox").checked = pref.limit_tcp_overhead; - $("limit_lan_peers_checkbox").checked = pref.limit_lan_peers; + document.getElementById("enable_protocol_combobox").value = pref.bittorrent_protocol; + document.getElementById("limit_utp_rate_checkbox").checked = pref.limit_utp_rate; + document.getElementById("limit_tcp_overhead_checkbox").checked = pref.limit_tcp_overhead; + document.getElementById("limit_lan_peers_checkbox").checked = pref.limit_lan_peers; // Scheduling - $("limitSchedulingCheckbox").checked = pref.scheduler_enabled; - $("schedule_from_hour").value = time_padding(pref.schedule_from_hour); - $("schedule_from_min").value = time_padding(pref.schedule_from_min); - $("schedule_to_hour").value = time_padding(pref.schedule_to_hour); - $("schedule_to_min").value = time_padding(pref.schedule_to_min); - $("schedule_freq_select").value = pref.scheduler_days; + document.getElementById("limitSchedulingCheckbox").checked = pref.scheduler_enabled; + document.getElementById("schedule_from_hour").value = time_padding(pref.schedule_from_hour); + document.getElementById("schedule_from_min").value = time_padding(pref.schedule_from_min); + document.getElementById("schedule_to_hour").value = time_padding(pref.schedule_to_hour); + document.getElementById("schedule_to_min").value = time_padding(pref.schedule_to_min); + document.getElementById("schedule_freq_select").value = pref.scheduler_days; updateSchedulingEnabled(); // Bittorrent tab // Privacy - $("dht_checkbox").checked = pref.dht; - $("pex_checkbox").checked = pref.pex; - $("lsd_checkbox").checked = pref.lsd; + document.getElementById("dht_checkbox").checked = pref.dht; + document.getElementById("pex_checkbox").checked = pref.pex; + document.getElementById("lsd_checkbox").checked = pref.lsd; const encryption = Number(pref.encryption); - $("encryption_select").getChildren("option")[encryption].selected = true; - $("anonymous_mode_checkbox").checked = pref.anonymous_mode; + document.getElementById("encryption_select").getChildren("option")[encryption].selected = true; + document.getElementById("anonymous_mode_checkbox").checked = pref.anonymous_mode; - $("maxActiveCheckingTorrents").value = pref.max_active_checking_torrents; + document.getElementById("maxActiveCheckingTorrents").value = pref.max_active_checking_torrents; // Torrent Queueing - $("queueingCheckbox").checked = pref.queueing_enabled; - $("maxActiveDlValue").value = Number(pref.max_active_downloads); - $("maxActiveUpValue").value = Number(pref.max_active_uploads); - $("maxActiveToValue").value = Number(pref.max_active_torrents); - $("dontCountSlowTorrentsCheckbox").checked = pref.dont_count_slow_torrents; - $("dlRateThresholdValue").value = Number(pref.slow_torrent_dl_rate_threshold); - $("ulRateThresholdValue").value = Number(pref.slow_torrent_ul_rate_threshold); - $("torrentInactiveTimerValue").value = Number(pref.slow_torrent_inactive_timer); + document.getElementById("queueingCheckbox").checked = pref.queueing_enabled; + document.getElementById("maxActiveDlValue").value = Number(pref.max_active_downloads); + document.getElementById("maxActiveUpValue").value = Number(pref.max_active_uploads); + document.getElementById("maxActiveToValue").value = Number(pref.max_active_torrents); + document.getElementById("dontCountSlowTorrentsCheckbox").checked = pref.dont_count_slow_torrents; + document.getElementById("dlRateThresholdValue").value = Number(pref.slow_torrent_dl_rate_threshold); + document.getElementById("ulRateThresholdValue").value = Number(pref.slow_torrent_ul_rate_threshold); + document.getElementById("torrentInactiveTimerValue").value = Number(pref.slow_torrent_inactive_timer); updateQueueingSystem(); // Share Limiting - $("maxRatioCheckbox").checked = pref.max_ratio_enabled; - $("maxRatioValue").value = (pref.max_ratio_enabled ? pref.max_ratio : 1); - $("maxSeedingTimeCheckbox").checked = pref.max_seeding_time_enabled; - $("maxSeedingTimeValue").value = (pref.max_seeding_time_enabled ? Number(pref.max_seeding_time) : 1440); - $("maxInactiveSeedingTimeCheckbox").checked = pref.max_inactive_seeding_time_enabled; - $("maxInactiveSeedingTimeValue").value = (pref.max_inactive_seeding_time_enabled ? Number(pref.max_inactive_seeding_time) : 1440); + document.getElementById("maxRatioCheckbox").checked = pref.max_ratio_enabled; + document.getElementById("maxRatioValue").value = (pref.max_ratio_enabled ? pref.max_ratio : 1); + document.getElementById("maxSeedingTimeCheckbox").checked = pref.max_seeding_time_enabled; + document.getElementById("maxSeedingTimeValue").value = (pref.max_seeding_time_enabled ? Number(pref.max_seeding_time) : 1440); + document.getElementById("maxInactiveSeedingTimeCheckbox").checked = pref.max_inactive_seeding_time_enabled; + document.getElementById("maxInactiveSeedingTimeValue").value = (pref.max_inactive_seeding_time_enabled ? Number(pref.max_inactive_seeding_time) : 1440); let maxRatioAct = 0; switch (Number(pref.max_ratio_act)) { case 0: // Stop @@ -2492,151 +2492,151 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD maxRatioAct = 2; break; } - $("maxRatioSelect").getChildren("option")[maxRatioAct].selected = true; + document.getElementById("maxRatioSelect").getChildren("option")[maxRatioAct].selected = true; updateMaxRatioTimeEnabled(); // Add trackers - $("add_trackers_checkbox").checked = pref.add_trackers_enabled; - $("add_trackers_textarea").value = pref.add_trackers; - $("addTrackersFromURLCheckbox").checked = pref.add_trackers_from_url_enabled; - $("addTrackersURLListTextarea").value = pref.add_trackers_url_list; - $("addTrackersURL").value = pref.add_trackers_url; + document.getElementById("add_trackers_checkbox").checked = pref.add_trackers_enabled; + document.getElementById("add_trackers_textarea").value = pref.add_trackers; + document.getElementById("addTrackersFromURLCheckbox").checked = pref.add_trackers_from_url_enabled; + document.getElementById("addTrackersURLListTextarea").value = pref.add_trackers_url_list; + document.getElementById("addTrackersURL").value = pref.add_trackers_url; updateAddTrackersEnabled(); updateAddTrackersFromURLEnabled(); // RSS Tab - $("enable_fetching_rss_feeds_checkbox").checked = pref.rss_processing_enabled; - $("feed_refresh_interval").value = pref.rss_refresh_interval; - $("feedFetchDelay").value = pref.rss_fetch_delay; - $("maximum_article_number").value = pref.rss_max_articles_per_feed; - $("enable_auto_downloading_rss_torrents_checkbox").checked = pref.rss_auto_downloading_enabled; - $("downlock_repack_proper_episodes").checked = pref.rss_download_repack_proper_episodes; - $("rss_filter_textarea").value = pref.rss_smart_episode_filters; + document.getElementById("enable_fetching_rss_feeds_checkbox").checked = pref.rss_processing_enabled; + document.getElementById("feed_refresh_interval").value = pref.rss_refresh_interval; + document.getElementById("feedFetchDelay").value = pref.rss_fetch_delay; + document.getElementById("maximum_article_number").value = pref.rss_max_articles_per_feed; + document.getElementById("enable_auto_downloading_rss_torrents_checkbox").checked = pref.rss_auto_downloading_enabled; + document.getElementById("downlock_repack_proper_episodes").checked = pref.rss_download_repack_proper_episodes; + document.getElementById("rss_filter_textarea").value = pref.rss_smart_episode_filters; // WebUI tab // HTTP Server - $("webuiDomainTextarea").value = pref.web_ui_domain_list; - $("webuiAddressValue").value = pref.web_ui_address; - $("webuiPortValue").value = pref.web_ui_port; - $("webuiUpnpCheckbox").checked = pref.web_ui_upnp; - $("use_https_checkbox").checked = pref.use_https; - $("ssl_cert_text").value = pref.web_ui_https_cert_path; - $("ssl_key_text").value = pref.web_ui_https_key_path; + document.getElementById("webuiDomainTextarea").value = pref.web_ui_domain_list; + document.getElementById("webuiAddressValue").value = pref.web_ui_address; + document.getElementById("webuiPortValue").value = pref.web_ui_port; + document.getElementById("webuiUpnpCheckbox").checked = pref.web_ui_upnp; + document.getElementById("use_https_checkbox").checked = pref.use_https; + document.getElementById("ssl_cert_text").value = pref.web_ui_https_cert_path; + document.getElementById("ssl_key_text").value = pref.web_ui_https_key_path; updateHttpsSettings(); // Authentication - $("webui_username_text").value = pref.web_ui_username; - $("bypass_local_auth_checkbox").checked = pref.bypass_local_auth; - $("bypass_auth_subnet_whitelist_checkbox").checked = pref.bypass_auth_subnet_whitelist_enabled; - $("bypass_auth_subnet_whitelist_textarea").value = pref.bypass_auth_subnet_whitelist; + document.getElementById("webui_username_text").value = pref.web_ui_username; + document.getElementById("bypass_local_auth_checkbox").checked = pref.bypass_local_auth; + document.getElementById("bypass_auth_subnet_whitelist_checkbox").checked = pref.bypass_auth_subnet_whitelist_enabled; + document.getElementById("bypass_auth_subnet_whitelist_textarea").value = pref.bypass_auth_subnet_whitelist; updateBypasssAuthSettings(); - $("webUIMaxAuthFailCountInput").value = Number(pref.web_ui_max_auth_fail_count); - $("webUIBanDurationInput").value = Number(pref.web_ui_ban_duration); - $("webUISessionTimeoutInput").value = Number(pref.web_ui_session_timeout); + document.getElementById("webUIMaxAuthFailCountInput").value = Number(pref.web_ui_max_auth_fail_count); + document.getElementById("webUIBanDurationInput").value = Number(pref.web_ui_ban_duration); + document.getElementById("webUISessionTimeoutInput").value = Number(pref.web_ui_session_timeout); // Use alternative WebUI - $("use_alt_webui_checkbox").checked = pref.alternative_webui_enabled; - $("webui_files_location_textarea").value = pref.alternative_webui_path; + document.getElementById("use_alt_webui_checkbox").checked = pref.alternative_webui_enabled; + document.getElementById("webui_files_location_textarea").value = pref.alternative_webui_path; updateAlternativeWebUISettings(); // Security - $("clickjacking_protection_checkbox").checked = pref.web_ui_clickjacking_protection_enabled; - $("csrf_protection_checkbox").checked = pref.web_ui_csrf_protection_enabled; - $("secureCookieCheckbox").checked = pref.web_ui_secure_cookie_enabled; - $("host_header_validation_checkbox").checked = pref.web_ui_host_header_validation_enabled; + document.getElementById("clickjacking_protection_checkbox").checked = pref.web_ui_clickjacking_protection_enabled; + document.getElementById("csrf_protection_checkbox").checked = pref.web_ui_csrf_protection_enabled; + document.getElementById("secureCookieCheckbox").checked = pref.web_ui_secure_cookie_enabled; + document.getElementById("host_header_validation_checkbox").checked = pref.web_ui_host_header_validation_enabled; updateHostHeaderValidationSettings(); // Custom HTTP headers - $("webUIUseCustomHTTPHeadersCheckbox").checked = pref.web_ui_use_custom_http_headers_enabled; - $("webUICustomHTTPHeadersTextarea").value = pref.web_ui_custom_http_headers; + document.getElementById("webUIUseCustomHTTPHeadersCheckbox").checked = pref.web_ui_use_custom_http_headers_enabled; + document.getElementById("webUICustomHTTPHeadersTextarea").value = pref.web_ui_custom_http_headers; updateWebUICustomHTTPHeadersSettings(); // Reverse Proxy - $("webUIReverseProxySupportCheckbox").checked = pref.web_ui_reverse_proxy_enabled; - $("webUIReverseProxiesListTextarea").value = pref.web_ui_reverse_proxies_list; + document.getElementById("webUIReverseProxySupportCheckbox").checked = pref.web_ui_reverse_proxy_enabled; + document.getElementById("webUIReverseProxiesListTextarea").value = pref.web_ui_reverse_proxies_list; updateWebUIReverseProxySettings(); // Update my dynamic domain name - $("use_dyndns_checkbox").checked = pref.dyndns_enabled; - $("dyndns_select").value = pref.dyndns_service; - $("dyndns_domain_text").value = pref.dyndns_domain; - $("dyndns_username_text").value = pref.dyndns_username; - $("dyndns_password_text").value = pref.dyndns_password; + document.getElementById("use_dyndns_checkbox").checked = pref.dyndns_enabled; + document.getElementById("dyndns_select").value = pref.dyndns_service; + document.getElementById("dyndns_domain_text").value = pref.dyndns_domain; + document.getElementById("dyndns_username_text").value = pref.dyndns_username; + document.getElementById("dyndns_password_text").value = pref.dyndns_password; updateDynDnsSettings(); // Advanced settings // qBittorrent section - $("resumeDataStorageType").value = pref.resume_data_storage_type; - $("torrentContentRemoveOption").value = pref.torrent_content_remove_option; - $("memoryWorkingSetLimit").value = pref.memory_working_set_limit; + document.getElementById("resumeDataStorageType").value = pref.resume_data_storage_type; + document.getElementById("torrentContentRemoveOption").value = pref.torrent_content_remove_option; + document.getElementById("memoryWorkingSetLimit").value = pref.memory_working_set_limit; updateNetworkInterfaces(pref.current_network_interface, pref.current_interface_name); updateInterfaceAddresses(pref.current_network_interface, pref.current_interface_address); - $("saveResumeDataInterval").value = pref.save_resume_data_interval; - $("saveStatisticsInterval").value = pref.save_statistics_interval; - $("torrentFileSizeLimit").value = (pref.torrent_file_size_limit / 1024 / 1024); + document.getElementById("saveResumeDataInterval").value = pref.save_resume_data_interval; + document.getElementById("saveStatisticsInterval").value = pref.save_statistics_interval; + document.getElementById("torrentFileSizeLimit").value = (pref.torrent_file_size_limit / 1024 / 1024); document.getElementById("confirmTorrentRecheck").checked = pref.confirm_torrent_recheck; - $("recheckTorrentsOnCompletion").checked = pref.recheck_completed_torrents; - $("appInstanceName").value = pref.app_instance_name; - $("refreshInterval").value = pref.refresh_interval; - $("resolvePeerCountries").checked = pref.resolve_peer_countries; - $("reannounceWhenAddressChanged").checked = pref.reannounce_when_address_changed; - $("enableEmbeddedTracker").checked = pref.enable_embedded_tracker; - $("embeddedTrackerPort").value = pref.embedded_tracker_port; - $("embeddedTrackerPortForwarding").checked = pref.embedded_tracker_port_forwarding; - $("markOfTheWeb").checked = pref.mark_of_the_web; - $("ignoreSSLErrors").checked = pref.ignore_ssl_errors; - $("pythonExecutablePath").value = pref.python_executable_path; + document.getElementById("recheckTorrentsOnCompletion").checked = pref.recheck_completed_torrents; + document.getElementById("appInstanceName").value = pref.app_instance_name; + document.getElementById("refreshInterval").value = pref.refresh_interval; + document.getElementById("resolvePeerCountries").checked = pref.resolve_peer_countries; + document.getElementById("reannounceWhenAddressChanged").checked = pref.reannounce_when_address_changed; + document.getElementById("enableEmbeddedTracker").checked = pref.enable_embedded_tracker; + document.getElementById("embeddedTrackerPort").value = pref.embedded_tracker_port; + document.getElementById("embeddedTrackerPortForwarding").checked = pref.embedded_tracker_port_forwarding; + document.getElementById("markOfTheWeb").checked = pref.mark_of_the_web; + document.getElementById("ignoreSSLErrors").checked = pref.ignore_ssl_errors; + document.getElementById("pythonExecutablePath").value = pref.python_executable_path; // libtorrent section - $("bdecodeDepthLimit").value = pref.bdecode_depth_limit; - $("bdecodeTokenLimit").value = pref.bdecode_token_limit; - $("asyncIOThreads").value = pref.async_io_threads; - $("hashingThreads").value = pref.hashing_threads; - $("filePoolSize").value = pref.file_pool_size; - $("outstandMemoryWhenCheckingTorrents").value = pref.checking_memory_use; - $("diskCache").value = pref.disk_cache; - $("diskCacheExpiryInterval").value = pref.disk_cache_ttl; - $("diskQueueSize").value = (pref.disk_queue_size / 1024); - $("diskIOType").value = pref.disk_io_type; - $("diskIOReadMode").value = pref.disk_io_read_mode; - $("diskIOWriteMode").value = pref.disk_io_write_mode; - $("coalesceReadsAndWrites").checked = pref.enable_coalesce_read_write; - $("pieceExtentAffinity").checked = pref.enable_piece_extent_affinity; - $("sendUploadPieceSuggestions").checked = pref.enable_upload_suggestions; - $("sendBufferWatermark").value = pref.send_buffer_watermark; - $("sendBufferLowWatermark").value = pref.send_buffer_low_watermark; - $("sendBufferWatermarkFactor").value = pref.send_buffer_watermark_factor; - $("connectionSpeed").value = pref.connection_speed; - $("socketSendBufferSize").value = (pref.socket_send_buffer_size / 1024); - $("socketReceiveBufferSize").value = (pref.socket_receive_buffer_size / 1024); - $("socketBacklogSize").value = pref.socket_backlog_size; - $("outgoingPortsMin").value = pref.outgoing_ports_min; - $("outgoingPortsMax").value = pref.outgoing_ports_max; - $("UPnPLeaseDuration").value = pref.upnp_lease_duration; - $("peerToS").value = pref.peer_tos; - $("utpTCPMixedModeAlgorithm").value = pref.utp_tcp_mixed_mode; - $("hostnameCacheTTL").value = pref.hostname_cache_ttl; - $("IDNSupportCheckbox").checked = pref.idn_support_enabled; - $("allowMultipleConnectionsFromTheSameIPAddress").checked = pref.enable_multi_connections_from_same_ip; - $("validateHTTPSTrackerCertificate").checked = pref.validate_https_tracker_certificate; - $("mitigateSSRF").checked = pref.ssrf_mitigation; - $("blockPeersOnPrivilegedPorts").checked = pref.block_peers_on_privileged_ports; - $("uploadSlotsBehavior").value = pref.upload_slots_behavior; - $("uploadChokingAlgorithm").value = pref.upload_choking_algorithm; - $("announceAllTrackers").checked = pref.announce_to_all_trackers; - $("announceAllTiers").checked = pref.announce_to_all_tiers; - $("announceIP").value = pref.announce_ip; - $("announcePort").value = pref.announce_port; - $("maxConcurrentHTTPAnnounces").value = pref.max_concurrent_http_announces; - $("stopTrackerTimeout").value = pref.stop_tracker_timeout; - $("peerTurnover").value = pref.peer_turnover; - $("peerTurnoverCutoff").value = pref.peer_turnover_cutoff; - $("peerTurnoverInterval").value = pref.peer_turnover_interval; - $("requestQueueSize").value = pref.request_queue_size; - $("dhtBootstrapNodes").value = pref.dht_bootstrap_nodes; - $("i2pInboundQuantity").value = pref.i2p_inbound_quantity; - $("i2pOutboundQuantity").value = pref.i2p_outbound_quantity; - $("i2pInboundLength").value = pref.i2p_inbound_length; - $("i2pOutboundLength").value = pref.i2p_outbound_length; + document.getElementById("bdecodeDepthLimit").value = pref.bdecode_depth_limit; + document.getElementById("bdecodeTokenLimit").value = pref.bdecode_token_limit; + document.getElementById("asyncIOThreads").value = pref.async_io_threads; + document.getElementById("hashingThreads").value = pref.hashing_threads; + document.getElementById("filePoolSize").value = pref.file_pool_size; + document.getElementById("outstandMemoryWhenCheckingTorrents").value = pref.checking_memory_use; + document.getElementById("diskCache").value = pref.disk_cache; + document.getElementById("diskCacheExpiryInterval").value = pref.disk_cache_ttl; + document.getElementById("diskQueueSize").value = (pref.disk_queue_size / 1024); + document.getElementById("diskIOType").value = pref.disk_io_type; + document.getElementById("diskIOReadMode").value = pref.disk_io_read_mode; + document.getElementById("diskIOWriteMode").value = pref.disk_io_write_mode; + document.getElementById("coalesceReadsAndWrites").checked = pref.enable_coalesce_read_write; + document.getElementById("pieceExtentAffinity").checked = pref.enable_piece_extent_affinity; + document.getElementById("sendUploadPieceSuggestions").checked = pref.enable_upload_suggestions; + document.getElementById("sendBufferWatermark").value = pref.send_buffer_watermark; + document.getElementById("sendBufferLowWatermark").value = pref.send_buffer_low_watermark; + document.getElementById("sendBufferWatermarkFactor").value = pref.send_buffer_watermark_factor; + document.getElementById("connectionSpeed").value = pref.connection_speed; + document.getElementById("socketSendBufferSize").value = (pref.socket_send_buffer_size / 1024); + document.getElementById("socketReceiveBufferSize").value = (pref.socket_receive_buffer_size / 1024); + document.getElementById("socketBacklogSize").value = pref.socket_backlog_size; + document.getElementById("outgoingPortsMin").value = pref.outgoing_ports_min; + document.getElementById("outgoingPortsMax").value = pref.outgoing_ports_max; + document.getElementById("UPnPLeaseDuration").value = pref.upnp_lease_duration; + document.getElementById("peerToS").value = pref.peer_tos; + document.getElementById("utpTCPMixedModeAlgorithm").value = pref.utp_tcp_mixed_mode; + document.getElementById("hostnameCacheTTL").value = pref.hostname_cache_ttl; + document.getElementById("IDNSupportCheckbox").checked = pref.idn_support_enabled; + document.getElementById("allowMultipleConnectionsFromTheSameIPAddress").checked = pref.enable_multi_connections_from_same_ip; + document.getElementById("validateHTTPSTrackerCertificate").checked = pref.validate_https_tracker_certificate; + document.getElementById("mitigateSSRF").checked = pref.ssrf_mitigation; + document.getElementById("blockPeersOnPrivilegedPorts").checked = pref.block_peers_on_privileged_ports; + document.getElementById("uploadSlotsBehavior").value = pref.upload_slots_behavior; + document.getElementById("uploadChokingAlgorithm").value = pref.upload_choking_algorithm; + document.getElementById("announceAllTrackers").checked = pref.announce_to_all_trackers; + document.getElementById("announceAllTiers").checked = pref.announce_to_all_tiers; + document.getElementById("announceIP").value = pref.announce_ip; + document.getElementById("announcePort").value = pref.announce_port; + document.getElementById("maxConcurrentHTTPAnnounces").value = pref.max_concurrent_http_announces; + document.getElementById("stopTrackerTimeout").value = pref.stop_tracker_timeout; + document.getElementById("peerTurnover").value = pref.peer_turnover; + document.getElementById("peerTurnoverCutoff").value = pref.peer_turnover_cutoff; + document.getElementById("peerTurnoverInterval").value = pref.peer_turnover_interval; + document.getElementById("requestQueueSize").value = pref.request_queue_size; + document.getElementById("dhtBootstrapNodes").value = pref.dht_bootstrap_nodes; + document.getElementById("i2pInboundQuantity").value = pref.i2p_inbound_quantity; + document.getElementById("i2pOutboundQuantity").value = pref.i2p_outbound_quantity; + document.getElementById("i2pInboundLength").value = pref.i2p_inbound_length; + document.getElementById("i2pOutboundLength").value = pref.i2p_outbound_length; } }); }; @@ -2647,7 +2647,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD // Behavior tab // Language - settings["locale"] = $("locale_select").value; + settings["locale"] = document.getElementById("locale_select").value; const colorScheme = Number(document.getElementById("colorSchemeSelect").value); if (colorScheme === 0) LocalPreferences.remove("color_scheme"); @@ -2655,52 +2655,52 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD LocalPreferences.set("color_scheme", "light"); else LocalPreferences.set("color_scheme", "dark"); - settings["status_bar_external_ip"] = $("statusBarExternalIP").checked; - settings["performance_warning"] = $("performanceWarning").checked; + settings["status_bar_external_ip"] = document.getElementById("statusBarExternalIP").checked; + settings["performance_warning"] = document.getElementById("performanceWarning").checked; LocalPreferences.set("full_url_tracker_column", document.getElementById("displayFullURLTrackerColumn").checked.toString()); LocalPreferences.set("use_virtual_list", document.getElementById("useVirtualList").checked.toString()); LocalPreferences.set("hide_zero_status_filters", document.getElementById("hideZeroFiltersCheckbox").checked.toString()); - LocalPreferences.set("dblclick_download", $("dblclickDownloadSelect").value); - LocalPreferences.set("dblclick_complete", $("dblclickCompleteSelect").value); + LocalPreferences.set("dblclick_download", document.getElementById("dblclickDownloadSelect").value); + LocalPreferences.set("dblclick_complete", document.getElementById("dblclickCompleteSelect").value); settings["confirm_torrent_deletion"] = document.getElementById("confirmTorrentDeletion").checked; LocalPreferences.set("use_alt_row_colors", document.getElementById("useAltRowColorsInput").checked.toString()); - settings["file_log_enabled"] = $("filelog_checkbox").checked; - settings["file_log_path"] = $("filelog_save_path_input").value; - settings["file_log_backup_enabled"] = $("filelog_backup_checkbox").checked; - settings["file_log_max_size"] = Number($("filelog_max_size_input").value); - settings["file_log_delete_old"] = $("filelog_delete_old_checkbox").checked; - settings["file_log_age"] = Number($("filelog_age_input").value); - settings["file_log_age_type"] = Number($("filelog_age_type_select").value); + settings["file_log_enabled"] = document.getElementById("filelog_checkbox").checked; + settings["file_log_path"] = document.getElementById("filelog_save_path_input").value; + settings["file_log_backup_enabled"] = document.getElementById("filelog_backup_checkbox").checked; + settings["file_log_max_size"] = Number(document.getElementById("filelog_max_size_input").value); + settings["file_log_delete_old"] = document.getElementById("filelog_delete_old_checkbox").checked; + settings["file_log_age"] = Number(document.getElementById("filelog_age_input").value); + settings["file_log_age_type"] = Number(document.getElementById("filelog_age_type_select").value); // Downloads tab // When adding a torrent - settings["torrent_content_layout"] = $("contentlayout_select").getSelected()[0].value; - settings["add_to_top_of_queue"] = $("addToTopOfQueueCheckbox").checked; - settings["add_stopped_enabled"] = $("dontstartdownloads_checkbox").checked; - settings["torrent_stop_condition"] = $("stopConditionSelect").getSelected()[0].value; + settings["torrent_content_layout"] = document.getElementById("contentlayout_select").getSelected()[0].value; + settings["add_to_top_of_queue"] = document.getElementById("addToTopOfQueueCheckbox").checked; + settings["add_stopped_enabled"] = document.getElementById("dontstartdownloads_checkbox").checked; + settings["torrent_stop_condition"] = document.getElementById("stopConditionSelect").getSelected()[0].value; settings["merge_trackers"] = document.getElementById("mergeTrackersInput").checked; - settings["auto_delete_mode"] = Number($("deletetorrentfileafter_checkbox").checked); + settings["auto_delete_mode"] = Number(document.getElementById("deletetorrentfileafter_checkbox").checked); - settings["preallocate_all"] = $("preallocateall_checkbox").checked; - settings["incomplete_files_ext"] = $("appendext_checkbox").checked; - settings["use_unwanted_folder"] = $("unwantedfolder_checkbox").checked; + settings["preallocate_all"] = document.getElementById("preallocateall_checkbox").checked; + settings["incomplete_files_ext"] = document.getElementById("appendext_checkbox").checked; + settings["use_unwanted_folder"] = document.getElementById("unwantedfolder_checkbox").checked; // Saving Management - settings["auto_tmm_enabled"] = ($("default_tmm_combobox").value === "true"); - settings["torrent_changed_tmm_enabled"] = ($("torrent_changed_tmm_combobox").value === "true"); - settings["save_path_changed_tmm_enabled"] = ($("save_path_changed_tmm_combobox").value === "true"); - settings["category_changed_tmm_enabled"] = ($("category_changed_tmm_combobox").value === "true"); - settings["use_subcategories"] = $("use_subcategories_checkbox").checked; + settings["auto_tmm_enabled"] = (document.getElementById("default_tmm_combobox").value === "true"); + settings["torrent_changed_tmm_enabled"] = (document.getElementById("torrent_changed_tmm_combobox").value === "true"); + settings["save_path_changed_tmm_enabled"] = (document.getElementById("save_path_changed_tmm_combobox").value === "true"); + settings["category_changed_tmm_enabled"] = (document.getElementById("category_changed_tmm_combobox").value === "true"); + settings["use_subcategories"] = document.getElementById("use_subcategories_checkbox").checked; settings["use_category_paths_in_manual_mode"] = document.getElementById("categoryPathsManualModeCheckbox").checked; - settings["save_path"] = $("savepath_text").value; - settings["temp_path_enabled"] = $("temppath_checkbox").checked; - settings["temp_path"] = $("temppath_text").value; - if ($("exportdir_checkbox").checked) - settings["export_dir"] = $("exportdir_text").value; + settings["save_path"] = document.getElementById("savepath_text").value; + settings["temp_path_enabled"] = document.getElementById("temppath_checkbox").checked; + settings["temp_path"] = document.getElementById("temppath_text").value; + if (document.getElementById("exportdir_checkbox").checked) + settings["export_dir"] = document.getElementById("exportdir_text").value; else settings["export_dir"] = ""; - if ($("exportdirfin_checkbox").checked) - settings["export_dir_fin"] = $("exportdirfin_text").value; + if (document.getElementById("exportdirfin_checkbox").checked) + settings["export_dir_fin"] = document.getElementById("exportdirfin_text").value; else settings["export_dir_fin"] = ""; @@ -2708,40 +2708,40 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["scan_dirs"] = getWatchedFolders(); // Excluded file names - settings["excluded_file_names_enabled"] = $("excludedFileNamesCheckbox").checked; - settings["excluded_file_names"] = $("excludedFileNamesTextarea").value; + settings["excluded_file_names_enabled"] = document.getElementById("excludedFileNamesCheckbox").checked; + settings["excluded_file_names"] = document.getElementById("excludedFileNamesTextarea").value; // Email notification upon download completion - settings["mail_notification_enabled"] = $("mail_notification_checkbox").checked; - settings["mail_notification_sender"] = $("src_email_txt").value; - settings["mail_notification_email"] = $("dest_email_txt").value; - settings["mail_notification_smtp"] = $("smtp_server_txt").value; - settings["mail_notification_ssl_enabled"] = $("mail_ssl_checkbox").checked; - settings["mail_notification_auth_enabled"] = $("mail_auth_checkbox").checked; - settings["mail_notification_username"] = $("mail_username_text").value; - settings["mail_notification_password"] = $("mail_password_text").value; + settings["mail_notification_enabled"] = document.getElementById("mail_notification_checkbox").checked; + settings["mail_notification_sender"] = document.getElementById("src_email_txt").value; + settings["mail_notification_email"] = document.getElementById("dest_email_txt").value; + settings["mail_notification_smtp"] = document.getElementById("smtp_server_txt").value; + settings["mail_notification_ssl_enabled"] = document.getElementById("mail_ssl_checkbox").checked; + settings["mail_notification_auth_enabled"] = document.getElementById("mail_auth_checkbox").checked; + settings["mail_notification_username"] = document.getElementById("mail_username_text").value; + settings["mail_notification_password"] = document.getElementById("mail_password_text").value; // Run an external program on torrent added - settings["autorun_on_torrent_added_enabled"] = $("autorunOnTorrentAddedCheckbox").checked; - settings["autorun_on_torrent_added_program"] = $("autorunOnTorrentAddedProgram").value; + settings["autorun_on_torrent_added_enabled"] = document.getElementById("autorunOnTorrentAddedCheckbox").checked; + settings["autorun_on_torrent_added_program"] = document.getElementById("autorunOnTorrentAddedProgram").value; // Run an external program on torrent finished - settings["autorun_enabled"] = $("autorun_checkbox").checked; - settings["autorun_program"] = $("autorunProg_txt").value; + settings["autorun_enabled"] = document.getElementById("autorun_checkbox").checked; + settings["autorun_program"] = document.getElementById("autorunProg_txt").value; // Connection tab // Listening Port - const listenPort = Number($("portValue").value); + const listenPort = Number(document.getElementById("portValue").value); if (Number.isNaN(listenPort) || (listenPort < 0) || (listenPort > 65535)) { alert("QBT_TR(The port used for incoming connections must be between 0 and 65535.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["listen_port"] = listenPort; - settings["upnp"] = $("upnpCheckbox").checked; + settings["upnp"] = document.getElementById("upnpCheckbox").checked; // Connections Limits let maxConnec = -1; - if ($("maxConnectionsCheckbox").checked) { - maxConnec = Number($("maxConnectionsValue").value); + if (document.getElementById("maxConnectionsCheckbox").checked) { + maxConnec = Number(document.getElementById("maxConnectionsValue").value); if (Number.isNaN(maxConnec) || (maxConnec <= 0)) { alert("QBT_TR(Maximum number of connections limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2750,8 +2750,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_connec"] = maxConnec; let maxConnecPerTorrent = -1; - if ($("maxConnectionsPerTorrentCheckbox").checked) { - maxConnecPerTorrent = Number($("maxConnectionsPerTorrentValue").value); + if (document.getElementById("maxConnectionsPerTorrentCheckbox").checked) { + maxConnecPerTorrent = Number(document.getElementById("maxConnectionsPerTorrentValue").value); if (Number.isNaN(maxConnecPerTorrent) || (maxConnecPerTorrent <= 0)) { alert("QBT_TR(Maximum number of connections per torrent limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2760,8 +2760,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_connec_per_torrent"] = maxConnecPerTorrent; let maxUploads = -1; - if ($("maxUploadsCheckbox").checked) { - maxUploads = Number($("max_uploads_value").value); + if (document.getElementById("maxUploadsCheckbox").checked) { + maxUploads = Number(document.getElementById("max_uploads_value").value); if (Number.isNaN(maxUploads) || (maxUploads <= 0)) { alert("QBT_TR(Global number of upload slots limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2770,8 +2770,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_uploads"] = maxUploads; let maxUploadsPerTorrent = -1; - if ($("maxUploadsPerTorrentCheckbox").checked) { - maxUploadsPerTorrent = Number($("maxUploadsPerTorrentValue").value); + if (document.getElementById("maxUploadsPerTorrentCheckbox").checked) { + maxUploadsPerTorrent = Number(document.getElementById("maxUploadsPerTorrentValue").value); if (Number.isNaN(maxUploadsPerTorrent) || (maxUploadsPerTorrent <= 0)) { alert("QBT_TR(Maximum number of upload slots per torrent limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2780,40 +2780,40 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_uploads_per_torrent"] = maxUploadsPerTorrent; // I2P - settings["i2p_enabled"] = $("i2pEnabledCheckbox").checked; - settings["i2p_address"] = $("i2pAddress").value; - settings["i2p_port"] = Number($("i2pPort").value); - settings["i2p_mixed_mode"] = $("i2pMixedMode").checked; + settings["i2p_enabled"] = document.getElementById("i2pEnabledCheckbox").checked; + settings["i2p_address"] = document.getElementById("i2pAddress").value; + settings["i2p_port"] = Number(document.getElementById("i2pPort").value); + settings["i2p_mixed_mode"] = document.getElementById("i2pMixedMode").checked; // Proxy Server - settings["proxy_type"] = $("peer_proxy_type_select").value; - settings["proxy_ip"] = $("peer_proxy_host_text").value; - settings["proxy_port"] = Number($("peer_proxy_port_value").value); - settings["proxy_auth_enabled"] = $("peer_proxy_auth_checkbox").checked; - settings["proxy_username"] = $("peer_proxy_username_text").value; - settings["proxy_password"] = $("peer_proxy_password_text").value; - settings["proxy_hostname_lookup"] = $("proxyHostnameLookupCheckbox").checked; - settings["proxy_bittorrent"] = $("proxy_bittorrent_checkbox").checked; - settings["proxy_peer_connections"] = $("use_peer_proxy_checkbox").checked; - settings["proxy_rss"] = $("proxy_rss_checkbox").checked; - settings["proxy_misc"] = $("proxy_misc_checkbox").checked; + settings["proxy_type"] = document.getElementById("peer_proxy_type_select").value; + settings["proxy_ip"] = document.getElementById("peer_proxy_host_text").value; + settings["proxy_port"] = Number(document.getElementById("peer_proxy_port_value").value); + settings["proxy_auth_enabled"] = document.getElementById("peer_proxy_auth_checkbox").checked; + settings["proxy_username"] = document.getElementById("peer_proxy_username_text").value; + settings["proxy_password"] = document.getElementById("peer_proxy_password_text").value; + settings["proxy_hostname_lookup"] = document.getElementById("proxyHostnameLookupCheckbox").checked; + settings["proxy_bittorrent"] = document.getElementById("proxy_bittorrent_checkbox").checked; + settings["proxy_peer_connections"] = document.getElementById("use_peer_proxy_checkbox").checked; + settings["proxy_rss"] = document.getElementById("proxy_rss_checkbox").checked; + settings["proxy_misc"] = document.getElementById("proxy_misc_checkbox").checked; // IP Filtering - settings["ip_filter_enabled"] = $("ipfilter_text_checkbox").checked; - settings["ip_filter_path"] = $("ipfilter_text").value; - settings["ip_filter_trackers"] = $("ipfilter_trackers_checkbox").checked; - settings["banned_IPs"] = $("banned_IPs_textarea").value; + settings["ip_filter_enabled"] = document.getElementById("ipfilter_text_checkbox").checked; + settings["ip_filter_path"] = document.getElementById("ipfilter_text").value; + settings["ip_filter_trackers"] = document.getElementById("ipfilter_trackers_checkbox").checked; + settings["banned_IPs"] = document.getElementById("banned_IPs_textarea").value; // Speed tab // Global Rate Limits - const upLimit = Number($("upLimitValue").value) * 1024; + const upLimit = Number(document.getElementById("upLimitValue").value) * 1024; if (Number.isNaN(upLimit) || (upLimit < 0)) { alert("QBT_TR(Global upload rate limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["up_limit"] = upLimit; - const dlLimit = Number($("dlLimitValue").value) * 1024; + const dlLimit = Number(document.getElementById("dlLimitValue").value) * 1024; if (Number.isNaN(dlLimit) || (dlLimit < 0)) { alert("QBT_TR(Global download rate limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2821,86 +2821,86 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["dl_limit"] = dlLimit; // Alternative Global Rate Limits - const altUpLimit = Number($("altUpLimitValue").value) * 1024; + const altUpLimit = Number(document.getElementById("altUpLimitValue").value) * 1024; if (Number.isNaN(altUpLimit) || (altUpLimit < 0)) { alert("QBT_TR(Alternative upload rate limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["alt_up_limit"] = altUpLimit; - const altDlLimit = Number($("altDlLimitValue").value) * 1024; + const altDlLimit = Number(document.getElementById("altDlLimitValue").value) * 1024; if (Number.isNaN(altDlLimit) || (altDlLimit < 0)) { alert("QBT_TR(Alternative download rate limit must be greater than 0 or disabled.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["alt_dl_limit"] = altDlLimit; - settings["bittorrent_protocol"] = Number($("enable_protocol_combobox").value); - settings["limit_utp_rate"] = $("limit_utp_rate_checkbox").checked; - settings["limit_tcp_overhead"] = $("limit_tcp_overhead_checkbox").checked; - settings["limit_lan_peers"] = $("limit_lan_peers_checkbox").checked; + settings["bittorrent_protocol"] = Number(document.getElementById("enable_protocol_combobox").value); + settings["limit_utp_rate"] = document.getElementById("limit_utp_rate_checkbox").checked; + settings["limit_tcp_overhead"] = document.getElementById("limit_tcp_overhead_checkbox").checked; + settings["limit_lan_peers"] = document.getElementById("limit_lan_peers_checkbox").checked; // Scheduler - const schedulingEnabled = $("limitSchedulingCheckbox").checked; + const schedulingEnabled = document.getElementById("limitSchedulingCheckbox").checked; settings["scheduler_enabled"] = schedulingEnabled; if (schedulingEnabled) { - settings["schedule_from_hour"] = Number($("schedule_from_hour").value); - settings["schedule_from_min"] = Number($("schedule_from_min").value); - settings["schedule_to_hour"] = Number($("schedule_to_hour").value); - settings["schedule_to_min"] = Number($("schedule_to_min").value); - settings["scheduler_days"] = Number($("schedule_freq_select").value); + settings["schedule_from_hour"] = Number(document.getElementById("schedule_from_hour").value); + settings["schedule_from_min"] = Number(document.getElementById("schedule_from_min").value); + settings["schedule_to_hour"] = Number(document.getElementById("schedule_to_hour").value); + settings["schedule_to_min"] = Number(document.getElementById("schedule_to_min").value); + settings["scheduler_days"] = Number(document.getElementById("schedule_freq_select").value); } // Bittorrent tab // Privacy - settings["dht"] = $("dht_checkbox").checked; - settings["pex"] = $("pex_checkbox").checked; - settings["lsd"] = $("lsd_checkbox").checked; - settings["encryption"] = Number($("encryption_select").getSelected()[0].value); - settings["anonymous_mode"] = $("anonymous_mode_checkbox").checked; + settings["dht"] = document.getElementById("dht_checkbox").checked; + settings["pex"] = document.getElementById("pex_checkbox").checked; + settings["lsd"] = document.getElementById("lsd_checkbox").checked; + settings["encryption"] = Number(document.getElementById("encryption_select").getSelected()[0].value); + settings["anonymous_mode"] = document.getElementById("anonymous_mode_checkbox").checked; - settings["max_active_checking_torrents"] = Number($("maxActiveCheckingTorrents").value); + settings["max_active_checking_torrents"] = Number(document.getElementById("maxActiveCheckingTorrents").value); // Torrent Queueing - settings["queueing_enabled"] = $("queueingCheckbox").checked; - if ($("queueingCheckbox").checked) { - const maxActiveDownloads = Number($("maxActiveDlValue").value); + settings["queueing_enabled"] = document.getElementById("queueingCheckbox").checked; + if (document.getElementById("queueingCheckbox").checked) { + const maxActiveDownloads = Number(document.getElementById("maxActiveDlValue").value); if (Number.isNaN(maxActiveDownloads) || (maxActiveDownloads < -1)) { alert("QBT_TR(Maximum active downloads must be greater than -1.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["max_active_downloads"] = maxActiveDownloads; - const maxActiveUploads = Number($("maxActiveUpValue").value); + const maxActiveUploads = Number(document.getElementById("maxActiveUpValue").value); if (Number.isNaN(maxActiveUploads) || (maxActiveUploads < -1)) { alert("QBT_TR(Maximum active uploads must be greater than -1.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["max_active_uploads"] = maxActiveUploads; - const maxActiveTorrents = Number($("maxActiveToValue").value); + const maxActiveTorrents = Number(document.getElementById("maxActiveToValue").value); if (Number.isNaN(maxActiveTorrents) || (maxActiveTorrents < -1)) { alert("QBT_TR(Maximum active torrents must be greater than -1.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["max_active_torrents"] = maxActiveTorrents; - settings["dont_count_slow_torrents"] = $("dontCountSlowTorrentsCheckbox").checked; + settings["dont_count_slow_torrents"] = document.getElementById("dontCountSlowTorrentsCheckbox").checked; - const dlRateThreshold = Number($("dlRateThresholdValue").value); + const dlRateThreshold = Number(document.getElementById("dlRateThresholdValue").value); if (Number.isNaN(dlRateThreshold) || (dlRateThreshold < 1)) { alert("QBT_TR(Download rate threshold must be greater than 0.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["slow_torrent_dl_rate_threshold"] = dlRateThreshold; - const ulRateThreshold = Number($("ulRateThresholdValue").value); + const ulRateThreshold = Number(document.getElementById("ulRateThresholdValue").value); if (Number.isNaN(ulRateThreshold) || (ulRateThreshold < 1)) { alert("QBT_TR(Upload rate threshold must be greater than 0.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["slow_torrent_ul_rate_threshold"] = ulRateThreshold; - const torrentInactiveTimer = Number($("torrentInactiveTimerValue").value); + const torrentInactiveTimer = Number(document.getElementById("torrentInactiveTimerValue").value); if (Number.isNaN(torrentInactiveTimer) || (torrentInactiveTimer < 1)) { alert("QBT_TR(Torrent inactivity timer must be greater than 0.)QBT_TR[CONTEXT=HttpServer]"); return; @@ -2910,78 +2910,78 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD // Share Ratio Limiting let maxRatio = -1; - if ($("maxRatioCheckbox").checked) { - maxRatio = Number($("maxRatioValue").value); + if (document.getElementById("maxRatioCheckbox").checked) { + maxRatio = Number(document.getElementById("maxRatioValue").value); if (isNaN(maxRatio) || (maxRatio < 0) || (maxRatio > 9998)) { alert("QBT_TR(Share ratio limit must be between 0 and 9998.)QBT_TR[CONTEXT=HttpServer]"); return; } } - settings["max_ratio_enabled"] = $("maxRatioCheckbox").checked; + settings["max_ratio_enabled"] = document.getElementById("maxRatioCheckbox").checked; settings["max_ratio"] = maxRatio; let maxSeedingTime = -1; - if ($("maxSeedingTimeCheckbox").checked) { - maxSeedingTime = Number($("maxSeedingTimeValue").value); + if (document.getElementById("maxSeedingTimeCheckbox").checked) { + maxSeedingTime = Number(document.getElementById("maxSeedingTimeValue").value); if (Number.isNaN(maxSeedingTime) || (maxSeedingTime < 0) || (maxSeedingTime > 525600)) { alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); return; } } - settings["max_seeding_time_enabled"] = $("maxSeedingTimeCheckbox").checked; + settings["max_seeding_time_enabled"] = document.getElementById("maxSeedingTimeCheckbox").checked; settings["max_seeding_time"] = maxSeedingTime; let maxInactiveSeedingTime = -1; - if ($("maxInactiveSeedingTimeCheckbox").checked) { - maxInactiveSeedingTime = Number($("maxInactiveSeedingTimeValue").value); + if (document.getElementById("maxInactiveSeedingTimeCheckbox").checked) { + maxInactiveSeedingTime = Number(document.getElementById("maxInactiveSeedingTimeValue").value); if (Number.isNaN(maxInactiveSeedingTime) || (maxInactiveSeedingTime < 0) || (maxInactiveSeedingTime > 525600)) { alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); return; } } - settings["max_inactive_seeding_time_enabled"] = $("maxInactiveSeedingTimeCheckbox").checked; + settings["max_inactive_seeding_time_enabled"] = document.getElementById("maxInactiveSeedingTimeCheckbox").checked; settings["max_inactive_seeding_time"] = maxInactiveSeedingTime; - settings["max_ratio_act"] = Number($("maxRatioSelect").value); + settings["max_ratio_act"] = Number(document.getElementById("maxRatioSelect").value); // Add trackers - settings["add_trackers_enabled"] = $("add_trackers_checkbox").checked; - settings["add_trackers"] = $("add_trackers_textarea").value; - settings["add_trackers_from_url_enabled"] = $("addTrackersFromURLCheckbox").checked; - settings["add_trackers_url"] = $("addTrackersURL").value; + settings["add_trackers_enabled"] = document.getElementById("add_trackers_checkbox").checked; + settings["add_trackers"] = document.getElementById("add_trackers_textarea").value; + settings["add_trackers_from_url_enabled"] = document.getElementById("addTrackersFromURLCheckbox").checked; + settings["add_trackers_url"] = document.getElementById("addTrackersURL").value; // RSS Tab - settings["rss_processing_enabled"] = $("enable_fetching_rss_feeds_checkbox").checked; - settings["rss_refresh_interval"] = Number($("feed_refresh_interval").value); - settings["rss_fetch_delay"] = Number($("feedFetchDelay").value); - settings["rss_max_articles_per_feed"] = Number($("maximum_article_number").value); - settings["rss_auto_downloading_enabled"] = $("enable_auto_downloading_rss_torrents_checkbox").checked; - settings["rss_download_repack_proper_episodes"] = $("downlock_repack_proper_episodes").checked; - settings["rss_smart_episode_filters"] = $("rss_filter_textarea").value; + settings["rss_processing_enabled"] = document.getElementById("enable_fetching_rss_feeds_checkbox").checked; + settings["rss_refresh_interval"] = Number(document.getElementById("feed_refresh_interval").value); + settings["rss_fetch_delay"] = Number(document.getElementById("feedFetchDelay").value); + settings["rss_max_articles_per_feed"] = Number(document.getElementById("maximum_article_number").value); + settings["rss_auto_downloading_enabled"] = document.getElementById("enable_auto_downloading_rss_torrents_checkbox").checked; + settings["rss_download_repack_proper_episodes"] = document.getElementById("downlock_repack_proper_episodes").checked; + settings["rss_smart_episode_filters"] = document.getElementById("rss_filter_textarea").value; // WebUI tab // HTTP Server - settings["web_ui_domain_list"] = $("webuiDomainTextarea").value; - const webUIAddress = $("webuiAddressValue").value.toString(); - const webUIPort = Number($("webuiPortValue").value); + settings["web_ui_domain_list"] = document.getElementById("webuiDomainTextarea").value; + const webUIAddress = document.getElementById("webuiAddressValue").value.toString(); + const webUIPort = Number(document.getElementById("webuiPortValue").value); if (Number.isNaN(webUIPort) || (webUIPort < 1) || (webUIPort > 65535)) { alert("QBT_TR(The port used for the WebUI must be between 1 and 65535.)QBT_TR[CONTEXT=HttpServer]"); return; } settings["web_ui_address"] = webUIAddress; settings["web_ui_port"] = webUIPort; - settings["web_ui_upnp"] = $("webuiUpnpCheckbox").checked; + settings["web_ui_upnp"] = document.getElementById("webuiUpnpCheckbox").checked; - const useHTTPS = $("use_https_checkbox").checked; + const useHTTPS = document.getElementById("use_https_checkbox").checked; settings["use_https"] = useHTTPS; - const httpsCertificate = $("ssl_cert_text").value; + const httpsCertificate = document.getElementById("ssl_cert_text").value; settings["web_ui_https_cert_path"] = httpsCertificate; if (useHTTPS && (httpsCertificate.length === 0)) { alert("QBT_TR(HTTPS certificate should not be empty)QBT_TR[CONTEXT=OptionsDialog]"); return; } - const httpsKey = $("ssl_key_text").value; + const httpsKey = document.getElementById("ssl_key_text").value; settings["web_ui_https_key_path"] = httpsKey; if (useHTTPS && (httpsKey.length === 0)) { alert("QBT_TR(HTTPS key should not be empty)QBT_TR[CONTEXT=OptionsDialog]"); @@ -2989,12 +2989,12 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD } // Authentication - const web_ui_username = $("webui_username_text").value; + const web_ui_username = document.getElementById("webui_username_text").value; if (web_ui_username.length < 3) { alert("QBT_TR(The WebUI username must be at least 3 characters long.)QBT_TR[CONTEXT=OptionsDialog]"); return; } - const web_ui_password = $("webui_password_text").value; + const web_ui_password = document.getElementById("webui_password_text").value; if ((0 < web_ui_password.length) && (web_ui_password.length < 6)) { alert("QBT_TR(The WebUI password must be at least 6 characters long.)QBT_TR[CONTEXT=OptionsDialog]"); return; @@ -3003,16 +3003,16 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["web_ui_username"] = web_ui_username; if (web_ui_password.length > 0) settings["web_ui_password"] = web_ui_password; - settings["bypass_local_auth"] = $("bypass_local_auth_checkbox").checked; - settings["bypass_auth_subnet_whitelist_enabled"] = $("bypass_auth_subnet_whitelist_checkbox").checked; - settings["bypass_auth_subnet_whitelist"] = $("bypass_auth_subnet_whitelist_textarea").value; - settings["web_ui_max_auth_fail_count"] = Number($("webUIMaxAuthFailCountInput").value); - settings["web_ui_ban_duration"] = Number($("webUIBanDurationInput").value); - settings["web_ui_session_timeout"] = Number($("webUISessionTimeoutInput").value); + settings["bypass_local_auth"] = document.getElementById("bypass_local_auth_checkbox").checked; + settings["bypass_auth_subnet_whitelist_enabled"] = document.getElementById("bypass_auth_subnet_whitelist_checkbox").checked; + settings["bypass_auth_subnet_whitelist"] = document.getElementById("bypass_auth_subnet_whitelist_textarea").value; + settings["web_ui_max_auth_fail_count"] = Number(document.getElementById("webUIMaxAuthFailCountInput").value); + settings["web_ui_ban_duration"] = Number(document.getElementById("webUIBanDurationInput").value); + settings["web_ui_session_timeout"] = Number(document.getElementById("webUISessionTimeoutInput").value); // Use alternative WebUI - const alternative_webui_enabled = $("use_alt_webui_checkbox").checked; - const webui_files_location_textarea = $("webui_files_location_textarea").value; + const alternative_webui_enabled = document.getElementById("use_alt_webui_checkbox").checked; + const webui_files_location_textarea = document.getElementById("webui_files_location_textarea").value; if (alternative_webui_enabled && (webui_files_location_textarea.trim() === "")) { alert("QBT_TR(The alternative WebUI files location cannot be blank.)QBT_TR[CONTEXT=OptionsDialog]"); return; @@ -3021,105 +3021,105 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["alternative_webui_path"] = webui_files_location_textarea; // Security - settings["web_ui_clickjacking_protection_enabled"] = $("clickjacking_protection_checkbox").checked; - settings["web_ui_csrf_protection_enabled"] = $("csrf_protection_checkbox").checked; - settings["web_ui_secure_cookie_enabled"] = $("secureCookieCheckbox").checked; - settings["web_ui_host_header_validation_enabled"] = $("host_header_validation_checkbox").checked; + settings["web_ui_clickjacking_protection_enabled"] = document.getElementById("clickjacking_protection_checkbox").checked; + settings["web_ui_csrf_protection_enabled"] = document.getElementById("csrf_protection_checkbox").checked; + settings["web_ui_secure_cookie_enabled"] = document.getElementById("secureCookieCheckbox").checked; + settings["web_ui_host_header_validation_enabled"] = document.getElementById("host_header_validation_checkbox").checked; // Custom HTTP headers - settings["web_ui_use_custom_http_headers_enabled"] = $("webUIUseCustomHTTPHeadersCheckbox").checked; - settings["web_ui_custom_http_headers"] = $("webUICustomHTTPHeadersTextarea").value; + settings["web_ui_use_custom_http_headers_enabled"] = document.getElementById("webUIUseCustomHTTPHeadersCheckbox").checked; + settings["web_ui_custom_http_headers"] = document.getElementById("webUICustomHTTPHeadersTextarea").value; // Reverse Proxy - settings["web_ui_reverse_proxy_enabled"] = $("webUIReverseProxySupportCheckbox").checked; - settings["web_ui_reverse_proxies_list"] = $("webUIReverseProxiesListTextarea").value; + settings["web_ui_reverse_proxy_enabled"] = document.getElementById("webUIReverseProxySupportCheckbox").checked; + settings["web_ui_reverse_proxies_list"] = document.getElementById("webUIReverseProxiesListTextarea").value; // Update my dynamic domain name - settings["dyndns_enabled"] = $("use_dyndns_checkbox").checked; - settings["dyndns_service"] = Number($("dyndns_select").value); - settings["dyndns_domain"] = $("dyndns_domain_text").value; - settings["dyndns_username"] = $("dyndns_username_text").value; - settings["dyndns_password"] = $("dyndns_password_text").value; + settings["dyndns_enabled"] = document.getElementById("use_dyndns_checkbox").checked; + settings["dyndns_service"] = Number(document.getElementById("dyndns_select").value); + settings["dyndns_domain"] = document.getElementById("dyndns_domain_text").value; + settings["dyndns_username"] = document.getElementById("dyndns_username_text").value; + settings["dyndns_password"] = document.getElementById("dyndns_password_text").value; // Update advanced settings // qBittorrent section - settings["resume_data_storage_type"] = $("resumeDataStorageType").value; - settings["torrent_content_remove_option"] = $("torrentContentRemoveOption").value; - settings["memory_working_set_limit"] = Number($("memoryWorkingSetLimit").value); - settings["current_network_interface"] = $("networkInterface").value; - settings["current_interface_address"] = $("optionalIPAddressToBind").value; - settings["save_resume_data_interval"] = Number($("saveResumeDataInterval").value); - settings["save_statistics_interval"] = Number($("saveStatisticsInterval").value); - settings["torrent_file_size_limit"] = ($("torrentFileSizeLimit").value * 1024 * 1024); + settings["resume_data_storage_type"] = document.getElementById("resumeDataStorageType").value; + settings["torrent_content_remove_option"] = document.getElementById("torrentContentRemoveOption").value; + settings["memory_working_set_limit"] = Number(document.getElementById("memoryWorkingSetLimit").value); + settings["current_network_interface"] = document.getElementById("networkInterface").value; + settings["current_interface_address"] = document.getElementById("optionalIPAddressToBind").value; + settings["save_resume_data_interval"] = Number(document.getElementById("saveResumeDataInterval").value); + settings["save_statistics_interval"] = Number(document.getElementById("saveStatisticsInterval").value); + settings["torrent_file_size_limit"] = (document.getElementById("torrentFileSizeLimit").value * 1024 * 1024); settings["confirm_torrent_recheck"] = document.getElementById("confirmTorrentRecheck").checked; - settings["recheck_completed_torrents"] = $("recheckTorrentsOnCompletion").checked; - settings["app_instance_name"] = $("appInstanceName").value; - settings["refresh_interval"] = Number($("refreshInterval").value); - settings["resolve_peer_countries"] = $("resolvePeerCountries").checked; - settings["reannounce_when_address_changed"] = $("reannounceWhenAddressChanged").checked; - settings["enable_embedded_tracker"] = $("enableEmbeddedTracker").checked; - settings["embedded_tracker_port"] = Number($("embeddedTrackerPort").value); - settings["embedded_tracker_port_forwarding"] = $("embeddedTrackerPortForwarding").checked; - settings["mark_of_the_web"] = $("markOfTheWeb").checked; - settings["ignore_ssl_errors"] = $("ignoreSSLErrors").checked; - settings["python_executable_path"] = $("pythonExecutablePath").value; + settings["recheck_completed_torrents"] = document.getElementById("recheckTorrentsOnCompletion").checked; + settings["app_instance_name"] = document.getElementById("appInstanceName").value; + settings["refresh_interval"] = Number(document.getElementById("refreshInterval").value); + settings["resolve_peer_countries"] = document.getElementById("resolvePeerCountries").checked; + settings["reannounce_when_address_changed"] = document.getElementById("reannounceWhenAddressChanged").checked; + settings["enable_embedded_tracker"] = document.getElementById("enableEmbeddedTracker").checked; + settings["embedded_tracker_port"] = Number(document.getElementById("embeddedTrackerPort").value); + settings["embedded_tracker_port_forwarding"] = document.getElementById("embeddedTrackerPortForwarding").checked; + settings["mark_of_the_web"] = document.getElementById("markOfTheWeb").checked; + settings["ignore_ssl_errors"] = document.getElementById("ignoreSSLErrors").checked; + settings["python_executable_path"] = document.getElementById("pythonExecutablePath").value; // libtorrent section - settings["bdecode_depth_limit"] = Number($("bdecodeDepthLimit").value); - settings["bdecode_token_limit"] = Number($("bdecodeTokenLimit").value); - settings["async_io_threads"] = Number($("asyncIOThreads").value); - settings["hashing_threads"] = Number($("hashingThreads").value); - settings["file_pool_size"] = Number($("filePoolSize").value); - settings["checking_memory_use"] = Number($("outstandMemoryWhenCheckingTorrents").value); - settings["disk_cache"] = Number($("diskCache").value); - settings["disk_cache_ttl"] = Number($("diskCacheExpiryInterval").value); - settings["disk_queue_size"] = (Number($("diskQueueSize").value) * 1024); - settings["disk_io_type"] = Number($("diskIOType").value); - settings["disk_io_read_mode"] = Number($("diskIOReadMode").value); - settings["disk_io_write_mode"] = Number($("diskIOWriteMode").value); - settings["enable_coalesce_read_write"] = $("coalesceReadsAndWrites").checked; - settings["enable_piece_extent_affinity"] = $("pieceExtentAffinity").checked; - settings["enable_upload_suggestions"] = $("sendUploadPieceSuggestions").checked; - settings["send_buffer_watermark"] = Number($("sendBufferWatermark").value); - settings["send_buffer_low_watermark"] = Number($("sendBufferLowWatermark").value); - settings["send_buffer_watermark_factor"] = Number($("sendBufferWatermarkFactor").value); - settings["connection_speed"] = Number($("connectionSpeed").value); - settings["socket_send_buffer_size"] = ($("socketSendBufferSize").value * 1024); - settings["socket_receive_buffer_size"] = ($("socketReceiveBufferSize").value * 1024); - settings["socket_backlog_size"] = Number($("socketBacklogSize").value); - settings["outgoing_ports_min"] = Number($("outgoingPortsMin").value); - settings["outgoing_ports_max"] = Number($("outgoingPortsMax").value); - settings["upnp_lease_duration"] = Number($("UPnPLeaseDuration").value); - settings["peer_tos"] = Number($("peerToS").value); - settings["utp_tcp_mixed_mode"] = Number($("utpTCPMixedModeAlgorithm").value); - settings["hostname_cache_ttl"] = Number($("hostnameCacheTTL").value); - settings["idn_support_enabled"] = $("IDNSupportCheckbox").checked; - settings["enable_multi_connections_from_same_ip"] = $("allowMultipleConnectionsFromTheSameIPAddress").checked; - settings["validate_https_tracker_certificate"] = $("validateHTTPSTrackerCertificate").checked; - settings["ssrf_mitigation"] = $("mitigateSSRF").checked; - settings["block_peers_on_privileged_ports"] = $("blockPeersOnPrivilegedPorts").checked; - settings["upload_slots_behavior"] = Number($("uploadSlotsBehavior").value); - settings["upload_choking_algorithm"] = Number($("uploadChokingAlgorithm").value); - settings["announce_to_all_trackers"] = $("announceAllTrackers").checked; - settings["announce_to_all_tiers"] = $("announceAllTiers").checked; - settings["announce_ip"] = $("announceIP").value; - const announcePort = Number($("announcePort").value); + settings["bdecode_depth_limit"] = Number(document.getElementById("bdecodeDepthLimit").value); + settings["bdecode_token_limit"] = Number(document.getElementById("bdecodeTokenLimit").value); + settings["async_io_threads"] = Number(document.getElementById("asyncIOThreads").value); + settings["hashing_threads"] = Number(document.getElementById("hashingThreads").value); + settings["file_pool_size"] = Number(document.getElementById("filePoolSize").value); + settings["checking_memory_use"] = Number(document.getElementById("outstandMemoryWhenCheckingTorrents").value); + settings["disk_cache"] = Number(document.getElementById("diskCache").value); + settings["disk_cache_ttl"] = Number(document.getElementById("diskCacheExpiryInterval").value); + settings["disk_queue_size"] = (Number(document.getElementById("diskQueueSize").value) * 1024); + settings["disk_io_type"] = Number(document.getElementById("diskIOType").value); + settings["disk_io_read_mode"] = Number(document.getElementById("diskIOReadMode").value); + settings["disk_io_write_mode"] = Number(document.getElementById("diskIOWriteMode").value); + settings["enable_coalesce_read_write"] = document.getElementById("coalesceReadsAndWrites").checked; + settings["enable_piece_extent_affinity"] = document.getElementById("pieceExtentAffinity").checked; + settings["enable_upload_suggestions"] = document.getElementById("sendUploadPieceSuggestions").checked; + settings["send_buffer_watermark"] = Number(document.getElementById("sendBufferWatermark").value); + settings["send_buffer_low_watermark"] = Number(document.getElementById("sendBufferLowWatermark").value); + settings["send_buffer_watermark_factor"] = Number(document.getElementById("sendBufferWatermarkFactor").value); + settings["connection_speed"] = Number(document.getElementById("connectionSpeed").value); + settings["socket_send_buffer_size"] = (document.getElementById("socketSendBufferSize").value * 1024); + settings["socket_receive_buffer_size"] = (document.getElementById("socketReceiveBufferSize").value * 1024); + settings["socket_backlog_size"] = Number(document.getElementById("socketBacklogSize").value); + settings["outgoing_ports_min"] = Number(document.getElementById("outgoingPortsMin").value); + settings["outgoing_ports_max"] = Number(document.getElementById("outgoingPortsMax").value); + settings["upnp_lease_duration"] = Number(document.getElementById("UPnPLeaseDuration").value); + settings["peer_tos"] = Number(document.getElementById("peerToS").value); + settings["utp_tcp_mixed_mode"] = Number(document.getElementById("utpTCPMixedModeAlgorithm").value); + settings["hostname_cache_ttl"] = Number(document.getElementById("hostnameCacheTTL").value); + settings["idn_support_enabled"] = document.getElementById("IDNSupportCheckbox").checked; + settings["enable_multi_connections_from_same_ip"] = document.getElementById("allowMultipleConnectionsFromTheSameIPAddress").checked; + settings["validate_https_tracker_certificate"] = document.getElementById("validateHTTPSTrackerCertificate").checked; + settings["ssrf_mitigation"] = document.getElementById("mitigateSSRF").checked; + settings["block_peers_on_privileged_ports"] = document.getElementById("blockPeersOnPrivilegedPorts").checked; + settings["upload_slots_behavior"] = Number(document.getElementById("uploadSlotsBehavior").value); + settings["upload_choking_algorithm"] = Number(document.getElementById("uploadChokingAlgorithm").value); + settings["announce_to_all_trackers"] = document.getElementById("announceAllTrackers").checked; + settings["announce_to_all_tiers"] = document.getElementById("announceAllTiers").checked; + settings["announce_ip"] = document.getElementById("announceIP").value; + const announcePort = Number(document.getElementById("announcePort").value); if (Number.isNaN(announcePort) || (announcePort < 0) || (announcePort > 65535)) { alert("QBT_TR(The announce port must be between 0 and 65535.)QBT_TR[CONTEXT=OptionsDialog]"); return; } settings["announce_port"] = announcePort; - settings["max_concurrent_http_announces"] = Number($("maxConcurrentHTTPAnnounces").value); - settings["stop_tracker_timeout"] = Number($("stopTrackerTimeout").value); - settings["peer_turnover"] = Number($("peerTurnover").value); - settings["peer_turnover_cutoff"] = Number($("peerTurnoverCutoff").value); - settings["peer_turnover_interval"] = Number($("peerTurnoverInterval").value); - settings["request_queue_size"] = Number($("requestQueueSize").value); - settings["dht_bootstrap_nodes"] = $("dhtBootstrapNodes").value; - settings["i2p_inbound_quantity"] = Number($("i2pInboundQuantity").value); - settings["i2p_outbound_quantity"] = Number($("i2pOutboundQuantity").value); - settings["i2p_inbound_length"] = Number($("i2pInboundLength").value); - settings["i2p_outbound_length"] = Number($("i2pOutboundLength").value); + settings["max_concurrent_http_announces"] = Number(document.getElementById("maxConcurrentHTTPAnnounces").value); + settings["stop_tracker_timeout"] = Number(document.getElementById("stopTrackerTimeout").value); + settings["peer_turnover"] = Number(document.getElementById("peerTurnover").value); + settings["peer_turnover_cutoff"] = Number(document.getElementById("peerTurnoverCutoff").value); + settings["peer_turnover_interval"] = Number(document.getElementById("peerTurnoverInterval").value); + settings["request_queue_size"] = Number(document.getElementById("requestQueueSize").value); + settings["dht_bootstrap_nodes"] = document.getElementById("dhtBootstrapNodes").value; + settings["i2p_inbound_quantity"] = Number(document.getElementById("i2pInboundQuantity").value); + settings["i2p_outbound_quantity"] = Number(document.getElementById("i2pOutboundQuantity").value); + settings["i2p_inbound_length"] = Number(document.getElementById("i2pInboundLength").value); + settings["i2p_outbound_length"] = Number(document.getElementById("i2pOutboundLength").value); // Send it to qBT window.parent.qBittorrent.Cache.preferences.set({ @@ -3137,7 +3137,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD }; const setup = () => { - watchedFoldersTable = new HtmlTable($("watched_folders_tab")); + watchedFoldersTable = new HtmlTable(document.getElementById("watched_folders_tab")); const buildInfo = window.qBittorrent.Cache.buildInfo.get(); @@ -3145,29 +3145,29 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD const libtorrentVersion = window.qBittorrent.Misc.parseVersion(buildInfo.libtorrent); if (libtorrentVersion.valid) { if (libtorrentVersion.major >= 2) { - $("rowDiskCache").style.display = "none"; - $("rowDiskCacheExpiryInterval").style.display = "none"; - $("rowCoalesceReadsAndWrites").style.display = "none"; + document.getElementById("rowDiskCache").style.display = "none"; + document.getElementById("rowDiskCacheExpiryInterval").style.display = "none"; + document.getElementById("rowCoalesceReadsAndWrites").style.display = "none"; } else { - $("fieldsetI2p").style.display = "none"; - $("rowMemoryWorkingSetLimit").style.display = "none"; - $("rowHashingThreads").style.display = "none"; - $("rowDiskIOType").style.display = "none"; - $("rowI2pInboundQuantity").style.display = "none"; - $("rowI2pOutboundQuantity").style.display = "none"; - $("rowI2pInboundLength").style.display = "none"; - $("rowI2pOutboundLength").style.display = "none"; + document.getElementById("fieldsetI2p").style.display = "none"; + document.getElementById("rowMemoryWorkingSetLimit").style.display = "none"; + document.getElementById("rowHashingThreads").style.display = "none"; + document.getElementById("rowDiskIOType").style.display = "none"; + document.getElementById("rowI2pInboundQuantity").style.display = "none"; + document.getElementById("rowI2pOutboundQuantity").style.display = "none"; + document.getElementById("rowI2pInboundLength").style.display = "none"; + document.getElementById("rowI2pOutboundLength").style.display = "none"; } if (!((libtorrentVersion.major >= 2) && (libtorrentVersion.minor >= 0) && (libtorrentVersion.fix >= 6))) - $("diskIOWriteModeWriteThrough").style.display = "none"; + document.getElementById("diskIOWriteModeWriteThrough").style.display = "none"; } if ((buildInfo.platform !== "macos") && (buildInfo.platform !== "windows")) - $("rowMarkOfTheWeb").style.display = "none"; + document.getElementById("rowMarkOfTheWeb").style.display = "none"; - $("networkInterface").addEventListener("change", function() { + document.getElementById("networkInterface").addEventListener("change", function() { updateInterfaceAddresses(this.value, ""); }); diff --git a/src/webui/www/private/views/preferencesToolbar.html b/src/webui/www/private/views/preferencesToolbar.html index c2ff79993..20eb487aa 100644 --- a/src/webui/www/private/views/preferencesToolbar.html +++ b/src/webui/www/private/views/preferencesToolbar.html @@ -36,37 +36,37 @@ // Tabs MochaUI.initializeTabs("preferencesTabs"); - $("PrefBehaviorLink").addEventListener("click", (e) => { + document.getElementById("PrefBehaviorLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("BehaviorTab").classList.remove("invisible"); + document.getElementById("BehaviorTab").classList.remove("invisible"); }); - $("PrefDownloadsLink").addEventListener("click", (e) => { + document.getElementById("PrefDownloadsLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("DownloadsTab").classList.remove("invisible"); + document.getElementById("DownloadsTab").classList.remove("invisible"); }); - $("PrefConnectionLink").addEventListener("click", (e) => { + document.getElementById("PrefConnectionLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("ConnectionTab").classList.remove("invisible"); + document.getElementById("ConnectionTab").classList.remove("invisible"); }); - $("PrefSpeedLink").addEventListener("click", (e) => { + document.getElementById("PrefSpeedLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("SpeedTab").classList.remove("invisible"); + document.getElementById("SpeedTab").classList.remove("invisible"); }); - $("PrefBittorrentLink").addEventListener("click", (e) => { + document.getElementById("PrefBittorrentLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("BittorrentTab").classList.remove("invisible"); + document.getElementById("BittorrentTab").classList.remove("invisible"); }); - $("PrefRSSLink").addEventListener("click", (e) => { + document.getElementById("PrefRSSLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("RSSTab").classList.remove("invisible"); + document.getElementById("RSSTab").classList.remove("invisible"); }); - $("PrefWebUILink").addEventListener("click", (e) => { + document.getElementById("PrefWebUILink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("WebUITab").classList.remove("invisible"); + document.getElementById("WebUITab").classList.remove("invisible"); }); - $("PrefAdvancedLink").addEventListener("click", (e) => { + document.getElementById("PrefAdvancedLink").addEventListener("click", (e) => { Array.prototype.forEach.call(document.querySelectorAll(".PrefTab"), (tab => tab.classList.add("invisible"))); - $("AdvancedTab").classList.remove("invisible"); + document.getElementById("AdvancedTab").classList.remove("invisible"); }); })(); diff --git a/src/webui/www/private/views/rss.html b/src/webui/www/private/views/rss.html index 7088f6f8f..76c0fdbdd 100644 --- a/src/webui/www/private/views/rss.html +++ b/src/webui/www/private/views/rss.html @@ -218,7 +218,7 @@ const pref = window.parent.qBittorrent.Cache.preferences.get(); if (!pref.rss_processing_enabled) - $("rssFetchingDisabled").classList.remove("invisible"); + document.getElementById("rssFetchingDisabled").classList.remove("invisible"); const rssFeedContextMenu = new window.qBittorrent.ContextMenu.RssFeedContextMenu({ targets: "#rssFeedTableDiv tbody tr", @@ -263,13 +263,13 @@ } }); - rssFeedContextMenu.addTarget($("rssFeedTableDiv")); + rssFeedContextMenu.addTarget(document.getElementById("rssFeedTableDiv")); // deselect feed when clicking on empty part of table - $("rssFeedTableDiv").addEventListener("click", (e) => { + document.getElementById("rssFeedTableDiv").addEventListener("click", (e) => { rssFeedTable.deselectAll(); rssFeedTable.deselectRow(); }); - $("rssFeedTableDiv").addEventListener("contextmenu", (e) => { + document.getElementById("rssFeedTableDiv").addEventListener("contextmenu", (e) => { if (e.target.nodeName === "DIV") { rssFeedTable.deselectAll(); rssFeedTable.deselectRow(); diff --git a/src/webui/www/private/views/rssDownloader.html b/src/webui/www/private/views/rssDownloader.html index 4a0b8d6ce..8da31614e 100644 --- a/src/webui/www/private/views/rssDownloader.html +++ b/src/webui/www/private/views/rssDownloader.html @@ -370,30 +370,30 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const pref = window.parent.qBittorrent.Cache.preferences.get(); if (!pref.rss_auto_downloading_enabled) - $("rssDownloaderDisabled").classList.remove("invisible"); + document.getElementById("rssDownloaderDisabled").classList.remove("invisible"); // recalculate height - const warningHeight = $("rssDownloaderDisabled").getBoundingClientRect().height; + const warningHeight = document.getElementById("rssDownloaderDisabled").getBoundingClientRect().height; - $("leftRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; - $("centerRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; - $("rightRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; + document.getElementById("leftRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; + document.getElementById("centerRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; + document.getElementById("rightRssDownloaderColumn").style.height = `calc(100% - ${warningHeight}px)`; - $("rulesTable").style.height = `calc(100% - ${$("rulesTableDesc").getBoundingClientRect().height}px)`; - $("rssDownloaderArticlesTable").style.height = `calc(100% - ${$("articleTableDesc").getBoundingClientRect().height}px)`; + document.getElementById("rulesTable").style.height = `calc(100% - ${document.getElementById("rulesTableDesc").getBoundingClientRect().height}px)`; + document.getElementById("rssDownloaderArticlesTable").style.height = `calc(100% - ${document.getElementById("articleTableDesc").getBoundingClientRect().height}px)`; - const centerRowNotTableHeight = $("saveButton").getBoundingClientRect().height - + $("ruleSettings").getBoundingClientRect().height + 15; + const centerRowNotTableHeight = document.getElementById("saveButton").getBoundingClientRect().height + + document.getElementById("ruleSettings").getBoundingClientRect().height + 15; - $("rssDownloaderFeeds").style.height = `calc(100% - ${centerRowNotTableHeight}px)`; + document.getElementById("rssDownloaderFeeds").style.height = `calc(100% - ${centerRowNotTableHeight}px)`; // firefox calculates the height of the table inside fieldset differently and thus doesn't need the offset if (navigator.userAgent.toLowerCase().includes("firefox")) { - $("rssDownloaderFeedsTable").style.height = "100%"; + document.getElementById("rssDownloaderFeedsTable").style.height = "100%"; } else { - const outsideTableHeight = ($("rssDownloaderFeedsTable").getBoundingClientRect().top - $("rssDownloaderFeeds").getBoundingClientRect().top) - 10; - $("rssDownloaderFeedsTable").style.height = `calc(100% - ${outsideTableHeight}px)`; + const outsideTableHeight = (document.getElementById("rssDownloaderFeedsTable").getBoundingClientRect().top - document.getElementById("rssDownloaderFeeds").getBoundingClientRect().top) - 10; + document.getElementById("rssDownloaderFeedsTable").style.height = `calc(100% - ${outsideTableHeight}px)`; } const rssDownloaderRuleContextMenu = new window.qBittorrent.ContextMenu.RssDownloaderRuleContextMenu({ @@ -419,9 +419,9 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also rssDownloaderFeedSelectionTable.setup("rssDownloaderFeedSelectionTableDiv", "rssDownloaderFeedSelectionFixedHeaderDiv"); rssDownloaderArticlesTable.setup("rssDownloaderArticlesTableDiv", "rssDownloaderArticlesFixedHeaderDiv"); - rssDownloaderRuleContextMenu.addTarget($("rulesTable")); + rssDownloaderRuleContextMenu.addTarget(document.getElementById("rulesTable")); // deselect feed when clicking on empty part of table - $("rulesTable").addEventListener("click", (e) => { + document.getElementById("rulesTable").addEventListener("click", (e) => { if (e.target.nodeName === "DIV") { rssDownloaderRulesTable.deselectAll(); rssDownloaderRulesTable.deselectRow(); @@ -439,7 +439,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const responseJSON = await response.json(); - const combobox = $("assignCategoryCombobox"); + const combobox = document.getElementById("assignCategoryCombobox"); for (const cat in responseJSON) { if (!Object.hasOwn(responseJSON, cat)) continue; @@ -475,8 +475,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also }; flatten(responseJSON); }); - $("savetoDifferentDir").addEventListener("click", () => { - $("saveToText").disabled = !$("savetoDifferentDir").checked; + document.getElementById("savetoDifferentDir").addEventListener("click", () => { + document.getElementById("saveToText").disabled = !document.getElementById("savetoDifferentDir").checked; }); updateRulesList(); }; @@ -599,27 +599,27 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const lastSelectedRow = rssDownloaderRulesTable.selectedRows.at(-1); const rule = rssDownloaderRulesTable.getRow(lastSelectedRow).full_data.name; - rulesList[rule].useRegex = $("useRegEx").checked; - rulesList[rule].mustContain = $("mustContainText").value; - rulesList[rule].mustNotContain = $("mustNotContainText").value; - rulesList[rule].episodeFilter = $("episodeFilterText").value; - rulesList[rule].smartFilter = $("useSmartFilter").checked; - rulesList[rule].ignoreDays = Number($("ignoreDaysValue").value); + rulesList[rule].useRegex = document.getElementById("useRegEx").checked; + rulesList[rule].mustContain = document.getElementById("mustContainText").value; + rulesList[rule].mustNotContain = document.getElementById("mustNotContainText").value; + rulesList[rule].episodeFilter = document.getElementById("episodeFilterText").value; + rulesList[rule].smartFilter = document.getElementById("useSmartFilter").checked; + rulesList[rule].ignoreDays = Number(document.getElementById("ignoreDaysValue").value); rulesList[rule].affectedFeeds = [...rssDownloaderFeedSelectionTable.getRowValues()] .filter((row) => row.full_data.checked) .map((row) => row.full_data.url); - rulesList[rule].torrentParams.category = $("assignCategoryCombobox").value; - rulesList[rule].torrentParams.tags = $("ruleAddTags").value.split(","); - if ($("savetoDifferentDir").checked) { - rulesList[rule].torrentParams.save_path = $("saveToText").value; + rulesList[rule].torrentParams.category = document.getElementById("assignCategoryCombobox").value; + rulesList[rule].torrentParams.tags = document.getElementById("ruleAddTags").value.split(","); + if (document.getElementById("savetoDifferentDir").checked) { + rulesList[rule].torrentParams.save_path = document.getElementById("saveToText").value; rulesList[rule].torrentParams.use_auto_tmm = false; } else { rulesList[rule].torrentParams.save_path = ""; } - switch ($("addStoppedCombobox").value) { + switch (document.getElementById("addStoppedCombobox").value) { case "default": rulesList[rule].torrentParams.stopped = null; break; @@ -631,7 +631,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also break; } - switch ($("contentLayoutCombobox").value) { + switch (document.getElementById("contentLayoutCombobox").value) { case "Default": rulesList[rule].torrentParams.content_layout = null; break; @@ -701,89 +701,89 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const showRule = (ruleName) => { if (ruleName === "") { // disable all - $("saveButton").disabled = true; - $("useRegEx").disabled = true; - $("mustContainText").disabled = true; - $("mustNotContainText").disabled = true; - $("episodeFilterText").disabled = true; - $("useSmartFilter").disabled = true; - $("assignCategoryCombobox").disabled = true; - $("ruleAddTags").disabled = true; - $("savetoDifferentDir").disabled = true; - $("saveToText").disabled = true; - $("ignoreDaysValue").disabled = true; - $("addStoppedCombobox").disabled = true; - $("contentLayoutCombobox").disabled = true; + document.getElementById("saveButton").disabled = true; + document.getElementById("useRegEx").disabled = true; + document.getElementById("mustContainText").disabled = true; + document.getElementById("mustNotContainText").disabled = true; + document.getElementById("episodeFilterText").disabled = true; + document.getElementById("useSmartFilter").disabled = true; + document.getElementById("assignCategoryCombobox").disabled = true; + document.getElementById("ruleAddTags").disabled = true; + document.getElementById("savetoDifferentDir").disabled = true; + document.getElementById("saveToText").disabled = true; + document.getElementById("ignoreDaysValue").disabled = true; + document.getElementById("addStoppedCombobox").disabled = true; + document.getElementById("contentLayoutCombobox").disabled = true; // reset all boxes - $("useRegEx").checked = false; - $("mustContainText").value = ""; - $("mustNotContainText").value = ""; - $("episodeFilterText").value = ""; - $("useSmartFilter").checked = false; - $("assignCategoryCombobox").value = "default"; - $("ruleAddTags").value = ""; - $("savetoDifferentDir").checked = false; - $("saveToText").value = ""; - $("ignoreDaysValue").value = 0; - $("lastMatchText").textContent = "QBT_TR(Last Match: Unknown)QBT_TR[CONTEXT=AutomatedRssDownloader]"; - $("addStoppedCombobox").value = "default"; - $("contentLayoutCombobox").value = "Default"; + document.getElementById("useRegEx").checked = false; + document.getElementById("mustContainText").value = ""; + document.getElementById("mustNotContainText").value = ""; + document.getElementById("episodeFilterText").value = ""; + document.getElementById("useSmartFilter").checked = false; + document.getElementById("assignCategoryCombobox").value = "default"; + document.getElementById("ruleAddTags").value = ""; + document.getElementById("savetoDifferentDir").checked = false; + document.getElementById("saveToText").value = ""; + document.getElementById("ignoreDaysValue").value = 0; + document.getElementById("lastMatchText").textContent = "QBT_TR(Last Match: Unknown)QBT_TR[CONTEXT=AutomatedRssDownloader]"; + document.getElementById("addStoppedCombobox").value = "default"; + document.getElementById("contentLayoutCombobox").value = "Default"; rssDownloaderFeedSelectionTable.clear(); rssDownloaderArticlesTable.clear(); - $("mustContainText").title = ""; - $("mustNotContainText").title = ""; - $("episodeFilterText").title = ""; + document.getElementById("mustContainText").title = ""; + document.getElementById("mustNotContainText").title = ""; + document.getElementById("episodeFilterText").title = ""; } else { // enable all - $("saveButton").disabled = false; - $("useRegEx").disabled = false; - $("mustContainText").disabled = false; - $("mustNotContainText").disabled = false; - $("episodeFilterText").disabled = false; - $("useSmartFilter").disabled = false; - $("assignCategoryCombobox").disabled = false; - $("ruleAddTags").disabled = false; - $("savetoDifferentDir").disabled = false; - $("ignoreDaysValue").disabled = false; - $("addStoppedCombobox").disabled = false; - $("contentLayoutCombobox").disabled = false; + document.getElementById("saveButton").disabled = false; + document.getElementById("useRegEx").disabled = false; + document.getElementById("mustContainText").disabled = false; + document.getElementById("mustNotContainText").disabled = false; + document.getElementById("episodeFilterText").disabled = false; + document.getElementById("useSmartFilter").disabled = false; + document.getElementById("assignCategoryCombobox").disabled = false; + document.getElementById("ruleAddTags").disabled = false; + document.getElementById("savetoDifferentDir").disabled = false; + document.getElementById("ignoreDaysValue").disabled = false; + document.getElementById("addStoppedCombobox").disabled = false; + document.getElementById("contentLayoutCombobox").disabled = false; // load rule settings - $("useRegEx").checked = rulesList[ruleName].useRegex; - $("mustContainText").value = rulesList[ruleName].mustContain; - $("mustNotContainText").value = rulesList[ruleName].mustNotContain; - $("episodeFilterText").value = rulesList[ruleName].episodeFilter; - $("useSmartFilter").checked = rulesList[ruleName].smartFilter; + document.getElementById("useRegEx").checked = rulesList[ruleName].useRegex; + document.getElementById("mustContainText").value = rulesList[ruleName].mustContain; + document.getElementById("mustNotContainText").value = rulesList[ruleName].mustNotContain; + document.getElementById("episodeFilterText").value = rulesList[ruleName].episodeFilter; + document.getElementById("useSmartFilter").checked = rulesList[ruleName].smartFilter; - $("assignCategoryCombobox").value = rulesList[ruleName].torrentParams.category ? rulesList[ruleName].torrentParams.category : "default"; - $("ruleAddTags").value = rulesList[ruleName].torrentParams.tags.join(","); - $("savetoDifferentDir").checked = rulesList[ruleName].torrentParams.save_path !== ""; - $("saveToText").disabled = !$("savetoDifferentDir").checked; - $("saveToText").value = rulesList[ruleName].torrentParams.save_path; - $("ignoreDaysValue").value = rulesList[ruleName].ignoreDays; + document.getElementById("assignCategoryCombobox").value = rulesList[ruleName].torrentParams.category ? rulesList[ruleName].torrentParams.category : "default"; + document.getElementById("ruleAddTags").value = rulesList[ruleName].torrentParams.tags.join(","); + document.getElementById("savetoDifferentDir").checked = rulesList[ruleName].torrentParams.save_path !== ""; + document.getElementById("saveToText").disabled = !document.getElementById("savetoDifferentDir").checked; + document.getElementById("saveToText").value = rulesList[ruleName].torrentParams.save_path; + document.getElementById("ignoreDaysValue").value = rulesList[ruleName].ignoreDays; // calculate days since last match if (rulesList[ruleName].lastMatch !== "") { const timeDiffInMs = new Date().getTime() - new Date(rulesList[ruleName].lastMatch).getTime(); const daysAgo = Math.floor(timeDiffInMs / (1000 * 60 * 60 * 24)).toString(); - $("lastMatchText").textContent = " QBT_TR(Last Match: %1 days ago)QBT_TR[CONTEXT=AutomatedRssDownloader]".replace("%1", daysAgo); + document.getElementById("lastMatchText").textContent = " QBT_TR(Last Match: %1 days ago)QBT_TR[CONTEXT=AutomatedRssDownloader]".replace("%1", daysAgo); } else { - $("lastMatchText").textContent = "QBT_TR(Last Match: Unknown)QBT_TR[CONTEXT=AutomatedRssDownloader]"; + document.getElementById("lastMatchText").textContent = "QBT_TR(Last Match: Unknown)QBT_TR[CONTEXT=AutomatedRssDownloader]"; } if ((rulesList[ruleName].torrentParams.stopped === undefined) || (rulesList[ruleName].torrentParams.stopped === null)) - $("addStoppedCombobox").value = "default"; + document.getElementById("addStoppedCombobox").value = "default"; else - $("addStoppedCombobox").value = rulesList[ruleName].torrentParams.stopped ? "always" : "never"; + document.getElementById("addStoppedCombobox").value = rulesList[ruleName].torrentParams.stopped ? "always" : "never"; if ((rulesList[ruleName].torrentParams.content_layout === undefined) || (rulesList[ruleName].torrentParams.content_layout === null)) - $("contentLayoutCombobox").value = "Default"; + document.getElementById("contentLayoutCombobox").value = "Default"; else - $("contentLayoutCombobox").value = rulesList[ruleName].torrentParams.content_layout; + document.getElementById("contentLayoutCombobox").value = rulesList[ruleName].torrentParams.content_layout; setElementTitles(); @@ -804,7 +804,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const setElementTitles = () => { let mainPart; - if ($("useRegEx").checked) { + if (document.getElementById("useRegEx").checked) { mainPart = "QBT_TR(Regex mode: use Perl-compatible regular expressions)QBT_TR[CONTEXT=AutomatedRssDownloader]\n\n"; } else { @@ -818,8 +818,8 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also const secondPart = "QBT_TR(An expression with an empty %1 clause (e.g. %2))QBT_TR[CONTEXT=AutomatedRssDownloader]" .replace("%1", "|").replace("%2", "expr|"); - $("mustContainText").title = `${mainPart}${secondPart}QBT_TR( will match all articles.)QBT_TR[CONTEXT=AutomatedRssDownloader]`; - $("mustNotContainText").title = `${mainPart}${secondPart}QBT_TR( will exclude all articles.)QBT_TR[CONTEXT=AutomatedRssDownloader]`; + document.getElementById("mustContainText").title = `${mainPart}${secondPart}QBT_TR( will match all articles.)QBT_TR[CONTEXT=AutomatedRssDownloader]`; + document.getElementById("mustNotContainText").title = `${mainPart}${secondPart}QBT_TR( will exclude all articles.)QBT_TR[CONTEXT=AutomatedRssDownloader]`; let episodeFilterTitle = "QBT_TR(Matches articles based on episode filter.)QBT_TR[CONTEXT=AutomatedRssDownloader]\n\n" + "QBT_TR(Example: )QBT_TR[CONTEXT=AutomatedRssDownloader]" @@ -835,7 +835,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also + " ● QBT_TR(Infinite range: 1x25-; matches episodes 25 and upward of season one, and all episodes of later seasons)QBT_TR[CONTEXT=AutomatedRssDownloader]"; episodeFilterTitle = episodeFilterTitle.replace(//g, "").replace(/<\/b>/g, ""); - $("episodeFilterText").title = episodeFilterTitle; + document.getElementById("episodeFilterText").title = episodeFilterTitle; }; return exports(); From b5394e7939344e7250a7128627a6d3a8a554db94 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sat, 26 Apr 2025 09:27:22 +0300 Subject: [PATCH 03/21] Don't interpret wildcard pattern as filepath globbing PR #22590. Closes #22583. --- src/base/utils/string.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/base/utils/string.cpp b/src/base/utils/string.cpp index f3fc4d87e..1fc6568f8 100644 --- a/src/base/utils/string.cpp +++ b/src/base/utils/string.cpp @@ -61,7 +61,12 @@ QString Utils::String::fromLocal8Bit(const std::string_view string) QString Utils::String::wildcardToRegexPattern(const QString &pattern) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + return QRegularExpression::wildcardToRegularExpression(pattern + , (QRegularExpression::UnanchoredWildcardConversion | QRegularExpression::NonPathWildcardConversion)); +#else return QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion); +#endif } QStringList Utils::String::splitCommand(const QString &command) From 70822e89426f695b2bade657622f4f4e219d9db7 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sat, 26 Apr 2025 09:28:24 +0300 Subject: [PATCH 04/21] Fix appearance of search history length spinbox PR #22605. --- src/gui/optionsdialog.ui | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index dbac539f7..263c2bf91 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -3290,15 +3290,9 @@ Disable encryption: Only connect to peers without protocol encryption - - QAbstractSpinBox::ButtonSymbols::PlusMinus - 99 - - QAbstractSpinBox::StepType::DefaultStepType - From 45babc336d85a89a8ea0d51367f4ec79a39dda42 Mon Sep 17 00:00:00 2001 From: Isak05 <51046377+Isak05@users.noreply.github.com> Date: Sun, 27 Apr 2025 09:02:52 +0200 Subject: [PATCH 05/21] Fix preview not opening on Wayland Deferring the opening of the preview slightly gives the preview select dialog time to close and for focus to shift back to the main window. PR #22608. Closes #22607. --------- Co-authored-by: Vladimir Golovnev --- src/gui/transferlistwidget.cpp | 20 ++++++++++++-------- src/gui/transferlistwidget.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 95814c0e6..6fb71bfaa 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -312,10 +312,7 @@ void TransferListWidget::torrentDoubleClicked() case PREVIEW_FILE: if (torrentContainsPreviewableFiles(torrent)) { - auto *dialog = new PreviewSelectDialog(this, torrent); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile); - dialog->show(); + openPreviewSelectDialog(torrent); } else { @@ -617,10 +614,7 @@ void TransferListWidget::previewSelectedTorrents() { if (torrentContainsPreviewableFiles(torrent)) { - auto *dialog = new PreviewSelectDialog(this, torrent); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile); - dialog->show(); + openPreviewSelectDialog(torrent); } else { @@ -1449,3 +1443,13 @@ void TransferListWidget::wheelEvent(QWheelEvent *event) QTreeView::wheelEvent(event); // event delegated to base class } + +void TransferListWidget::openPreviewSelectDialog(const BitTorrent::Torrent *torrent) +{ + auto *dialog = new PreviewSelectDialog(this, torrent); + dialog->setAttribute(Qt::WA_DeleteOnClose); + // Qt::QueuedConnection is required to prevent a bug on wayland compositors where the preview won't open. + // It occurs when the window focus shifts immediately after TransferListWidget::previewFile has been called. + connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile, Qt::QueuedConnection); + dialog->show(); +} diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index c5b24ba24..097dd809a 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -123,6 +123,7 @@ private: void dragMoveEvent(QDragMoveEvent *event) override; void dropEvent(QDropEvent *event) override; void wheelEvent(QWheelEvent *event) override; + void openPreviewSelectDialog(const BitTorrent::Torrent *torrent); QModelIndex mapToSource(const QModelIndex &index) const; QModelIndexList mapToSource(const QModelIndexList &indexes) const; QModelIndex mapFromSource(const QModelIndex &index) const; From 70dbe9468aba9162df139232480777c4d929269c Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 17 Apr 2025 18:48:12 +0800 Subject: [PATCH 06/21] WebUI: disallow unnecessary semicolons --- src/webui/www/eslint.config.mjs | 1 + src/webui/www/private/scripts/client.js | 2 +- src/webui/www/private/scripts/contextmenu.js | 22 +++++++++---------- src/webui/www/private/scripts/dynamicTable.js | 2 +- .../www/private/scripts/localpreferences.js | 2 +- src/webui/www/private/scripts/pathAutofill.js | 2 +- src/webui/www/private/scripts/search.js | 2 +- src/webui/www/private/views/preferences.html | 2 +- src/webui/www/private/views/rss.html | 2 +- 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/webui/www/eslint.config.mjs b/src/webui/www/eslint.config.mjs index 6aafb8d64..24de0c776 100644 --- a/src/webui/www/eslint.config.mjs +++ b/src/webui/www/eslint.config.mjs @@ -40,6 +40,7 @@ export default [ "prefer-template": "error", "radix": "error", "PreferArrowFunctions/prefer-arrow-functions": "error", + "Stylistic/no-extra-semi": "error", "Stylistic/no-mixed-operators": [ "error", { diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 15e7af365..0abc9c924 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -1818,5 +1818,5 @@ window.addEventListener("load", async () => { console.error(`Unexpected 'selected_window_tab' value: ${previouslyUsedTab}`); $("transfersTabLink").click(); break; - }; + } }); diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js index 7831461bf..4a389d424 100644 --- a/src/webui/www/private/scripts/contextmenu.js +++ b/src/webui/www/private/scripts/contextmenu.js @@ -292,7 +292,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.options.actions[action](element, this, action); return this; } - }; + } class FilterListContextMenu extends ContextMenu { constructor(options) { @@ -316,7 +316,7 @@ window.qBittorrent.ContextMenu ??= (() => { .setEnabled("stopTorrents", torrentsVisible) .setEnabled("deleteTorrents", torrentsVisible); } - }; + } class TorrentsTableContextMenu extends ContextMenu { updateMenuItems() { @@ -577,13 +577,13 @@ window.qBittorrent.ContextMenu ??= (() => { contextTagList.appendChild(setTagItem); } } - }; + } class StatusesFilterContextMenu extends FilterListContextMenu { updateMenuItems() { this.updateTorrentActions(); } - }; + } class CategoriesFilterContextMenu extends FilterListContextMenu { updateMenuItems() { @@ -604,7 +604,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.updateTorrentActions(); } - }; + } class TagsFilterContextMenu extends FilterListContextMenu { updateMenuItems() { @@ -616,7 +616,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.updateTorrentActions(); } - }; + } class TrackersFilterContextMenu extends FilterListContextMenu { updateMenuItems() { @@ -628,7 +628,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.updateTorrentActions(); } - }; + } class SearchPluginsTableContextMenu extends ContextMenu { updateMenuItems() { @@ -642,7 +642,7 @@ window.qBittorrent.ContextMenu ??= (() => { this.showItem("Uninstall"); } - }; + } class RssFeedContextMenu extends ContextMenu { updateMenuItems() { @@ -715,9 +715,9 @@ window.qBittorrent.ContextMenu ??= (() => { break; } } - }; + } - class RssArticleContextMenu extends ContextMenu {}; + class RssArticleContextMenu extends ContextMenu {} class RssDownloaderRuleContextMenu extends ContextMenu { adjustMenuPosition(e) { @@ -765,7 +765,7 @@ window.qBittorrent.ContextMenu ??= (() => { break; } } - }; + } return exports(); })(); diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index d05cd8c53..cd0147067 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -3128,7 +3128,7 @@ window.qBittorrent.DynamicTable ??= (() => { img.height = "22"; td.append(img); } - }; + } }, newColumn: function(name, style, caption, defaultWidth, defaultVisible) { const column = {}; diff --git a/src/webui/www/private/scripts/localpreferences.js b/src/webui/www/private/scripts/localpreferences.js index deb0c159f..73f341127 100644 --- a/src/webui/www/private/scripts/localpreferences.js +++ b/src/webui/www/private/scripts/localpreferences.js @@ -61,7 +61,7 @@ window.qBittorrent.LocalPreferences ??= (() => { console.error(err); } } - }; + } return exports(); })(); diff --git a/src/webui/www/private/scripts/pathAutofill.js b/src/webui/www/private/scripts/pathAutofill.js index 2e260f145..3568b8f71 100644 --- a/src/webui/www/private/scripts/pathAutofill.js +++ b/src/webui/www/private/scripts/pathAutofill.js @@ -85,7 +85,7 @@ window.qBittorrent.pathAutofill ??= (() => { input.addEventListener("input", function() { showPathSuggestions(this, "all"); }); input.classList.add("pathAutoFillInitialized"); } - }; + } return exports(); })(); diff --git a/src/webui/www/private/scripts/search.js b/src/webui/www/private/scripts/search.js index 3dc0b454b..47f9ad3a2 100644 --- a/src/webui/www/private/scripts/search.js +++ b/src/webui/www/private/scripts/search.js @@ -603,7 +603,7 @@ window.qBittorrent.Search ??= (() => { option.value = category.id; option.textContent = category.name; categoryOptions.push(option); - }; + } // first category is "All Categories" if (categoryOptions.length > 1) { diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 07109e68e..b392e263d 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -1891,7 +1891,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD case "other": other = $(`cb_watch_txt_${i}`).value.trim(); break; - }; + } folders[fpath] = other; } diff --git a/src/webui/www/private/views/rss.html b/src/webui/www/private/views/rss.html index 7088f6f8f..7db062c83 100644 --- a/src/webui/www/private/views/rss.html +++ b/src/webui/www/private/views/rss.html @@ -232,7 +232,7 @@ if ((row.full_data.dataPath.slice(0, selectedPath.length) === selectedPath) && (row.full_data.dataUid !== "")) feedsToUpdate.add(row); } - }; + } feedsToUpdate.forEach((feed) => refreshFeed(feed.full_data.dataUid)); }, markRead: markSelectedAsRead, From 1077cbba2b7d9a04c1d447aba35c94af463a26a4 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 17 Apr 2025 19:29:26 +0800 Subject: [PATCH 07/21] WebUI: ensure consistent shorthand syntax --- src/webui/www/eslint.config.mjs | 1 + src/webui/www/private/scripts/rename-files.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/webui/www/eslint.config.mjs b/src/webui/www/eslint.config.mjs index 24de0c776..58ff348bf 100644 --- a/src/webui/www/eslint.config.mjs +++ b/src/webui/www/eslint.config.mjs @@ -34,6 +34,7 @@ export default [ "no-undef": "off", "no-unused-vars": "off", "no-var": "error", + "object-shorthand": ["error", "consistent"], "operator-assignment": "error", "prefer-arrow-callback": "error", "prefer-const": "error", diff --git a/src/webui/www/private/scripts/rename-files.js b/src/webui/www/private/scripts/rename-files.js index 5087f793e..a320c83df 100644 --- a/src/webui/www/private/scripts/rename-files.js +++ b/src/webui/www/private/scripts/rename-files.js @@ -22,7 +22,7 @@ window.qBittorrent.MultiRename ??= (() => { // Search Options _inner_search: "", - setSearch(val) { + setSearch: function(val) { this._inner_search = val; this._inner_update(); this.onChanged(this.matchedFiles); @@ -33,7 +33,7 @@ window.qBittorrent.MultiRename ??= (() => { // Replacement Options _inner_replacement: "", - setReplacement(val) { + setReplacement: function(val) { this._inner_replacement = val; this._inner_update(); this.onChanged(this.matchedFiles); From e9fee414df8171cf9885275b19e77cba193dc1b9 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 17 Apr 2025 19:37:03 +0800 Subject: [PATCH 08/21] WebUI: disallow async functions which have no await expression --- src/webui/www/eslint.config.mjs | 1 + src/webui/www/private/downloadlimit.html | 4 ++-- src/webui/www/private/newtag.html | 4 ++-- src/webui/www/private/scripts/cache.js | 6 +++--- src/webui/www/private/shareratio.html | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/webui/www/eslint.config.mjs b/src/webui/www/eslint.config.mjs index 58ff348bf..ed4f3ab22 100644 --- a/src/webui/www/eslint.config.mjs +++ b/src/webui/www/eslint.config.mjs @@ -40,6 +40,7 @@ export default [ "prefer-const": "error", "prefer-template": "error", "radix": "error", + "require-await": "error", "PreferArrowFunctions/prefer-arrow-functions": "error", "Stylistic/no-extra-semi": "error", "Stylistic/no-mixed-operators": [ diff --git a/src/webui/www/private/downloadlimit.html b/src/webui/www/private/downloadlimit.html index d703cf79e..8f2f9da89 100644 --- a/src/webui/www/private/downloadlimit.html +++ b/src/webui/www/private/downloadlimit.html @@ -56,7 +56,7 @@ limit: limit }) }) - .then(async (response) => { + .then((response) => { if (!response.ok) return; @@ -72,7 +72,7 @@ limit: limit }) }) - .then(async (response) => { + .then((response) => { if (!response.ok) return; diff --git a/src/webui/www/private/newtag.html b/src/webui/www/private/newtag.html index a8067fecc..8287c5ef3 100644 --- a/src/webui/www/private/newtag.html +++ b/src/webui/www/private/newtag.html @@ -64,7 +64,7 @@ tags: tagName }) }) - .then(async (response) => { + .then((response) => { if (!response.ok) return; @@ -83,7 +83,7 @@ tags: tagName }) }) - .then(async (response) => { + .then((response) => { if (!response.ok) return; diff --git a/src/webui/www/private/scripts/cache.js b/src/webui/www/private/scripts/cache.js index 3b93c8757..999a5db2d 100644 --- a/src/webui/www/private/scripts/cache.js +++ b/src/webui/www/private/scripts/cache.js @@ -53,7 +53,7 @@ window.qBittorrent.Cache ??= (() => { class BuildInfoCache { #m_store = {}; - async init() { + init() { return fetch("api/v2/app/buildInfo", { method: "GET", cache: "no-store" @@ -80,7 +80,7 @@ window.qBittorrent.Cache ??= (() => { // onFailure: () => {}, // onSuccess: () => {} // } - async init(obj = {}) { + init(obj = {}) { return fetch("api/v2/app/preferences", { method: "GET", cache: "no-store" @@ -153,7 +153,7 @@ window.qBittorrent.Cache ??= (() => { class QbtVersionCache { #m_store = ""; - async init() { + init() { return fetch("api/v2/app/version", { method: "GET", cache: "no-store" diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index b106e72b8..726fbed29 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -108,7 +108,7 @@ inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue }) }) - .then(async (response) => { + .then((response) => { if (!response.ok) return; From fdd17159eb5cd18634ae5b62d3448635fdba382f Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 20 Apr 2025 17:46:12 +0800 Subject: [PATCH 09/21] WebUI: remove unused variable --- src/webui/www/private/scripts/dynamicTable.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index cd0147067..bf019e1d2 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -2858,7 +2858,6 @@ window.qBittorrent.DynamicTable ??= (() => { // progress this.columns["progress"].updateTd = function(td, row) { - const id = row.rowId; const value = Number(this.getRowValue(row)); const progressBar = td.firstElementChild; From 33aaa867b5ef82519e90c1bb4daaea4c8f0d2006 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sun, 27 Apr 2025 16:21:20 +0300 Subject: [PATCH 10/21] Drop support of Qt 6.5 PR #22599. --- .github/workflows/ci_ubuntu.yaml | 3 ++- .github/workflows/coverity-scan.yaml | 2 +- CMakeLists.txt | 2 +- INSTALL | 2 +- cmake/Modules/CommonConfig.cmake | 2 +- src/app/application.cpp | 2 -- src/base/bittorrent/sessionimpl.cpp | 4 ---- src/base/search/searchdownloadhandler.cpp | 2 +- src/base/search/searchhandler.cpp | 2 +- src/base/search/searchpluginmanager.cpp | 2 +- src/base/utils/foreignapps.cpp | 2 +- src/gui/utils.cpp | 2 -- test/testutilsversion.cpp | 8 -------- 13 files changed, 10 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 704ab0630..807eef19f 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -21,7 +21,7 @@ jobs: matrix: libt_version: ["2.0.11", "1.2.20"] qbt_gui: ["GUI=ON", "GUI=OFF"] - qt_version: ["6.5.2"] + qt_version: ["6.6.3"] env: boost_path: "${{ github.workspace }}/../boost" @@ -162,6 +162,7 @@ jobs: - name: Package AppImage run: | + rm -f "${{ runner.workspace }}/Qt/${{ matrix.qt_version }}/gcc_64/plugins/sqldrivers/libqsqlmimer.so" ./linuxdeploy-x86_64.AppImage --appdir qbittorrent --plugin qt rm qbittorrent/apprun-hooks/* cp .github/workflows/helper/appimage/export_vars.sh qbittorrent/apprun-hooks/export_vars.sh diff --git a/.github/workflows/coverity-scan.yaml b/.github/workflows/coverity-scan.yaml index ce970c773..22c5a7082 100644 --- a/.github/workflows/coverity-scan.yaml +++ b/.github/workflows/coverity-scan.yaml @@ -16,7 +16,7 @@ jobs: matrix: libt_version: ["2.0.11"] qbt_gui: ["GUI=ON"] - qt_version: ["6.5.2"] + qt_version: ["6.6.3"] env: boost_path: "${{ github.workspace }}/../boost" diff --git a/CMakeLists.txt b/CMakeLists.txt index 86ede6b3c..97ecb3684 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(qBittorrent # version requirements - older versions may work, but you are on your own set(minBoostVersion 1.76) -set(minQt6Version 6.5.0) +set(minQt6Version 6.6.0) set(minOpenSSLVersion 3.0.2) set(minLibtorrent1Version 1.2.19) set(minLibtorrentVersion 2.0.10) diff --git a/INSTALL b/INSTALL index ec3ff78ea..b17e323fb 100644 --- a/INSTALL +++ b/INSTALL @@ -11,7 +11,7 @@ qBittorrent - A BitTorrent client in C++ / Qt - OpenSSL >= 3.0.2 - - Qt 6.5.0 - 6.x + - Qt 6.6.0 - 6.x - zlib >= 1.2.11 diff --git a/cmake/Modules/CommonConfig.cmake b/cmake/Modules/CommonConfig.cmake index b57dc4bcf..85535313a 100644 --- a/cmake/Modules/CommonConfig.cmake +++ b/cmake/Modules/CommonConfig.cmake @@ -20,7 +20,7 @@ target_compile_features(qbt_common_cfg INTERFACE ) target_compile_definitions(qbt_common_cfg INTERFACE - QT_DISABLE_DEPRECATED_UP_TO=0x060500 + QT_DISABLE_DEPRECATED_UP_TO=0x060600 QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_BYTEARRAY diff --git a/src/app/application.cpp b/src/app/application.cpp index 90e785e1a..a6666c57e 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -674,9 +674,7 @@ void Application::runExternalProgram(const QString &programTemplate, const BitTo QProcess proc; proc.setProgram(command); proc.setArguments(args); -#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); -#endif if (proc.startDetached()) { diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 64d274f19..e88b7cd5c 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1642,11 +1642,7 @@ void SessionImpl::endStartup(ResumeSessionContext *context) auto wakeupCheckTimer = new QTimer(this); connect(wakeupCheckTimer, &QTimer::timeout, this, [this] { -#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) const bool hasSystemSlept = m_wakeupCheckTimestamp.durationElapsed() > 100s; -#else - const bool hasSystemSlept = m_wakeupCheckTimestamp.elapsed() > std::chrono::milliseconds(100s).count(); -#endif if (hasSystemSlept) { LogMsg(tr("System wake-up event detected. Re-announcing to all the trackers...")); diff --git a/src/base/search/searchdownloadhandler.cpp b/src/base/search/searchdownloadhandler.cpp index 34289bf8c..c2dca0790 100644 --- a/src/base/search/searchdownloadhandler.cpp +++ b/src/base/search/searchdownloadhandler.cpp @@ -42,7 +42,7 @@ SearchDownloadHandler::SearchDownloadHandler(const QString &pluginName, const QS , m_downloadProcess {new QProcess(this)} { m_downloadProcess->setProcessEnvironment(m_manager->proxyEnvironment()); -#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) +#ifdef Q_OS_UNIX m_downloadProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); #endif connect(m_downloadProcess, qOverload(&QProcess::finished) diff --git a/src/base/search/searchhandler.cpp b/src/base/search/searchhandler.cpp index 114ddce5f..f847d187a 100644 --- a/src/base/search/searchhandler.cpp +++ b/src/base/search/searchhandler.cpp @@ -72,7 +72,7 @@ SearchHandler::SearchHandler(const QString &pattern, const QString &category, co // Load environment variables (proxy) m_searchProcess->setProcessEnvironment(m_manager->proxyEnvironment()); m_searchProcess->setProgram(Utils::ForeignApps::pythonInfo().executableName); -#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) +#ifdef Q_OS_UNIX m_searchProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); #endif diff --git a/src/base/search/searchpluginmanager.cpp b/src/base/search/searchpluginmanager.cpp index c79ba5d60..5caa611bf 100644 --- a/src/base/search/searchpluginmanager.cpp +++ b/src/base/search/searchpluginmanager.cpp @@ -546,7 +546,7 @@ void SearchPluginManager::update() { QProcess nova; nova.setProcessEnvironment(proxyEnvironment()); -#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) +#ifdef Q_OS_UNIX nova.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); #endif diff --git a/src/base/utils/foreignapps.cpp b/src/base/utils/foreignapps.cpp index 038d5128f..d4e58c1a8 100644 --- a/src/base/utils/foreignapps.cpp +++ b/src/base/utils/foreignapps.cpp @@ -57,7 +57,7 @@ namespace info = {}; QProcess proc; -#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) +#ifdef Q_OS_UNIX proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); #endif proc.start(exeName, {u"--version"_s}, QIODevice::ReadOnly); diff --git a/src/gui/utils.cpp b/src/gui/utils.cpp index ac5d922dc..e987d75c0 100644 --- a/src/gui/utils.cpp +++ b/src/gui/utils.cpp @@ -176,9 +176,7 @@ void Utils::Gui::openFolderSelect(const Path &path) const int lineMaxLength = 64; QProcess proc; -#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); -#endif proc.start(u"xdg-mime"_s, {u"query"_s, u"default"_s, u"inode/directory"_s}); proc.waitForFinished(); const auto output = QString::fromLocal8Bit(proc.readLine(lineMaxLength).simplified()); diff --git a/test/testutilsversion.cpp b/test/testutilsversion.cpp index 733fadac8..63d8360dd 100644 --- a/test/testutilsversion.cpp +++ b/test/testutilsversion.cpp @@ -80,9 +80,7 @@ private slots: { const Utils::Version<1> version1 {1}; QCOMPARE(version1[0], 1); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) QVERIFY_THROWS_EXCEPTION(std::out_of_range, version1[1]); -#endif QCOMPARE(version1.majorNumber(), 1); // should not compile: // version1.minorNumber(); @@ -92,9 +90,7 @@ private slots: const Utils::Version<2, 1> version2 {2}; QCOMPARE(version2[0], 2); QCOMPARE(version2[1], 0); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) QVERIFY_THROWS_EXCEPTION(std::out_of_range, version2[2]); -#endif QCOMPARE(version2.majorNumber(), 2); QCOMPARE(version2.minorNumber(), 0); // should not compile: @@ -105,9 +101,7 @@ private slots: QCOMPARE(version3[0], 3); QCOMPARE(version3[1], 2); QCOMPARE(version3[2], 0); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) QVERIFY_THROWS_EXCEPTION(std::out_of_range, version3[3]); -#endif QCOMPARE(version3.majorNumber(), 3); QCOMPARE(version3.minorNumber(), 2); QCOMPARE(version3.revisionNumber(), 0); @@ -119,9 +113,7 @@ private slots: QCOMPARE(version4[1], 11); QCOMPARE(version4[2], 12); QCOMPARE(version4[3], 13); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) QVERIFY_THROWS_EXCEPTION(std::out_of_range, version4[4]); -#endif QCOMPARE(version4.majorNumber(), 10); QCOMPARE(version4.minorNumber(), 11); QCOMPARE(version4.revisionNumber(), 12); From 732b2bcbdb80debe1622dfe78dfd5530f2b0d008 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sun, 27 Apr 2025 16:24:07 +0300 Subject: [PATCH 11/21] Provide asynchronous results via QFuture Makes asynchronous logic to look more straightforward. Allows caller to choose blocking or non-blocking way of obtaining asynchronous results via the same interface. PR #22598. --- src/base/bittorrent/filesearcher.cpp | 24 ++-- src/base/bittorrent/filesearcher.h | 21 ++- src/base/bittorrent/sessionimpl.cpp | 87 ++++++------ src/base/bittorrent/sessionimpl.h | 8 +- src/base/bittorrent/torrent.h | 15 +-- src/base/bittorrent/torrentcontenthandler.h | 7 +- src/base/bittorrent/torrentimpl.cpp | 142 +++++--------------- src/base/bittorrent/torrentimpl.h | 19 +-- src/gui/addnewtorrentdialog.cpp | 15 ++- src/gui/properties/peerlistwidget.cpp | 5 +- src/gui/properties/propertieswidget.cpp | 16 +-- src/gui/torrentcontentmodel.cpp | 6 +- src/gui/trackerlist/trackerlistmodel.cpp | 5 +- src/webui/api/synccontroller.cpp | 5 +- src/webui/api/torrentscontroller.cpp | 13 +- 15 files changed, 165 insertions(+), 223 deletions(-) diff --git a/src/base/bittorrent/filesearcher.cpp b/src/base/bittorrent/filesearcher.cpp index 2fcd31f8f..9b1a1f9cc 100644 --- a/src/base/bittorrent/filesearcher.cpp +++ b/src/base/bittorrent/filesearcher.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2020 Vladimir Golovnev + * Copyright (C) 2020-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,13 +27,14 @@ */ #include "filesearcher.h" -#include "base/bittorrent/common.h" -#include "base/bittorrent/infohash.h" -void FileSearcher::search(const BitTorrent::TorrentID &id, const PathList &originalFileNames - , const Path &savePath, const Path &downloadPath, const bool forceAppendExt) +#include + +#include "base/bittorrent/common.h" + +namespace { - const auto findInDir = [](const Path &dirPath, PathList &fileNames, const bool forceAppendExt) -> bool + bool findInDir(const Path &dirPath, PathList &fileNames, const bool forceAppendExt) { bool found = false; for (Path &fileName : fileNames) @@ -58,7 +59,13 @@ void FileSearcher::search(const BitTorrent::TorrentID &id, const PathList &origi } return found; - }; + } +} + +void FileSearcher::search(const PathList &originalFileNames, const Path &savePath + , const Path &downloadPath, const bool forceAppendExt, QPromise promise) +{ + promise.start(); Path usedPath = savePath; PathList adjustedFileNames = originalFileNames; @@ -69,5 +76,6 @@ void FileSearcher::search(const BitTorrent::TorrentID &id, const PathList &origi findInDir(usedPath, adjustedFileNames, forceAppendExt); } - emit searchFinished(id, usedPath, adjustedFileNames); + promise.addResult(FileSearchResult {.savePath = usedPath, .fileNames = adjustedFileNames}); + promise.finish(); } diff --git a/src/base/bittorrent/filesearcher.h b/src/base/bittorrent/filesearcher.h index 04495bd76..cfd7ada73 100644 --- a/src/base/bittorrent/filesearcher.h +++ b/src/base/bittorrent/filesearcher.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2020 Vladimir Golovnev + * Copyright (C) 2020-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,10 +32,13 @@ #include "base/path.h" -namespace BitTorrent +template class QPromise; + +struct FileSearchResult { - class TorrentID; -} + Path savePath; + PathList fileNames; +}; class FileSearcher final : public QObject { @@ -43,12 +46,8 @@ class FileSearcher final : public QObject Q_DISABLE_COPY_MOVE(FileSearcher) public: - FileSearcher() = default; + using QObject::QObject; -public slots: - void search(const BitTorrent::TorrentID &id, const PathList &originalFileNames - , const Path &savePath, const Path &downloadPath, bool forceAppendExt); - -signals: - void searchFinished(const BitTorrent::TorrentID &id, const Path &savePath, const PathList &fileNames); + void search(const PathList &originalFileNames, const Path &savePath + , const Path &downloadPath, bool forceAppendExt, QPromise promise); }; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index e88b7cd5c..d9827b150 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -622,7 +624,6 @@ SessionImpl::SessionImpl(QObject *parent) m_fileSearcher = new FileSearcher; m_fileSearcher->moveToThread(m_ioThread.get()); connect(m_ioThread.get(), &QThread::finished, m_fileSearcher, &QObject::deleteLater); - connect(m_fileSearcher, &FileSearcher::searchFinished, this, &SessionImpl::fileSearchFinished); m_torrentContentRemover = new TorrentContentRemover; m_torrentContentRemover->moveToThread(m_ioThread.get()); @@ -2376,31 +2377,6 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent) } } -void SessionImpl::fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames) -{ - TorrentImpl *torrent = m_torrents.value(id); - if (torrent) - { - torrent->fileSearchFinished(savePath, fileNames); - return; - } - - const auto loadingTorrentsIter = m_loadingTorrents.find(id); - if (loadingTorrentsIter != m_loadingTorrents.end()) - { - LoadTorrentParams ¶ms = loadingTorrentsIter.value(); - lt::add_torrent_params &p = params.ltAddTorrentParams; - - p.save_path = savePath.toString().toStdString(); - const TorrentInfo torrentInfo {*p.ti}; - const auto nativeIndexes = torrentInfo.nativeIndexes(); - for (int i = 0; i < fileNames.size(); ++i) - p.renamed_files[nativeIndexes[i]] = fileNames[i].toString().toStdString(); - - m_nativeSession->async_add_torrent(p); - } -} - void SessionImpl::torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage) { if (errorMessage.isEmpty()) @@ -2828,11 +2804,12 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr lt::add_torrent_params &p = loadTorrentParams.ltAddTorrentParams; p = source.ltAddTorrentParams(); - bool isFindingIncompleteFiles = false; - const bool useAutoTMM = loadTorrentParams.useAutoTMM; const Path actualSavePath = useAutoTMM ? categorySavePath(loadTorrentParams.category) : loadTorrentParams.savePath; + bool needFindIncompleteFiles = false; + PathList filePaths; + if (hasMetadata) { // Torrent that is being added with metadata is considered to be added as stopped @@ -2847,7 +2824,7 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr Q_ASSERT(addTorrentParams.filePaths.isEmpty() || (addTorrentParams.filePaths.size() == torrentInfo.filesCount())); - PathList filePaths = addTorrentParams.filePaths; + filePaths = addTorrentParams.filePaths; if (filePaths.isEmpty()) { filePaths = torrentInfo.filePaths(); @@ -2893,13 +2870,9 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr if (!loadTorrentParams.hasFinishedStatus) { - const Path actualDownloadPath = useAutoTMM - ? categoryDownloadPath(loadTorrentParams.category) : loadTorrentParams.downloadPath; - findIncompleteFiles(torrentInfo, actualSavePath, actualDownloadPath, filePaths); - isFindingIncompleteFiles = true; + needFindIncompleteFiles = true; } - - if (!isFindingIncompleteFiles) + else { for (int index = 0; index < filePaths.size(); ++index) p.renamed_files[nativeIndexes[index]] = filePaths.at(index).toString().toStdString(); @@ -2998,23 +2971,49 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr m_loadingTorrents.insert(id, loadTorrentParams); if (infoHash.isHybrid()) m_hybridTorrentsByAltID.insert(altID, nullptr); - if (!isFindingIncompleteFiles) + + if (needFindIncompleteFiles) + { + const Path actualDownloadPath = useAutoTMM + ? categoryDownloadPath(loadTorrentParams.category) : loadTorrentParams.downloadPath; + findIncompleteFiles(actualSavePath, actualDownloadPath, filePaths).then(this + , [this, id](const FileSearchResult &result) + { + const auto loadingTorrentsIter = m_loadingTorrents.find(id); + Q_ASSERT(loadingTorrentsIter != m_loadingTorrents.end()); + if (loadingTorrentsIter == m_loadingTorrents.end()) [[unlikely]] + return; + + LoadTorrentParams ¶ms = loadingTorrentsIter.value(); + lt::add_torrent_params &p = params.ltAddTorrentParams; + + p.save_path = result.savePath.toString().toStdString(); + const TorrentInfo torrentInfo {*p.ti}; + const auto nativeIndexes = torrentInfo.nativeIndexes(); + for (int i = 0; i < result.fileNames.size(); ++i) + p.renamed_files[nativeIndexes[i]] = result.fileNames[i].toString().toStdString(); + + m_nativeSession->async_add_torrent(p); + }); + } + else + { m_nativeSession->async_add_torrent(p); + } return true; } -void SessionImpl::findIncompleteFiles(const TorrentInfo &torrentInfo, const Path &savePath - , const Path &downloadPath, const PathList &filePaths) const +QFuture SessionImpl::findIncompleteFiles(const Path &savePath, const Path &downloadPath, const PathList &filePaths) const { - Q_ASSERT(filePaths.isEmpty() || (filePaths.size() == torrentInfo.filesCount())); - - const auto searchId = TorrentID::fromInfoHash(torrentInfo.infoHash()); - const PathList originalFileNames = (filePaths.isEmpty() ? torrentInfo.filePaths() : filePaths); - QMetaObject::invokeMethod(m_fileSearcher, [=, this] + QPromise promise; + QFuture future = promise.future(); + QMetaObject::invokeMethod(m_fileSearcher, [=, this, promise = std::move(promise)]() mutable { - m_fileSearcher->search(searchId, originalFileNames, savePath, downloadPath, isAppendExtensionEnabled()); + m_fileSearcher->search(filePaths, savePath, downloadPath, isAppendExtensionEnabled(), std::move(promise)); }); + + return future; } void SessionImpl::enablePortMapping() diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 1ad2108ff..e878cf4a6 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -61,12 +61,16 @@ class QString; class QTimer; class QUrl; +template class QFuture; + class BandwidthScheduler; class FileSearcher; class FilterParserThread; class FreeDiskSpaceChecker; class NativeSessionExtension; +struct FileSearchResult; + namespace BitTorrent { enum class MoveStorageMode; @@ -478,8 +482,7 @@ namespace BitTorrent bool addMoveTorrentStorageJob(TorrentImpl *torrent, const Path &newPath, MoveStorageMode mode, MoveStorageContext context); - void findIncompleteFiles(const TorrentInfo &torrentInfo, const Path &savePath - , const Path &downloadPath, const PathList &filePaths = {}) const; + QFuture findIncompleteFiles(const Path &savePath, const Path &downloadPath, const PathList &filePaths = {}) const; void enablePortMapping(); void disablePortMapping(); @@ -514,7 +517,6 @@ namespace BitTorrent void generateResumeData(); void handleIPFilterParsed(int ruleCount); void handleIPFilterError(); - void fileSearchFinished(const TorrentID &id, const Path &savePath, const PathList &fileNames); void torrentContentRemovingFinished(const QString &torrentName, const QString &errorMessage); private: diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index d2eefbabf..fc817b86c 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2024 Vladimir Golovnev + * Copyright (C) 2015-2025 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -45,6 +45,8 @@ class QByteArray; class QDateTime; class QUrl; +template class QFuture; + namespace BitTorrent { enum class DownloadPriority; @@ -275,10 +277,7 @@ namespace BitTorrent virtual bool isDHTDisabled() const = 0; virtual bool isPEXDisabled() const = 0; virtual bool isLSDDisabled() const = 0; - virtual QList peers() const = 0; virtual QBitArray pieces() const = 0; - virtual QBitArray downloadingPieces() const = 0; - virtual QList pieceAvailability() const = 0; virtual qreal distributedCopies() const = 0; virtual qreal maxRatio() const = 0; virtual int maxSeedingTime() const = 0; @@ -325,10 +324,10 @@ namespace BitTorrent virtual nonstd::expected exportToBuffer() const = 0; virtual nonstd::expected exportToFile(const Path &path) const = 0; - virtual void fetchPeerInfo(std::function)> resultHandler) const = 0; - virtual void fetchURLSeeds(std::function)> resultHandler) const = 0; - virtual void fetchPieceAvailability(std::function)> resultHandler) const = 0; - virtual void fetchDownloadingPieces(std::function resultHandler) const = 0; + virtual QFuture> fetchPeerInfo() const = 0; + virtual QFuture> fetchURLSeeds() const = 0; + virtual QFuture> fetchPieceAvailability() const = 0; + virtual QFuture fetchDownloadingPieces() const = 0; TorrentID id() const; bool isRunning() const; diff --git a/src/base/bittorrent/torrentcontenthandler.h b/src/base/bittorrent/torrentcontenthandler.h index 2e3702d2c..350db753e 100644 --- a/src/base/bittorrent/torrentcontenthandler.h +++ b/src/base/bittorrent/torrentcontenthandler.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2022-2023 Vladimir Golovnev + * Copyright (C) 2022-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,6 +34,8 @@ #include "abstractfilestorage.h" #include "downloadpriority.h" +template class QFuture; + namespace BitTorrent { class TorrentContentHandler : public QObject, public AbstractFileStorage @@ -52,8 +54,7 @@ namespace BitTorrent * This is not the same as torrrent availability, it is just a fraction of pieces * that can be downloaded right now. It varies between 0 to 1. */ - virtual QList availableFileFractions() const = 0; - virtual void fetchAvailableFileFractions(std::function)> resultHandler) const = 0; + virtual QFuture> fetchAvailableFileFractions() const = 0; virtual void prioritizeFiles(const QList &priorities) = 0; virtual void flushCache() const = 0; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 45cc7f3bf..a670db151 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2024 Vladimir Golovnev + * Copyright (C) 2015-2025 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -51,7 +51,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -67,6 +69,7 @@ #include "common.h" #include "downloadpriority.h" #include "extensiondata.h" +#include "filesearcher.h" #include "loadtorrentparams.h" #include "ltqbitarray.h" #include "lttypecast.h" @@ -1465,48 +1468,11 @@ bool TorrentImpl::isLSDDisabled() const return static_cast(m_nativeStatus.flags & lt::torrent_flags::disable_lsd); } -QList TorrentImpl::peers() const -{ - std::vector nativePeers; - m_nativeHandle.get_peer_info(nativePeers); - - QList peers; - peers.reserve(static_cast(nativePeers.size())); - - for (const lt::peer_info &peer : nativePeers) - peers.append(PeerInfo(peer, pieces())); - - return peers; -} - QBitArray TorrentImpl::pieces() const { return m_pieces; } -QBitArray TorrentImpl::downloadingPieces() const -{ - if (!hasMetadata()) - return {}; - - std::vector queue; - m_nativeHandle.get_download_queue(queue); - - QBitArray result {piecesCount()}; - for (const lt::partial_piece_info &info : queue) - result.setBit(LT::toUnderlyingType(info.piece_index)); - - return result; -} - -QList TorrentImpl::pieceAvailability() const -{ - std::vector avail; - m_nativeHandle.piece_availability(avail); - - return {avail.cbegin(), avail.cend()}; -} - qreal TorrentImpl::distributedCopies() const { return m_nativeStatus.distributed_copies; @@ -1751,12 +1717,6 @@ void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) m_nativeHandle.prioritize_pieces(piecePriorities); } -void TorrentImpl::fileSearchFinished(const Path &savePath, const PathList &fileNames) -{ - if (m_maintenanceJob == MaintenanceJob::HandleMetadata) - endReceivedMetadataHandling(savePath, fileNames); -} - TrackerEntryStatus TorrentImpl::updateTrackerEntryStatus(const lt::announce_entry &announceEntry, const QHash> &updateInfo) { const auto it = std::find_if(m_trackerEntryStatuses.begin(), m_trackerEntryStatuses.end() @@ -2150,7 +2110,7 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p) // URL seed list have been changed by libtorrent for some reason, so we need to update cached one. // Unfortunately, URL seed list containing in "resume data" is generated according to different rules // than the list we usually cache, so we have to request it from the appropriate source. - fetchURLSeeds([this](const QList &urlSeeds) { m_urlSeeds = urlSeeds; }); + fetchURLSeeds().then(this, [this](const QList &urlSeeds) { m_urlSeeds = urlSeeds; }); } if ((m_maintenanceJob == MaintenanceJob::HandleMetadata) && p->params.ti) @@ -2197,7 +2157,12 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p) filePaths[i] = Path(it->second); } - m_session->findIncompleteFiles(metadata, savePath(), downloadPath(), filePaths); + m_session->findIncompleteFiles(savePath(), downloadPath(), filePaths).then(this + , [this](const FileSearchResult &result) + { + if (m_maintenanceJob == MaintenanceJob::HandleMetadata) + endReceivedMetadataHandling(result.savePath, result.fileNames); + }); } else { @@ -2930,9 +2895,9 @@ nonstd::expected TorrentImpl::exportToFile(const Path &path) cons return {}; } -void TorrentImpl::fetchPeerInfo(std::function)> resultHandler) const +QFuture> TorrentImpl::fetchPeerInfo() const { - invokeAsync([nativeHandle = m_nativeHandle, allPieces = pieces()]() -> QList + return invokeAsync([nativeHandle = m_nativeHandle, allPieces = pieces()]() -> QList { try { @@ -2947,13 +2912,12 @@ void TorrentImpl::fetchPeerInfo(std::function)> resultHand catch (const std::exception &) {} return {}; - } - , std::move(resultHandler)); + }); } -void TorrentImpl::fetchURLSeeds(std::function)> resultHandler) const +QFuture> TorrentImpl::fetchURLSeeds() const { - invokeAsync([nativeHandle = m_nativeHandle]() -> QList + return invokeAsync([nativeHandle = m_nativeHandle]() -> QList { try { @@ -2967,13 +2931,12 @@ void TorrentImpl::fetchURLSeeds(std::function)> resultHandler) catch (const std::exception &) {} return {}; - } - , std::move(resultHandler)); + }); } -void TorrentImpl::fetchPieceAvailability(std::function)> resultHandler) const +QFuture> TorrentImpl::fetchPieceAvailability() const { - invokeAsync([nativeHandle = m_nativeHandle]() -> QList + return invokeAsync([nativeHandle = m_nativeHandle]() -> QList { try { @@ -2984,13 +2947,12 @@ void TorrentImpl::fetchPieceAvailability(std::function)> result catch (const std::exception &) {} return {}; - } - , std::move(resultHandler)); + }); } -void TorrentImpl::fetchDownloadingPieces(std::function resultHandler) const +QFuture TorrentImpl::fetchDownloadingPieces() const { - invokeAsync([nativeHandle = m_nativeHandle, torrentInfo = m_torrentInfo]() -> QBitArray + return invokeAsync([nativeHandle = m_nativeHandle, torrentInfo = m_torrentInfo]() -> QBitArray { try { @@ -3009,13 +2971,12 @@ void TorrentImpl::fetchDownloadingPieces(std::function resultH catch (const std::exception &) {} return {}; - } - , std::move(resultHandler)); + }); } -void TorrentImpl::fetchAvailableFileFractions(std::function)> resultHandler) const +QFuture> TorrentImpl::fetchAvailableFileFractions() const { - invokeAsync([nativeHandle = m_nativeHandle, torrentInfo = m_torrentInfo]() -> QList + return invokeAsync([nativeHandle = m_nativeHandle, torrentInfo = m_torrentInfo]() -> QList { if (!torrentInfo.isValid() || (torrentInfo.filesCount() <= 0)) return {}; @@ -3049,8 +3010,7 @@ void TorrentImpl::fetchAvailableFileFractions(std::function)> catch (const std::exception &) {} return {}; - } - , std::move(resultHandler)); + }); } void TorrentImpl::prioritizeFiles(const QList &priorities) @@ -3090,47 +3050,17 @@ void TorrentImpl::prioritizeFiles(const QList &priorities) manageActualFilePaths(); } -QList TorrentImpl::availableFileFractions() const +template +QFuture> TorrentImpl::invokeAsync(Func &&func) const { - Q_ASSERT(hasMetadata()); - - const int filesCount = this->filesCount(); - if (filesCount <= 0) return {}; - - const QList piecesAvailability = pieceAvailability(); - // libtorrent returns empty array for seeding only torrents - if (piecesAvailability.empty()) return QList(filesCount, -1); - - QList res; - res.reserve(filesCount); - for (int i = 0; i < filesCount; ++i) + QPromise> promise; + const auto future = promise.future(); + m_session->invokeAsync([func = std::forward(func), promise = std::move(promise)]() mutable { - const TorrentInfo::PieceRange filePieces = m_torrentInfo.filePieces(i); - - int availablePieces = 0; - for (const int piece : filePieces) - availablePieces += (piecesAvailability[piece] > 0) ? 1 : 0; - - const qreal availability = filePieces.isEmpty() - ? 1 // the file has no pieces, so it is available by default - : static_cast(availablePieces) / filePieces.size(); - res.push_back(availability); - } - return res; -} - -template -void TorrentImpl::invokeAsync(Func func, Callback resultHandler) const -{ - m_session->invokeAsync([session = m_session - , func = std::move(func) - , resultHandler = std::move(resultHandler) - , thisTorrent = QPointer(this)]() mutable - { - session->invoke([result = func(), thisTorrent, resultHandler = std::move(resultHandler)] - { - if (thisTorrent) - resultHandler(result); - }); + promise.start(); + promise.addResult(func()); + promise.finish(); }); + + return future; } diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index 5c54b2d00..87137cd73 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -203,10 +203,7 @@ namespace BitTorrent bool isDHTDisabled() const override; bool isPEXDisabled() const override; bool isLSDDisabled() const override; - QList peers() const override; QBitArray pieces() const override; - QBitArray downloadingPieces() const override; - QList pieceAvailability() const override; qreal distributedCopies() const override; qreal maxRatio() const override; int maxSeedingTime() const override; @@ -220,7 +217,6 @@ namespace BitTorrent int connectionsCount() const override; int connectionsLimit() const override; qlonglong nextAnnounce() const override; - QList availableFileFractions() const override; void setName(const QString &name) override; void setSequentialDownload(bool enable) override; @@ -258,11 +254,11 @@ namespace BitTorrent nonstd::expected exportToBuffer() const override; nonstd::expected exportToFile(const Path &path) const override; - void fetchPeerInfo(std::function)> resultHandler) const override; - void fetchURLSeeds(std::function)> resultHandler) const override; - void fetchPieceAvailability(std::function)> resultHandler) const override; - void fetchDownloadingPieces(std::function resultHandler) const override; - void fetchAvailableFileFractions(std::function)> resultHandler) const override; + QFuture> fetchPeerInfo() const override; + QFuture> fetchURLSeeds() const override; + QFuture> fetchPieceAvailability() const override; + QFuture fetchDownloadingPieces() const override; + QFuture> fetchAvailableFileFractions() const override; bool needSaveResumeData() const; @@ -278,7 +274,6 @@ namespace BitTorrent void requestResumeData(lt::resume_data_flags_t flags = {}); void deferredRequestResumeData(); void handleMoveStorageJobFinished(const Path &path, MoveStorageContext context, bool hasOutstandingJob); - void fileSearchFinished(const Path &savePath, const PathList &fileNames); TrackerEntryStatus updateTrackerEntryStatus(const lt::announce_entry &announceEntry, const QHash> &updateInfo); void resetTrackerEntryStatuses(); @@ -326,8 +321,8 @@ namespace BitTorrent nonstd::expected exportTorrent() const; - template - void invokeAsync(Func func, Callback resultHandler) const; + template + QFuture> invokeAsync(Func &&func) const; SessionImpl *const m_session = nullptr; lt::session *m_nativeSession = nullptr; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 321e1528b..8954a1c4d 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -32,12 +32,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -242,14 +244,13 @@ public: return QList(filesCount(), 0); } - QList availableFileFractions() const override + QFuture> fetchAvailableFileFractions() const override { - return QList(filesCount(), 0); - } - - void fetchAvailableFileFractions(std::function)> resultHandler) const override - { - resultHandler(availableFileFractions()); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + return QtFuture::makeReadyValueFuture(QList(filesCount(), 0)); +#else + return QtFuture::makeReadyFuture(QList(filesCount(), 0)); +#endif } void prioritizeFiles(const QList &priorities) override diff --git a/src/gui/properties/peerlistwidget.cpp b/src/gui/properties/peerlistwidget.cpp index 8546d7143..a6c44d106 100644 --- a/src/gui/properties/peerlistwidget.cpp +++ b/src/gui/properties/peerlistwidget.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2023 Vladimir Golovnev + * Copyright (C) 2023-2025 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -406,7 +407,7 @@ void PeerListWidget::loadPeers(const BitTorrent::Torrent *torrent) return; using TorrentPtr = QPointer; - torrent->fetchPeerInfo([this, torrent = TorrentPtr(torrent)](const QList &peers) + torrent->fetchPeerInfo().then(this, [this, torrent = TorrentPtr(torrent)](const QList &peers) { if (torrent != m_properties->getCurrentTorrent()) return; diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index ad9673272..303043a80 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2022-2024 Vladimir Golovnev + * Copyright (C) 2022-2025 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -471,15 +472,15 @@ void PropertiesWidget::loadDynamicData() if (m_torrent->hasMetadata()) { - using TorrentPtr = QPointer; - m_ui->labelTotalPiecesVal->setText(tr("%1 x %2 (have %3)", "(torrent pieces) eg 152 x 4MB (have 25)").arg(m_torrent->piecesCount()).arg(Utils::Misc::friendlyUnit(m_torrent->pieceLength())).arg(m_torrent->piecesHave())); if (!m_torrent->isFinished() && !m_torrent->isStopped() && !m_torrent->isQueued() && !m_torrent->isChecking()) { // Pieces availability showPiecesAvailability(true); - m_torrent->fetchPieceAvailability([this, torrent = TorrentPtr(m_torrent)](const QList &pieceAvailability) + + using TorrentPtr = QPointer; + m_torrent->fetchPieceAvailability().then(this, [this, torrent = TorrentPtr(m_torrent)](const QList &pieceAvailability) { if (torrent == m_torrent) m_piecesAvailability->setAvailability(pieceAvailability); @@ -496,10 +497,9 @@ void PropertiesWidget::loadDynamicData() qreal progress = m_torrent->progress() * 100.; m_ui->labelProgressVal->setText(Utils::String::fromDouble(progress, 1) + u'%'); - m_torrent->fetchDownloadingPieces([this, torrent = TorrentPtr(m_torrent)](const QBitArray &downloadingPieces) + m_torrent->fetchDownloadingPieces().then(this, [this](const QBitArray &downloadingPieces) { - if (torrent == m_torrent) - m_downloadedPieces->setProgress(m_torrent->pieces(), downloadingPieces); + m_downloadedPieces->setProgress(m_torrent->pieces(), downloadingPieces); }); } else @@ -525,7 +525,7 @@ void PropertiesWidget::loadUrlSeeds() return; using TorrentPtr = QPointer; - m_torrent->fetchURLSeeds([this, torrent = TorrentPtr(m_torrent)](const QList &urlSeeds) + m_torrent->fetchURLSeeds().then(this, [this, torrent = TorrentPtr(m_torrent)](const QList &urlSeeds) { if (torrent != m_torrent) return; diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index e75fc1856..32e44c16f 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2022-2024 Vladimir Golovnev + * Copyright (C) 2022-2025 Vladimir Golovnev * Copyright (C) 2006-2012 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -219,7 +220,8 @@ void TorrentContentModel::updateFilesAvailability() Q_ASSERT(m_contentHandler && m_contentHandler->hasMetadata()); using HandlerPtr = QPointer; - m_contentHandler->fetchAvailableFileFractions([this, handler = HandlerPtr(m_contentHandler)](const QList &availableFileFractions) + m_contentHandler->fetchAvailableFileFractions().then(this + , [this, handler = HandlerPtr(m_contentHandler)](const QList &availableFileFractions) { if (handler != m_contentHandler) return; diff --git a/src/gui/trackerlist/trackerlistmodel.cpp b/src/gui/trackerlist/trackerlistmodel.cpp index 78465488c..b13b067b6 100644 --- a/src/gui/trackerlist/trackerlistmodel.cpp +++ b/src/gui/trackerlist/trackerlistmodel.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2023-2024 Vladimir Golovnev + * Copyright (C) 2023-2025 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -309,7 +310,7 @@ void TrackerListModel::populate() m_items->emplace_back(std::make_shared(u"** [LSD] **", privateTorrentMessage)); using TorrentPtr = QPointer; - m_torrent->fetchPeerInfo([this, torrent = TorrentPtr(m_torrent)](const QList &peers) + m_torrent->fetchPeerInfo().then(this, [this, torrent = TorrentPtr(m_torrent)](const QList &peers) { if (torrent != m_torrent) return; diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index 222b066aa..574a833ed 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2018-2024 Vladimir Golovnev + * Copyright (C) 2018-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,6 +28,7 @@ #include "synccontroller.h" +#include #include #include #include @@ -745,7 +746,7 @@ void SyncController::torrentPeersAction() QVariantMap data; QVariantHash peers; - const QList peersList = torrent->peers(); + const QList peersList = torrent->fetchPeerInfo().takeResult(); bool resolvePeerCountries = Preferences::instance()->resolvePeerCountries(); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 6fd5f6fbf..c877fd5db 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2018-2023 Vladimir Golovnev + * Copyright (C) 2018-2025 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -180,9 +181,11 @@ namespace QJsonArray getStickyTrackers(const BitTorrent::Torrent *const torrent) { int seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, leechesDHT = 0, leechesPeX = 0, leechesLSD = 0; - for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers())) + const QList peersList = torrent->fetchPeerInfo().takeResult(); + for (const BitTorrent::PeerInfo &peer : peersList) { - if (peer.isConnecting()) continue; + if (peer.isConnecting()) + continue; if (peer.isSeed()) { @@ -727,7 +730,7 @@ void TorrentsController::filesAction() { const QList priorities = torrent->filePriorities(); const QList fp = torrent->filesProgress(); - const QList fileAvailability = torrent->availableFileFractions(); + const QList fileAvailability = torrent->fetchAvailableFileFractions().takeResult(); const BitTorrent::TorrentInfo info = torrent->info(); for (const int index : asConst(fileIndexes)) { @@ -796,7 +799,7 @@ void TorrentsController::pieceStatesAction() for (int i = 0; i < states.size(); ++i) pieceStates.append(static_cast(states[i]) * 2); - const QBitArray dlstates = torrent->downloadingPieces(); + const QBitArray dlstates = torrent->fetchDownloadingPieces().takeResult(); for (int i = 0; i < states.size(); ++i) { if (dlstates[i]) From c2f2a385824c6b118c364f1b152f5f5839fb11f1 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Mon, 28 Apr 2025 17:26:51 +0300 Subject: [PATCH 12/21] Call `QPromise::start()` early to avoid race condition PR #22617. --- src/base/bittorrent/filesearcher.cpp | 5 +---- src/base/bittorrent/filesearcher.h | 2 +- src/base/bittorrent/sessionimpl.cpp | 4 +++- src/base/bittorrent/torrentimpl.cpp | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/base/bittorrent/filesearcher.cpp b/src/base/bittorrent/filesearcher.cpp index 9b1a1f9cc..e7241b889 100644 --- a/src/base/bittorrent/filesearcher.cpp +++ b/src/base/bittorrent/filesearcher.cpp @@ -63,10 +63,8 @@ namespace } void FileSearcher::search(const PathList &originalFileNames, const Path &savePath - , const Path &downloadPath, const bool forceAppendExt, QPromise promise) + , const Path &downloadPath, const bool forceAppendExt, QPromise &promise) { - promise.start(); - Path usedPath = savePath; PathList adjustedFileNames = originalFileNames; const bool found = findInDir(usedPath, adjustedFileNames, (forceAppendExt && downloadPath.isEmpty())); @@ -77,5 +75,4 @@ void FileSearcher::search(const PathList &originalFileNames, const Path &savePat } promise.addResult(FileSearchResult {.savePath = usedPath, .fileNames = adjustedFileNames}); - promise.finish(); } diff --git a/src/base/bittorrent/filesearcher.h b/src/base/bittorrent/filesearcher.h index cfd7ada73..f225b95dc 100644 --- a/src/base/bittorrent/filesearcher.h +++ b/src/base/bittorrent/filesearcher.h @@ -49,5 +49,5 @@ public: using QObject::QObject; void search(const PathList &originalFileNames, const Path &savePath - , const Path &downloadPath, bool forceAppendExt, QPromise promise); + , const Path &downloadPath, bool forceAppendExt, QPromise &promise); }; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index d9827b150..f3d68cf5f 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -3008,9 +3008,11 @@ QFuture SessionImpl::findIncompleteFiles(const Path &savePath, { QPromise promise; QFuture future = promise.future(); + promise.start(); QMetaObject::invokeMethod(m_fileSearcher, [=, this, promise = std::move(promise)]() mutable { - m_fileSearcher->search(filePaths, savePath, downloadPath, isAppendExtensionEnabled(), std::move(promise)); + m_fileSearcher->search(filePaths, savePath, downloadPath, isAppendExtensionEnabled(), promise); + promise.finish(); }); return future; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index a670db151..f4ae0e0fa 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -3055,9 +3055,9 @@ QFuture> TorrentImpl::invokeAsync(Func &&func) const { QPromise> promise; const auto future = promise.future(); + promise.start(); m_session->invokeAsync([func = std::forward(func), promise = std::move(promise)]() mutable { - promise.start(); promise.addResult(func()); promise.finish(); }); From 0791828b84c150ce11170ea88f848fc77658cd06 Mon Sep 17 00:00:00 2001 From: tehcneko Date: Tue, 29 Apr 2025 20:16:00 +0800 Subject: [PATCH 13/21] WebUI: fix virtual list defects Fixes https://github.com/qbittorrent/qBittorrent/pull/22502#issuecomment-2822201721 and https://github.com/qbittorrent/qBittorrent/pull/22502#issuecomment-2822253388. PR #22597. --- src/webui/www/private/scripts/dynamicTable.js | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 59a52e5c5..3b6cc19de 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -911,6 +911,9 @@ window.qBittorrent.DynamicTable ??= (() => { // set the scrollable height this.table.style.height = `${rows.length * this.rowHeight}px`; + if (this.dynamicTableDiv.offsetHeight === 0) + return; + this.renderedHeight = this.dynamicTableDiv.offsetHeight; // show extra 6 rows at top/bottom to reduce flickering const extraRowCount = 6; // how many rows can be shown in the visible area @@ -947,17 +950,22 @@ window.qBittorrent.DynamicTable ??= (() => { this.updateRow(row, true); // refresh row height based on first row - setTimeout(() => { - if (this.tableBody.firstChild === null) - return; - const tr = this.tableBody.firstChild; - if (this.rowHeight !== tr.offsetHeight) { - this.rowHeight = tr.offsetHeight; - // rerender on row height change - this.rerender(); - } - - }); + const tr = this.tableBody.firstChild; + if (tr !== null) { + const updateRowHeight = () => { + if (tr.offsetHeight === 0) + return; + if (this.rowHeight !== tr.offsetHeight) { + this.rowHeight = tr.offsetHeight; + // rerender on row height change + this.rerender(); + } + }; + if (tr.offsetHeight === 0) + setTimeout(updateRowHeight); + else + updateRowHeight(); + } }, createRowElement: function(row, top = -1) { @@ -2650,8 +2658,18 @@ window.qBittorrent.DynamicTable ??= (() => { this._updateNodeCollapseIcon(node, shouldCollapse); - for (const child of node.children) - this._updateNodeVisibility(child, shouldCollapse); + this._updateNodeChildVisibility(node, shouldCollapse); + }, + + _updateNodeChildVisibility: function(root, shouldHide) { + const stack = [...root.children]; + while (stack.length > 0) { + const node = stack.pop(); + + this._updateNodeVisibility(node, (shouldHide ? shouldHide : this.isCollapsed(node.root.rowId))); + + stack.push(...node.children); + } }, clear: function() { @@ -2914,7 +2932,7 @@ window.qBittorrent.DynamicTable ??= (() => { _filterNodes: function(node, filterTerms, filteredRows) { if (node.isFolder && (!this.useVirtualList || !this.isCollapsed(node.rowId))) { - const childAdded = node.children.reduce((acc, child) => { + const childAdded = node.children.toReversed().reduce((acc, child) => { // we must execute the function before ORing w/ acc or we'll stop checking child nodes after the first successful match return (this._filterNodes(child, filterTerms, filteredRows) || acc); }, false); From 4c91cd9372ea36f9e1e80219b8384a0c01c03d1a Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:32:54 +0200 Subject: [PATCH 14/21] WebUI: Use modern class syntax to create dynamic table classes --- src/webui/www/private/scripts/dynamicTable.js | 780 +++++++++--------- 1 file changed, 370 insertions(+), 410 deletions(-) diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 3b6cc19de..c23606140 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -67,11 +67,8 @@ window.qBittorrent.DynamicTable ??= (() => { let DynamicTableHeaderContextMenuClass = null; let progressColumnWidth = -1; - const DynamicTable = new Class({ - - initialize: () => {}, - - setup: function(dynamicTableDivId, dynamicTableFixedHeaderDivId, contextMenu, useVirtualList = false) { + class DynamicTable { + setup(dynamicTableDivId, dynamicTableFixedHeaderDivId, contextMenu, useVirtualList = false) { this.dynamicTableDivId = dynamicTableDivId; this.dynamicTableFixedHeaderDivId = dynamicTableFixedHeaderDivId; this.dynamicTableDiv = document.getElementById(dynamicTableDivId); @@ -96,9 +93,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.setupHeaderMenu(); this.setupAltRow(); this.setupVirtualList(); - }, + } - setupVirtualList: function() { + setupVirtualList() { if (!this.useVirtualList) return; this.table.style.position = "relative"; @@ -112,9 +109,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.rerender(); }); new ResizeObserver(resizeCallback).observe(this.dynamicTableDiv); - }, + } - setupCommonEvents: function() { + setupCommonEvents() { const tableFixedHeaderDiv = document.getElementById(this.dynamicTableFixedHeaderDivId); const tableElement = tableFixedHeaderDiv.querySelector("table"); @@ -194,9 +191,9 @@ window.qBittorrent.DynamicTable ??= (() => { } } }); - }, + } - setupHeaderEvents: function() { + setupHeaderEvents() { this.currentHeaderAction = ""; this.canResize = false; @@ -372,9 +369,9 @@ window.qBittorrent.DynamicTable ??= (() => { onCancel: onCancel }); } - }, + } - setupDynamicTableHeaderContextMenuClass: function() { + setupDynamicTableHeaderContextMenuClass() { DynamicTableHeaderContextMenuClass ??= class extends window.qBittorrent.ContextMenu.ContextMenu { updateMenuItems() { for (let i = 0; i < this.dynamicTable.columns.length; ++i) { @@ -387,16 +384,16 @@ window.qBittorrent.DynamicTable ??= (() => { } } }; - }, + } - showColumn: function(columnName, show) { + showColumn(columnName, show) { this.columns[columnName].visible = show ? "1" : "0"; LocalPreferences.set(`column_${columnName}_visible_${this.dynamicTableDivId}`, show ? "1" : "0"); this.updateColumn(columnName); this.columns[columnName].onVisibilityChange?.(columnName); - }, + } - _calculateColumnBodyWidth: function(column) { + _calculateColumnBodyWidth(column) { const columnIndex = this.getColumnPos(column.name); const bodyColumn = document.getElementById(this.dynamicTableDivId).querySelectorAll("tr>th")[columnIndex]; const canvas = document.createElement("canvas"); @@ -418,9 +415,9 @@ window.qBittorrent.DynamicTable ??= (() => { // slight buffer to prevent clipping return longestTd.width + 10; - }, + } - _setColumnWidth: function(columnName, width) { + _setColumnWidth(columnName, width) { const column = this.columns[columnName]; column.width = width; @@ -433,9 +430,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.rerender(); column.onResize?.(column.name); - }, + } - autoResizeColumn: function(columnName) { + autoResizeColumn(columnName) { const column = this.columns[columnName]; let width = column.staticWidth ?? 0; @@ -458,13 +455,13 @@ window.qBittorrent.DynamicTable ??= (() => { this._setColumnWidth(column.name, width); this.saveColumnWidth(column.name); - }, + } - saveColumnWidth: function(columnName) { + saveColumnWidth(columnName) { LocalPreferences.set(`column_${columnName}_width_${this.dynamicTableDivId}`, this.columns[columnName].width); - }, + } - setupHeaderMenu: function() { + setupHeaderMenu() { this.setupDynamicTableHeaderContextMenuClass(); const menuId = `${this.dynamicTableDivId}_headerMenu`; @@ -551,11 +548,11 @@ window.qBittorrent.DynamicTable ??= (() => { }); this.headerContextMenu.dynamicTable = this; - }, + } - initColumns: () => {}, + initColumns() {} - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -594,9 +591,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); - }, + } - loadColumnsOrder: function() { + loadColumnsOrder() { const columnsOrder = []; const val = LocalPreferences.get(`columns_order_${this.dynamicTableDivId}`); if ((val === null) || (val === undefined)) @@ -613,9 +610,9 @@ window.qBittorrent.DynamicTable ??= (() => { for (let i = 0; i < this.columns.length; ++i) this.columns[i] = this.columns[columnsOrder[i]]; - }, + } - saveColumnsOrder: function() { + saveColumnsOrder() { let val = ""; for (let i = 0; i < this.columns.length; ++i) { if (i > 0) @@ -623,15 +620,15 @@ window.qBittorrent.DynamicTable ??= (() => { val += this.columns[i].name; } LocalPreferences.set(`columns_order_${this.dynamicTableDivId}`, val); - }, + } - updateTableHeaders: function() { + updateTableHeaders() { this.updateHeader(this.hiddenTableHeader); this.updateHeader(this.fixedTableHeader); this.setSortedColumnIcon(this.sortedColumn, null, (this.reverseSort === "1")); - }, + } - updateHeader: function(header) { + updateHeader(header) { const ths = this.getRowCells(header); for (let i = 0; i < ths.length; ++i) { const th = ths[i]; @@ -644,17 +641,17 @@ window.qBittorrent.DynamicTable ??= (() => { th.classList.toggle("invisible", ((this.columns[i].visible === "0") || this.columns[i].force_hide)); } } - }, + } - getColumnPos: function(columnName) { + getColumnPos(columnName) { for (let i = 0; i < this.columns.length; ++i) { if (this.columns[i].name === columnName) return i; } return -1; - }, + } - updateColumn: function(columnName, updateCellData = false) { + updateColumn(columnName, updateCellData = false) { const column = this.columns[columnName]; const pos = this.getColumnPos(columnName); const ths = this.getRowCells(this.hiddenTableHeader); @@ -669,17 +666,17 @@ window.qBittorrent.DynamicTable ??= (() => { if (updateCellData) column.updateTd(td, this.rows.get(tr.rowId)); } - }, + } - getSortedColumn: function() { + getSortedColumn() { return LocalPreferences.get(`sorted_column_${this.dynamicTableDivId}`); - }, + } /** * @param {string} column name to sort by * @param {string|null} reverse defaults to implementation-specific behavior when not specified. Should only be passed when restoring previous state. */ - setSortedColumn: function(column, reverse = null) { + setSortedColumn(column, reverse = null) { if (column !== this.sortedColumn) { const oldColumn = this.sortedColumn; this.sortedColumn = column; @@ -694,9 +691,9 @@ window.qBittorrent.DynamicTable ??= (() => { LocalPreferences.set(`sorted_column_${this.dynamicTableDivId}`, column); LocalPreferences.set(`reverse_sort_${this.dynamicTableDivId}`, this.reverseSort); this.updateTable(false); - }, + } - setSortedColumnIcon: function(newColumn, oldColumn, isReverse) { + setSortedColumnIcon(newColumn, oldColumn, isReverse) { const getCol = (headerDivId, colName) => { const colElem = document.querySelectorAll(`#${headerDivId} .column_${colName}`); if (colElem.length === 1) @@ -714,48 +711,48 @@ window.qBittorrent.DynamicTable ??= (() => { oldColElem.classList.remove("sorted"); oldColElem.classList.remove("reverse"); } - }, + } - getSelectedRowId: function() { + getSelectedRowId() { if (this.selectedRows.length > 0) return this.selectedRows[0]; return ""; - }, + } - isRowSelected: function(rowId) { + isRowSelected(rowId) { return this.selectedRows.contains(rowId); - }, + } - setupAltRow: function() { + setupAltRow() { const useAltRowColors = (LocalPreferences.get("use_alt_row_colors", "true") === "true"); if (useAltRowColors) document.getElementById(this.dynamicTableDivId).classList.add("altRowColors"); - }, + } - selectAll: function() { + selectAll() { this.deselectAll(); for (const row of this.getFilteredAndSortedRows()) this.selectedRows.push(row.rowId); this.setRowClass(); - }, + } - deselectAll: function() { + deselectAll() { this.selectedRows.empty(); - }, + } - selectRow: function(rowId) { + selectRow(rowId) { this.selectedRows.push(rowId); this.setRowClass(); this.onSelectedRowChanged(); - }, + } - deselectRow: function(rowId) { + deselectRow(rowId) { this.selectedRows.erase(rowId); this.setRowClass(); this.onSelectedRowChanged(); - }, + } - selectRows: function(rowId1, rowId2) { + selectRows(rowId1, rowId2) { this.deselectAll(); if (rowId1 === rowId2) { this.selectRow(rowId1); @@ -774,22 +771,22 @@ window.qBittorrent.DynamicTable ??= (() => { } this.setRowClass(); this.onSelectedRowChanged(); - }, + } - reselectRows: function(rowIds) { + reselectRows(rowIds) { this.deselectAll(); this.selectedRows = rowIds.slice(); this.setRowClass(); - }, + } - setRowClass: function() { + setRowClass() { for (const tr of this.getTrs()) tr.classList.toggle("selected", this.isRowSelected(tr.rowId)); - }, + } - onSelectedRowChanged: () => {}, + onSelectedRowChanged() {} - updateRowData: function(data) { + updateRowData(data) { // ensure rowId is a string const rowId = `${data["rowId"]}`; let row; @@ -811,21 +808,21 @@ window.qBittorrent.DynamicTable ??= (() => { continue; row["full_data"][x] = data[x]; } - }, + } - getTrs: function() { + getTrs() { return this.tableBody.querySelectorAll("tr"); - }, + } - getRowCells: (tr) => { + getRowCells(tr) { return tr.querySelectorAll("td, th"); - }, + } - getRow: function(rowId) { + getRow(rowId) { return this.rows.get(rowId); - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { const filteredRows = []; for (const row of this.getRowValues()) { @@ -842,13 +839,13 @@ window.qBittorrent.DynamicTable ??= (() => { return -res; }); return filteredRows; - }, + } - getTrByRowId: function(rowId) { + getTrByRowId(rowId) { return Array.prototype.find.call(this.getTrs(), (tr => tr.rowId === rowId)); - }, + } - updateTable: function(fullUpdate = false) { + updateTable(fullUpdate = false) { const rows = this.getFilteredAndSortedRows(); for (let i = 0; i < this.selectedRows.length; ++i) { @@ -905,9 +902,9 @@ window.qBittorrent.DynamicTable ??= (() => { while ((rowPos < trs.length) && (trs.length > 0)) trs.pop().destroy(); } - }, + } - rerender: function(rows = this.getFilteredAndSortedRows()) { + rerender(rows = this.getFilteredAndSortedRows()) { // set the scrollable height this.table.style.height = `${rows.length * this.rowHeight}px`; @@ -966,9 +963,9 @@ window.qBittorrent.DynamicTable ??= (() => { else updateRowHeight(); } - }, + } - createRowElement: function(row, top = -1) { + createRowElement(row, top = -1) { const tr = document.createElement("tr"); // set tabindex so element receives keydown events // more info: https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event @@ -986,9 +983,9 @@ window.qBittorrent.DynamicTable ??= (() => { // update context menu this.contextMenu?.addTarget(tr); return tr; - }, + } - updateRowElement: function(tr, rowId, top) { + updateRowElement(tr, rowId, top) { tr.dataset.rowId = rowId; tr.rowId = rowId; @@ -998,9 +995,9 @@ window.qBittorrent.DynamicTable ??= (() => { tr.style.position = "absolute"; tr.style.top = `${top}px`; } - }, + } - updateRow: function(tr, fullUpdate) { + updateRow(tr, fullUpdate) { const row = this.rows.get(tr.rowId); const data = row[fullUpdate ? "full_data" : "data"]; @@ -1015,9 +1012,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns[i].updateTd(tds[i], row); } row["data"] = {}; - }, + } - removeRow: function(rowId) { + removeRow(rowId) { this.selectedRows.erase(rowId); this.rows.delete(rowId); if (this.useVirtualList) { @@ -1027,9 +1024,9 @@ window.qBittorrent.DynamicTable ??= (() => { const tr = this.getTrByRowId(rowId); tr?.destroy(); } - }, + } - clear: function() { + clear() { this.deselectAll(); this.rows.clear(); if (this.useVirtualList) { @@ -1039,29 +1036,29 @@ window.qBittorrent.DynamicTable ??= (() => { for (const tr of this.getTrs()) tr.destroy(); } - }, + } - selectedRowsIds: function() { + selectedRowsIds() { return this.selectedRows.slice(); - }, + } - getRowIds: function() { + getRowIds() { return this.rows.keys(); - }, + } - getRowValues: function() { + getRowValues() { return this.rows.values(); - }, + } - getRowItems: function() { + getRowItems() { return this.rows.entries(); - }, + } - getRowSize: function() { + getRowSize() { return this.rows.size; - }, + } - selectNextRow: function() { + selectNextRow() { const visibleRows = Array.prototype.filter.call(this.getTrs(), (tr => !tr.classList.contains("invisible") && (tr.style.display !== "none"))); const selectedRowId = this.getSelectedRowId(); @@ -1081,9 +1078,9 @@ window.qBittorrent.DynamicTable ??= (() => { const newRow = visibleRows[selectedIndex + 1]; this.selectRow(newRow.getAttribute("data-row-id")); } - }, + } - selectPreviousRow: function() { + selectPreviousRow() { const visibleRows = Array.prototype.filter.call(this.getTrs(), (tr => !tr.classList.contains("invisible") && (tr.style.display !== "none"))); const selectedRowId = this.getSelectedRowId(); @@ -1103,19 +1100,16 @@ window.qBittorrent.DynamicTable ??= (() => { const newRow = visibleRows[selectedIndex - 1]; this.selectRow(newRow.getAttribute("data-row-id")); } - }, - }); - - const TorrentsTable = new Class({ - Extends: DynamicTable, - - setupVirtualList: function() { - this.parent(); + } + } + class TorrentsTable extends DynamicTable { + setupVirtualList() { + super.setupVirtualList(); this.rowHeight = 22; - }, + } - initColumns: function() { + initColumns() { this.newColumn("priority", "", "#", 30, true); this.newColumn("state_icon", "", "QBT_TR(Status Icon)QBT_TR[CONTEXT=TransferListModel]", 30, false); this.newColumn("name", "", "QBT_TR(Name)QBT_TR[CONTEXT=TransferListModel]", 200, true); @@ -1162,9 +1156,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["time_active"].dataProperties.push("seeding_time"); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const getStateIconClasses = (state) => { let stateClass = "stateUnknown"; // normalize states @@ -1583,9 +1577,9 @@ window.qBittorrent.DynamicTable ??= (() => { td.textContent = string; td.title = string; }; - }, + } - applyFilter: (row, filterName, category, tag, tracker, filterTerms) => { + applyFilter(row, filterName, category, tag, tracker, filterTerms) { const state = row["full_data"].state; let inactive = false; @@ -1733,9 +1727,9 @@ window.qBittorrent.DynamicTable ??= (() => { } return true; - }, + } - getFilteredTorrentsNumber: function(filterName, category, tag, tracker) { + getFilteredTorrentsNumber(filterName, category, tag, tracker) { let cnt = 0; for (const row of this.rows.values()) { @@ -1743,9 +1737,9 @@ window.qBittorrent.DynamicTable ??= (() => { ++cnt; } return cnt; - }, + } - getFilteredTorrentsHashes: function(filterName, category, tag, tracker) { + getFilteredTorrentsHashes(filterName, category, tag, tracker) { const rowsHashes = []; const useRegex = document.getElementById("torrentsFilterRegexBox").checked; const filterText = document.getElementById("torrentsFilterInput").value.trim().toLowerCase(); @@ -1765,9 +1759,9 @@ window.qBittorrent.DynamicTable ??= (() => { } return rowsHashes; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { const filteredRows = []; const useRegex = document.getElementById("torrentsFilterRegexBox").checked; @@ -1798,10 +1792,10 @@ window.qBittorrent.DynamicTable ??= (() => { return -res; }); return filteredRows; - }, + } - setupCommonEvents: function() { - this.parent(); + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("dblclick", (e) => { const tr = e.target.closest("tr"); if (!tr) @@ -1830,21 +1824,19 @@ window.qBittorrent.DynamicTable ??= (() => { else stopFN(); }); - }, + } - getCurrentTorrentID: function() { + getCurrentTorrentID() { return this.getSelectedRowId(); - }, + } - onSelectedRowChanged: () => { + onSelectedRowChanged() { updatePropertiesPanel(); } - }); + } - const TorrentPeersTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class TorrentPeersTable extends DynamicTable { + initColumns() { this.newColumn("country", "", "QBT_TR(Country/Region)QBT_TR[CONTEXT=PeerListWidget]", 22, true); this.newColumn("ip", "", "QBT_TR(IP)QBT_TR[CONTEXT=PeerListWidget]", 80, true); this.newColumn("port", "", "QBT_TR(Port)QBT_TR[CONTEXT=PeerListWidget]", 35, true); @@ -1863,10 +1855,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["country"].dataProperties.push("country_code"); this.columns["flags"].dataProperties.push("flags_desc"); this.initColumnsFunctions(); - }, - - initColumnsFunctions: function() { + } + initColumnsFunctions() { // country this.columns["country"].updateTd = function(td, row) { const country = this.getRowValue(row, 0); @@ -1949,12 +1940,10 @@ window.qBittorrent.DynamicTable ??= (() => { }; } - }); + } - const SearchResultsTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class SearchResultsTable extends DynamicTable { + initColumns() { this.newColumn("fileName", "", "QBT_TR(Name)QBT_TR[CONTEXT=SearchResultsTable]", 500, true); this.newColumn("fileSize", "", "QBT_TR(Size)QBT_TR[CONTEXT=SearchResultsTable]", 100, true); this.newColumn("nbSeeders", "", "QBT_TR(Seeders)QBT_TR[CONTEXT=SearchResultsTable]", 100, true); @@ -1964,9 +1953,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("pubDate", "", "QBT_TR(Published On)QBT_TR[CONTEXT=SearchResultsTable]", 200, true); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const displaySize = function(td, row) { const size = window.qBittorrent.Misc.friendlyUnit(this.getRowValue(row), false); td.textContent = size; @@ -1989,9 +1978,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["nbSeeders"].updateTd = displayNum; this.columns["nbLeechers"].updateTd = displayNum; this.columns["pubDate"].updateTd = displayDate; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { const getSizeFilters = () => { let minSize = (window.qBittorrent.Search.searchSizeFilter.min > 0.00) ? (window.qBittorrent.Search.searchSizeFilter.min * Math.pow(1024, window.qBittorrent.Search.searchSizeFilter.minUnit)) : 0.00; let maxSize = (window.qBittorrent.Search.searchSizeFilter.max > 0.00) ? (window.qBittorrent.Search.searchSizeFilter.max * Math.pow(1024, window.qBittorrent.Search.searchSizeFilter.maxUnit)) : 0.00; @@ -2064,22 +2053,20 @@ window.qBittorrent.DynamicTable ??= (() => { }); return filteredRows; - }, - }); + } + } - const SearchPluginsTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class SearchPluginsTable extends DynamicTable { + initColumns() { this.newColumn("fullName", "", "QBT_TR(Name)QBT_TR[CONTEXT=SearchPluginsTable]", 175, true); this.newColumn("version", "", "QBT_TR(Version)QBT_TR[CONTEXT=SearchPluginsTable]", 100, true); this.newColumn("url", "", "QBT_TR(Url)QBT_TR[CONTEXT=SearchPluginsTable]", 175, true); this.newColumn("enabled", "", "QBT_TR(Enabled)QBT_TR[CONTEXT=SearchPluginsTable]", 100, true); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { this.columns["enabled"].updateTd = function(td, row) { const value = this.getRowValue(row); if (value) { @@ -2095,13 +2082,11 @@ window.qBittorrent.DynamicTable ??= (() => { td.closest("tr").classList.remove("green"); } }; - }, - }); + } + } - const TorrentTrackersTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class TorrentTrackersTable extends DynamicTable { + initColumns() { this.newColumn("tier", "", "QBT_TR(Tier)QBT_TR[CONTEXT=TrackerListWidget]", 35, true); this.newColumn("url", "", "QBT_TR(URL)QBT_TR[CONTEXT=TrackerListWidget]", 250, true); this.newColumn("status", "", "QBT_TR(Status)QBT_TR[CONTEXT=TrackerListWidget]", 125, true); @@ -2112,9 +2097,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("message", "", "QBT_TR(Message)QBT_TR[CONTEXT=TrackerListWidget]", 250, true); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const naturalSort = function(row1, row2) { if (!row1.full_data._sortable || !row2.full_data._sortable) return 0; @@ -2191,33 +2176,30 @@ window.qBittorrent.DynamicTable ??= (() => { td.title = status; }; } - }); + } - const BulkRenameTorrentFilesTable = new Class({ - Extends: DynamicTable, - - filterTerms: [], - prevFilterTerms: [], - prevRowsString: null, - prevFilteredRows: [], - prevSortedColumn: null, - prevReverseSort: null, - fileTree: new window.qBittorrent.FileTree.FileTree(), - - setupVirtualList: function() { - this.parent(); + class BulkRenameTorrentFilesTable extends DynamicTable { + filterTerms = []; + prevFilterTerms = []; + prevRowsString = null; + prevFilteredRows = []; + prevSortedColumn = null; + prevReverseSort = null; + fileTree = new window.qBittorrent.FileTree.FileTree(); + setupVirtualList() { + super.setupVirtualList(); this.rowHeight = 29; - }, + } - populateTable: function(root) { + populateTable(root) { this.fileTree.setRoot(root); root.children.each((node) => { this._addNodeToTable(node, 0); }); - }, + } - _addNodeToTable: function(node, depth) { + _addNodeToTable(node, depth) { node.depth = depth; if (node.isFolder) { @@ -2243,28 +2225,28 @@ window.qBittorrent.DynamicTable ??= (() => { node.children.each((child) => { this._addNodeToTable(child, depth + 1); }); - }, + } - getRoot: function() { + getRoot() { return this.fileTree.getRoot(); - }, + } - getNode: function(rowId) { + getNode(rowId) { return this.fileTree.getNode(rowId); - }, + } - getRow: function(node) { + getRow(node) { const rowId = this.fileTree.getRowId(node).toString(); return this.rows.get(rowId); - }, + } - getSelectedRows: function() { + getSelectedRows() { const nodes = this.fileTree.toArray(); return nodes.filter(x => x.checked === 0); - }, + } - initColumns: function() { + initColumns() { // Blocks saving header width (because window width isn't saved) LocalPreferences.remove(`column_checked_width_${this.dynamicTableDivId}`); LocalPreferences.remove(`column_original_width_${this.dynamicTableDivId}`); @@ -2274,12 +2256,12 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("renamed", "", "QBT_TR(Renamed)QBT_TR[CONTEXT=TrackerListWidget]", 220, true); this.initColumnsFunctions(); - }, + } /** * Toggles the global checkbox and all checkboxes underneath */ - toggleGlobalCheckbox: function() { + toggleGlobalCheckbox() { const checkbox = document.getElementById("rootMultiRename_cb"); const checkboxes = document.querySelectorAll("input.RenamingCB"); @@ -2305,9 +2287,9 @@ window.qBittorrent.DynamicTable ??= (() => { } this.updateGlobalCheckbox(); - }, + } - toggleNodeTreeCheckbox: function(rowId, checkState) { + toggleNodeTreeCheckbox(rowId, checkState) { const node = this.getNode(rowId); node.checked = checkState; node.full_data.checked = checkState; @@ -2317,9 +2299,9 @@ window.qBittorrent.DynamicTable ??= (() => { for (let i = 0; i < node.children.length; ++i) this.toggleNodeTreeCheckbox(node.children[i].rowId, checkState); - }, + } - updateGlobalCheckbox: function() { + updateGlobalCheckbox() { const checkbox = document.getElementById("rootMultiRename_cb"); const nodes = this.fileTree.toArray(); const isAllChecked = nodes.every((node) => node.checked === 0); @@ -2339,9 +2321,9 @@ window.qBittorrent.DynamicTable ??= (() => { checkbox.indeterminate = true; checkbox.checked = false; } - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const that = this; // checked @@ -2426,15 +2408,13 @@ window.qBittorrent.DynamicTable ??= (() => { span.id = fileNameRenamedId; span.textContent = node.renamed; }; - }, + } - onRowSelectionChange: (row) => {}, + onRowSelectionChange(row) {} - selectRow: () => { - return; - }, + selectRow() {} - reselectRows: function(rowIds) { + reselectRows(rowIds) { this.deselectAll(); for (const tr of this.getTrs()) { if (rowIds.includes(tr.rowId)) { @@ -2449,9 +2429,9 @@ window.qBittorrent.DynamicTable ??= (() => { } } this.updateGlobalCheckbox(); - }, + } - _sortNodesByColumn: function(nodes, column) { + _sortNodesByColumn(nodes, column) { nodes.sort((row1, row2) => { // list folders before files when sorting by name if (column.name === "original") { @@ -2471,9 +2451,9 @@ window.qBittorrent.DynamicTable ??= (() => { if (node.children.length > 0) this._sortNodesByColumn(node.children, column); }); - }, + } - _filterNodes: function(node, filterTerms, filteredRows) { + _filterNodes(node, filterTerms, filteredRows) { if (node.isFolder) { const childAdded = node.children.reduce((acc, child) => { // we must execute the function before ORing w/ acc or we'll stop checking child nodes after the first successful match @@ -2494,17 +2474,17 @@ window.qBittorrent.DynamicTable ??= (() => { } return false; - }, + } - setFilter: function(text) { + setFilter(text) { const filterTerms = text.trim().toLowerCase().split(" "); if ((filterTerms.length === 1) && (filterTerms[0] === "")) this.filterTerms = []; else this.filterTerms = filterTerms; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { if (this.getRoot() === null) return []; @@ -2560,17 +2540,17 @@ window.qBittorrent.DynamicTable ??= (() => { this.prevSortedColumn = this.sortedColumn; this.prevReverseSort = this.reverseSort; return filteredRows; - }, + } - setIgnored: function(rowId, ignore) { + setIgnored(rowId, ignore) { const row = this.rows.get(rowId); if (ignore) row.full_data.remaining = 0; else row.full_data.remaining = (row.full_data.size * (1.0 - (row.full_data.progress / 100))); - }, + } - setupCommonEvents: function() { + setupCommonEvents() { const headerDiv = document.getElementById("bulkRenameFilesTableFixedHeaderDiv"); this.dynamicTableDiv.addEventListener("scroll", (e) => { headerDiv.scrollLeft = this.dynamicTableDiv.scrollLeft; @@ -2579,64 +2559,59 @@ window.qBittorrent.DynamicTable ??= (() => { this.rerender(); }); } - }); + } - const TorrentFilesTable = new Class({ - Extends: DynamicTable, + class TorrentFilesTable extends DynamicTable { + filterTerms = []; + prevFilterTerms = []; + prevRowsString = null; + prevFilteredRows = []; + prevSortedColumn = null; + prevReverseSort = null; + fileTree = new window.qBittorrent.FileTree.FileTree(); + collapseState = new Map(); - filterTerms: [], - prevFilterTerms: [], - prevRowsString: null, - prevFilteredRows: [], - prevSortedColumn: null, - prevReverseSort: null, - fileTree: new window.qBittorrent.FileTree.FileTree(), - - initialize: function() { - this.collapseState = new Map(); - }, - - isCollapsed: function(id) { + isCollapsed(id) { return this.collapseState.get(id)?.collapsed ?? false; - }, + } - expandNode: function(id) { + expandNode(id) { const state = this.collapseState.get(id); if (state !== undefined) state.collapsed = false; this._updateNodeState(id, false); - }, + } - collapseNode: function(id) { + collapseNode(id) { const state = this.collapseState.get(id); if (state !== undefined) state.collapsed = true; this._updateNodeState(id, true); - }, + } - expandAllNodes: function() { + expandAllNodes() { for (const [key, _] of this.collapseState) this.expandNode(key); - }, + } - collapseAllNodes: function() { + collapseAllNodes() { for (const [key, state] of this.collapseState) { // collapse all nodes except root if (state.depth >= 1) this.collapseNode(key); } - }, + } - _updateNodeVisibility: (node, shouldHide) => { + _updateNodeVisibility(node, shouldHide) { const span = document.getElementById(`filesTablefileName${node.rowId}`); // span won't exist if row has been filtered out if (span === null) return; const tr = span.parentElement.parentElement; tr.classList.toggle("invisible", shouldHide); - }, + } - _updateNodeCollapseIcon: (node, isCollapsed) => { + _updateNodeCollapseIcon(node, isCollapsed) { const span = document.getElementById(`filesTablefileName${node.rowId}`); // span won't exist if row has been filtered out if (span === null) @@ -2646,9 +2621,9 @@ window.qBittorrent.DynamicTable ??= (() => { // rotate the collapse icon const collapseIcon = td.firstElementChild; collapseIcon.classList.toggle("rotate", isCollapsed); - }, + } - _updateNodeState: function(id, shouldCollapse) { + _updateNodeState(id, shouldCollapse) { // collapsed rows will be filtered out when using virtual list if (this.useVirtualList) return; @@ -2659,9 +2634,9 @@ window.qBittorrent.DynamicTable ??= (() => { this._updateNodeCollapseIcon(node, shouldCollapse); this._updateNodeChildVisibility(node, shouldCollapse); - }, + } - _updateNodeChildVisibility: function(root, shouldHide) { + _updateNodeChildVisibility(root, shouldHide) { const stack = [...root.children]; while (stack.length > 0) { const node = stack.pop(); @@ -2670,48 +2645,46 @@ window.qBittorrent.DynamicTable ??= (() => { stack.push(...node.children); } - }, - - clear: function() { - this.parent(); + } + clear() { + super.clear(); this.collapseState.clear(); - }, - - setupVirtualList: function() { - this.parent(); + } + setupVirtualList() { + super.setupVirtualList(); this.rowHeight = 29.5; - }, + } - expandFolder: function(id) { + expandFolder(id) { const node = this.getNode(id); if (node.isFolder) this.expandNode(node); - }, + } - collapseFolder: function(id) { + collapseFolder(id) { const node = this.getNode(id); if (node.isFolder) this.collapseNode(node); - }, + } - isAllCheckboxesChecked: function() { + isAllCheckboxesChecked() { return this.fileTree.toArray().every((node) => node.checked === 1); - }, + } - isAllCheckboxesUnchecked: function() { + isAllCheckboxesUnchecked() { return this.fileTree.toArray().every((node) => node.checked !== 1); - }, + } - populateTable: function(root) { + populateTable(root) { this.fileTree.setRoot(root); root.children.each((node) => { this._addNodeToTable(node, 0); }); - }, + } - _addNodeToTable: function(node, depth) { + _addNodeToTable(node, depth) { node.depth = depth; if (node.isFolder) { @@ -2742,27 +2715,27 @@ window.qBittorrent.DynamicTable ??= (() => { node.children.each((child) => { this._addNodeToTable(child, depth + 1); }); - }, + } - getRoot: function() { + getRoot() { return this.fileTree.getRoot(); - }, + } - getNode: function(rowId) { + getNode(rowId) { return this.fileTree.getNode(rowId); - }, + } - getRow: function(node) { + getRow(node) { const rowId = this.fileTree.getRowId(node).toString(); return this.rows.get(rowId); - }, + } - getRowFileId: function(rowId) { + getRowFileId(rowId) { const row = this.rows.get(rowId); return row?.full_data.fileId; - }, + } - initColumns: function() { + initColumns() { this.newColumn("checked", "", "", 50, true); this.newColumn("name", "", "QBT_TR(Name)QBT_TR[CONTEXT=TrackerListWidget]", 300, true); this.newColumn("size", "", "QBT_TR(Total Size)QBT_TR[CONTEXT=TrackerListWidget]", 75, true); @@ -2772,9 +2745,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.newColumn("availability", "", "QBT_TR(Availability)QBT_TR[CONTEXT=TrackerListWidget]", 75, true); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const that = this; const displaySize = function(td, row) { const size = window.qBittorrent.Misc.friendlyUnit(this.getRowValue(row), false); @@ -2906,9 +2879,9 @@ window.qBittorrent.DynamicTable ??= (() => { // remaining, availability this.columns["remaining"].updateTd = displaySize; this.columns["availability"].updateTd = displayPercentage; - }, + } - _sortNodesByColumn: function(nodes, column) { + _sortNodesByColumn(nodes, column) { nodes.sort((row1, row2) => { // list folders before files when sorting by name if (column.name === "name") { @@ -2928,9 +2901,9 @@ window.qBittorrent.DynamicTable ??= (() => { if (node.children.length > 0) this._sortNodesByColumn(node.children, column); }); - }, + } - _filterNodes: function(node, filterTerms, filteredRows) { + _filterNodes(node, filterTerms, filteredRows) { if (node.isFolder && (!this.useVirtualList || !this.isCollapsed(node.rowId))) { const childAdded = node.children.toReversed().reduce((acc, child) => { // we must execute the function before ORing w/ acc or we'll stop checking child nodes after the first successful match @@ -2951,17 +2924,17 @@ window.qBittorrent.DynamicTable ??= (() => { } return false; - }, + } - setFilter: function(text) { + setFilter(text) { const filterTerms = text.trim().toLowerCase().split(" "); if ((filterTerms.length === 1) && (filterTerms[0] === "")) this.filterTerms = []; else this.filterTerms = filterTerms; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { if (this.getRoot() === null) return []; @@ -3009,18 +2982,18 @@ window.qBittorrent.DynamicTable ??= (() => { this.prevSortedColumn = this.sortedColumn; this.prevReverseSort = this.reverseSort; return filteredRows; - }, + } - setIgnored: function(rowId, ignore) { + setIgnored(rowId, ignore) { const row = this.rows.get(rowId.toString()); if (ignore) row.full_data.remaining = 0; else row.full_data.remaining = (row.full_data.size * (1.0 - (row.full_data.progress / 100))); - }, + } - setupCommonEvents: function() { - this.parent(); + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("keydown", (e) => { const tr = e.target.closest("tr"); if (!tr) @@ -3038,11 +3011,10 @@ window.qBittorrent.DynamicTable ??= (() => { } }); } - }); + } - const RssFeedTable = new Class({ - Extends: DynamicTable, - initColumns: function() { + class RssFeedTable extends DynamicTable { + initColumns() { this.newColumn("state_icon", "", "", 30, true); this.newColumn("name", "", "QBT_TR(RSS feeds)QBT_TR[CONTEXT=FeedListWidget]", -1, true); @@ -3057,13 +3029,13 @@ window.qBittorrent.DynamicTable ??= (() => { td.textContent = value; td.title = value; }; - }, - setupHeaderMenu: () => {}, - setupHeaderEvents: () => {}, - getFilteredAndSortedRows: function() { + } + setupHeaderMenu() {} + setupHeaderEvents() {} + getFilteredAndSortedRows() { return [...this.getRowValues()]; - }, - selectRow: function(rowId) { + } + selectRow(rowId) { this.selectedRows.push(rowId); this.setRowClass(); this.onSelectedRowChanged(); @@ -3076,9 +3048,9 @@ window.qBittorrent.DynamicTable ??= (() => { } } window.qBittorrent.Rss.showRssFeed(path); - }, - setupCommonEvents: function() { - this.parent(); + } + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("dblclick", (e) => { const tr = e.target.closest("tr"); if (!tr || (tr.rowId === "0")) @@ -3086,8 +3058,8 @@ window.qBittorrent.DynamicTable ??= (() => { window.qBittorrent.Rss.moveItem(this.getRow(tr.rowId).full_data.dataPath); }); - }, - updateRow: function(tr, fullUpdate) { + } + updateRow(tr, fullUpdate) { const row = this.rows.get(tr.rowId); const data = row[fullUpdate ? "full_data" : "data"]; @@ -3101,8 +3073,8 @@ window.qBittorrent.DynamicTable ??= (() => { const indentation = row.full_data.indentation; tds[0].style.paddingLeft = `${indentation * 32 + 4}px`; tds[1].style.paddingLeft = `${indentation * 32 + 4}px`; - }, - updateIcons: function() { + } + updateIcons() { // state_icon for (const row of this.getRowValues()) { let img_path; @@ -3146,8 +3118,8 @@ window.qBittorrent.DynamicTable ??= (() => { td.append(img); } } - }, - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + } + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -3183,19 +3155,18 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); } - }); + } - const RssArticleTable = new Class({ - Extends: DynamicTable, - initColumns: function() { + class RssArticleTable extends DynamicTable { + initColumns() { this.newColumn("name", "", "QBT_TR(Torrents: (double-click to download))QBT_TR[CONTEXT=RSSWidget]", -1, true); - }, - setupHeaderMenu: () => {}, - setupHeaderEvents: () => {}, - getFilteredAndSortedRows: function() { + } + setupHeaderMenu() {} + setupHeaderEvents() {} + getFilteredAndSortedRows() { return [...this.getRowValues()]; - }, - selectRow: function(rowId) { + } + selectRow(rowId) { this.selectedRows.push(rowId); this.setRowClass(); this.onSelectedRowChanged(); @@ -3211,10 +3182,10 @@ window.qBittorrent.DynamicTable ??= (() => { } } window.qBittorrent.Rss.showDetails(feedUid, articleId); - }, + } - setupCommonEvents: function() { - this.parent(); + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("dblclick", (e) => { const tr = e.target.closest("tr"); if (!tr) @@ -3222,8 +3193,8 @@ window.qBittorrent.DynamicTable ??= (() => { showDownloadPage([this.getRow(tr.rowId).full_data.torrentURL]); }); - }, - updateRow: function(tr, fullUpdate) { + } + updateRow(tr, fullUpdate) { const row = this.rows.get(tr.rowId); const data = row[fullUpdate ? "full_data" : "data"]; tr.classList.toggle("unreadArticle", !row.full_data.isRead); @@ -3234,8 +3205,8 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns[i].updateTd(tds[i], row); } row["data"] = {}; - }, - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + } + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -3271,11 +3242,10 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); } - }); + } - const RssDownloaderRulesTable = new Class({ - Extends: DynamicTable, - initColumns: function() { + class RssDownloaderRulesTable extends DynamicTable { + initColumns() { this.newColumn("checked", "", "", 30, true); this.newColumn("name", "", "", -1, true); @@ -3302,15 +3272,15 @@ window.qBittorrent.DynamicTable ??= (() => { } }; this.columns["checked"].staticWidth = 50; - }, - setupHeaderMenu: () => {}, - setupHeaderEvents: () => {}, - getFilteredAndSortedRows: function() { + } + setupHeaderMenu() {} + setupHeaderEvents() {} + getFilteredAndSortedRows() { return [...this.getRowValues()]; - }, + } - setupCommonEvents: function() { - this.parent(); + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("dblclick", (e) => { const tr = e.target.closest("tr"); if (!tr) @@ -3318,8 +3288,8 @@ window.qBittorrent.DynamicTable ??= (() => { window.qBittorrent.RssDownloader.renameRule(this.getRow(tr.rowId).full_data.name); }); - }, - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + } + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -3354,8 +3324,8 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); - }, - selectRow: function(rowId) { + } + selectRow(rowId) { this.selectedRows.push(rowId); this.setRowClass(); this.onSelectedRowChanged(); @@ -3369,11 +3339,10 @@ window.qBittorrent.DynamicTable ??= (() => { } window.qBittorrent.RssDownloader.showRule(name); } - }); + } - const RssDownloaderFeedSelectionTable = new Class({ - Extends: DynamicTable, - initColumns: function() { + class RssDownloaderFeedSelectionTable extends DynamicTable { + initColumns() { this.newColumn("checked", "", "", 30, true); this.newColumn("name", "", "", -1, true); @@ -3399,13 +3368,13 @@ window.qBittorrent.DynamicTable ??= (() => { } }; this.columns["checked"].staticWidth = 50; - }, - setupHeaderMenu: () => {}, - setupHeaderEvents: () => {}, - getFilteredAndSortedRows: function() { + } + setupHeaderMenu() {} + setupHeaderEvents() {} + getFilteredAndSortedRows() { return [...this.getRowValues()]; - }, - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + } + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -3440,21 +3409,20 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); - }, - selectRow: () => {} - }); + } + selectRow() {} + } - const RssDownloaderArticlesTable = new Class({ - Extends: DynamicTable, - initColumns: function() { + class RssDownloaderArticlesTable extends DynamicTable { + initColumns() { this.newColumn("name", "", "", -1, true); - }, - setupHeaderMenu: () => {}, - setupHeaderEvents: () => {}, - getFilteredAndSortedRows: function() { + } + setupHeaderMenu() {} + setupHeaderEvents() {} + getFilteredAndSortedRows() { return [...this.getRowValues()]; - }, - newColumn: function(name, style, caption, defaultWidth, defaultVisible) { + } + newColumn(name, style, caption, defaultWidth, defaultVisible) { const column = {}; column["name"] = name; column["title"] = name; @@ -3489,9 +3457,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.hiddenTableHeader.append(document.createElement("th")); this.fixedTableHeader.append(document.createElement("th")); - }, - selectRow: () => {}, - updateRow: function(tr, fullUpdate) { + } + selectRow() {} + updateRow(tr, fullUpdate) { const row = this.rows.get(tr.rowId); const data = row[fullUpdate ? "full_data" : "data"]; @@ -3511,22 +3479,20 @@ window.qBittorrent.DynamicTable ??= (() => { } row["data"] = {}; } - }); + } - const LogMessageTable = new Class({ - Extends: DynamicTable, + class LogMessageTable extends DynamicTable { + filterText = ""; - filterText: "", - - initColumns: function() { + initColumns() { this.newColumn("rowId", "", "QBT_TR(ID)QBT_TR[CONTEXT=ExecutionLogWidget]", 50, true); this.newColumn("message", "", "QBT_TR(Message)QBT_TR[CONTEXT=ExecutionLogWidget]", 350, true); this.newColumn("timestamp", "", "QBT_TR(Timestamp)QBT_TR[CONTEXT=ExecutionLogWidget]", 150, true); this.newColumn("type", "", "QBT_TR(Log Type)QBT_TR[CONTEXT=ExecutionLogWidget]", 100, true); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { this.columns["timestamp"].updateTd = function(td, row) { const date = new Date(this.getRowValue(row) * 1000).toLocaleString(); td.textContent = date; @@ -3562,9 +3528,9 @@ window.qBittorrent.DynamicTable ??= (() => { td.title = logLevel; td.closest("tr").classList.add(`logTableRow${addClass}`); }; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { let filteredRows = []; this.filterText = window.qBittorrent.Log.getFilterText(); const filterTerms = (this.filterText.length > 0) ? this.filterText.toLowerCase().split(" ") : []; @@ -3593,13 +3559,11 @@ window.qBittorrent.DynamicTable ??= (() => { this.filteredLength = filteredRows.length; return filteredRows; - }, - }); + } + } - const LogPeerTable = new Class({ - Extends: LogMessageTable, - - initColumns: function() { + class LogPeerTable extends LogMessageTable { + initColumns() { this.newColumn("rowId", "", "QBT_TR(ID)QBT_TR[CONTEXT=ExecutionLogWidget]", 50, true); this.newColumn("ip", "", "QBT_TR(IP)QBT_TR[CONTEXT=ExecutionLogWidget]", 150, true); this.newColumn("timestamp", "", "QBT_TR(Timestamp)QBT_TR[CONTEXT=ExecutionLogWidget]", 150, true); @@ -3626,9 +3590,9 @@ window.qBittorrent.DynamicTable ??= (() => { td.title = status; td.closest("tr").classList.add(`logTableRow${addClass}`); }; - }, + } - getFilteredAndSortedRows: function() { + getFilteredAndSortedRows() { let filteredRows = []; this.filterText = window.qBittorrent.Log.getFilterText(); const filterTerms = (this.filterText.length > 0) ? this.filterText.toLowerCase().split(" ") : []; @@ -3652,20 +3616,16 @@ window.qBittorrent.DynamicTable ??= (() => { return filteredRows; } - }); + } - const TorrentWebseedsTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class TorrentWebseedsTable extends DynamicTable { + initColumns() { this.newColumn("url", "", "QBT_TR(URL)QBT_TR[CONTEXT=HttpServer]", 500, true); - }, - }); + } + } - const TorrentCreationTasksTable = new Class({ - Extends: DynamicTable, - - initColumns: function() { + class TorrentCreationTasksTable extends DynamicTable { + initColumns() { this.newColumn("state_icon", "", "QBT_TR(Status Icon)QBT_TR[CONTEXT=TorrentCreator]", 30, false); this.newColumn("source_path", "", "QBT_TR(Source Path)QBT_TR[CONTEXT=TorrentCreator]", 200, true); this.newColumn("progress", "", "QBT_TR(Progress)QBT_TR[CONTEXT=TorrentCreator]", 85, true); @@ -3686,9 +3646,9 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["source_path"].dataProperties.push("status"); this.initColumnsFunctions(); - }, + } - initColumnsFunctions: function() { + initColumnsFunctions() { const getStateIconClasses = (state) => { let stateClass = "stateUnknown"; // normalize states @@ -3864,10 +3824,10 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["added_on"].updateTd = displayDate; this.columns["start_on"].updateTd = displayDate; this.columns["completion_on"].updateTd = displayDate; - }, + } - setupCommonEvents: function() { - this.parent(); + setupCommonEvents() { + super.setupCommonEvents(); this.dynamicTableDiv.addEventListener("dblclick", (e) => { const tr = e.target.closest("tr"); if (!tr) @@ -3878,8 +3838,8 @@ window.qBittorrent.DynamicTable ??= (() => { window.qBittorrent.TorrentCreator.exportTorrents(); }); - }, - }); + } + } return exports(); })(); From bb68a39b530e81858478b801c24a75914964d4a5 Mon Sep 17 00:00:00 2001 From: skomerko <168652295+skomerko@users.noreply.github.com> Date: Tue, 29 Apr 2025 19:58:23 +0200 Subject: [PATCH 15/21] WebUI: Prefix private properties with # in dynamic table classes --- src/webui/www/private/scripts/dynamicTable.js | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index c23606140..fdbbca346 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -293,7 +293,7 @@ window.qBittorrent.DynamicTable ??= (() => { if (width < 16) width = 16; - this._setColumnWidth(this.resizeTh.columnName, width); + this.#setColumnWidth(this.resizeTh.columnName, width); } }.bind(this); @@ -393,7 +393,7 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns[columnName].onVisibilityChange?.(columnName); } - _calculateColumnBodyWidth(column) { + #calculateColumnBodyWidth(column) { const columnIndex = this.getColumnPos(column.name); const bodyColumn = document.getElementById(this.dynamicTableDivId).querySelectorAll("tr>th")[columnIndex]; const canvas = document.createElement("canvas"); @@ -417,7 +417,7 @@ window.qBittorrent.DynamicTable ??= (() => { return longestTd.width + 10; } - _setColumnWidth(columnName, width) { + #setColumnWidth(columnName, width) { const column = this.columns[columnName]; column.width = width; @@ -438,7 +438,7 @@ window.qBittorrent.DynamicTable ??= (() => { let width = column.staticWidth ?? 0; if (column.staticWidth === null) { // check required min body width - const bodyTextWidth = this._calculateColumnBodyWidth(column); + const bodyTextWidth = this.#calculateColumnBodyWidth(column); // check required min header width const columnIndex = this.getColumnPos(column.name); @@ -453,7 +453,7 @@ window.qBittorrent.DynamicTable ??= (() => { width = Math.max(headTextWidth, bodyTextWidth); } - this._setColumnWidth(column.name, width); + this.#setColumnWidth(column.name, width); this.saveColumnWidth(column.name); } @@ -2195,11 +2195,11 @@ window.qBittorrent.DynamicTable ??= (() => { populateTable(root) { this.fileTree.setRoot(root); root.children.each((node) => { - this._addNodeToTable(node, 0); + this.#addNodeToTable(node, 0); }); } - _addNodeToTable(node, depth) { + #addNodeToTable(node, depth) { node.depth = depth; if (node.isFolder) { @@ -2223,7 +2223,7 @@ window.qBittorrent.DynamicTable ??= (() => { } node.children.each((child) => { - this._addNodeToTable(child, depth + 1); + this.#addNodeToTable(child, depth + 1); }); } @@ -2431,7 +2431,7 @@ window.qBittorrent.DynamicTable ??= (() => { this.updateGlobalCheckbox(); } - _sortNodesByColumn(nodes, column) { + #sortNodesByColumn(nodes, column) { nodes.sort((row1, row2) => { // list folders before files when sorting by name if (column.name === "original") { @@ -2449,15 +2449,15 @@ window.qBittorrent.DynamicTable ??= (() => { nodes.each((node) => { if (node.children.length > 0) - this._sortNodesByColumn(node.children, column); + this.#sortNodesByColumn(node.children, column); }); } - _filterNodes(node, filterTerms, filteredRows) { + #filterNodes(node, filterTerms, filteredRows) { if (node.isFolder) { const childAdded = node.children.reduce((acc, child) => { // we must execute the function before ORing w/ acc or we'll stop checking child nodes after the first successful match - return (this._filterNodes(child, filterTerms, filteredRows) || acc); + return (this.#filterNodes(child, filterTerms, filteredRows) || acc); }, false); if (childAdded) { @@ -2506,7 +2506,7 @@ window.qBittorrent.DynamicTable ??= (() => { const filteredRows = []; this.getRoot().children.each((child) => { - this._filterNodes(child, this.filterTerms, filteredRows); + this.#filterNodes(child, this.filterTerms, filteredRows); }); filteredRows.reverse(); return filteredRows; @@ -2531,7 +2531,7 @@ window.qBittorrent.DynamicTable ??= (() => { // sort, then filter const column = this.columns[this.sortedColumn]; - this._sortNodesByColumn(this.getRoot().children, column); + this.#sortNodesByColumn(this.getRoot().children, column); const filteredRows = getFilteredRows(); this.prevFilterTerms = this.filterTerms; @@ -2579,14 +2579,14 @@ window.qBittorrent.DynamicTable ??= (() => { const state = this.collapseState.get(id); if (state !== undefined) state.collapsed = false; - this._updateNodeState(id, false); + this.#updateNodeState(id, false); } collapseNode(id) { const state = this.collapseState.get(id); if (state !== undefined) state.collapsed = true; - this._updateNodeState(id, true); + this.#updateNodeState(id, true); } expandAllNodes() { @@ -2602,7 +2602,7 @@ window.qBittorrent.DynamicTable ??= (() => { } } - _updateNodeVisibility(node, shouldHide) { + #updateNodeVisibility(node, shouldHide) { const span = document.getElementById(`filesTablefileName${node.rowId}`); // span won't exist if row has been filtered out if (span === null) @@ -2611,7 +2611,7 @@ window.qBittorrent.DynamicTable ??= (() => { tr.classList.toggle("invisible", shouldHide); } - _updateNodeCollapseIcon(node, isCollapsed) { + #updateNodeCollapseIcon(node, isCollapsed) { const span = document.getElementById(`filesTablefileName${node.rowId}`); // span won't exist if row has been filtered out if (span === null) @@ -2623,7 +2623,7 @@ window.qBittorrent.DynamicTable ??= (() => { collapseIcon.classList.toggle("rotate", isCollapsed); } - _updateNodeState(id, shouldCollapse) { + #updateNodeState(id, shouldCollapse) { // collapsed rows will be filtered out when using virtual list if (this.useVirtualList) return; @@ -2631,17 +2631,17 @@ window.qBittorrent.DynamicTable ??= (() => { if (!node.isFolder) return; - this._updateNodeCollapseIcon(node, shouldCollapse); + this.#updateNodeCollapseIcon(node, shouldCollapse); - this._updateNodeChildVisibility(node, shouldCollapse); + this.#updateNodeChildVisibility(node, shouldCollapse); } - _updateNodeChildVisibility(root, shouldHide) { + #updateNodeChildVisibility(root, shouldHide) { const stack = [...root.children]; while (stack.length > 0) { const node = stack.pop(); - this._updateNodeVisibility(node, (shouldHide ? shouldHide : this.isCollapsed(node.root.rowId))); + this.#updateNodeVisibility(node, (shouldHide ? shouldHide : this.isCollapsed(node.root.rowId))); stack.push(...node.children); } @@ -2680,11 +2680,11 @@ window.qBittorrent.DynamicTable ??= (() => { populateTable(root) { this.fileTree.setRoot(root); root.children.each((node) => { - this._addNodeToTable(node, 0); + this.#addNodeToTable(node, 0); }); } - _addNodeToTable(node, depth) { + #addNodeToTable(node, depth) { node.depth = depth; if (node.isFolder) { @@ -2713,7 +2713,7 @@ window.qBittorrent.DynamicTable ??= (() => { } node.children.each((child) => { - this._addNodeToTable(child, depth + 1); + this.#addNodeToTable(child, depth + 1); }); } @@ -2881,7 +2881,7 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["availability"].updateTd = displayPercentage; } - _sortNodesByColumn(nodes, column) { + #sortNodesByColumn(nodes, column) { nodes.sort((row1, row2) => { // list folders before files when sorting by name if (column.name === "name") { @@ -2899,15 +2899,15 @@ window.qBittorrent.DynamicTable ??= (() => { nodes.each((node) => { if (node.children.length > 0) - this._sortNodesByColumn(node.children, column); + this.#sortNodesByColumn(node.children, column); }); } - _filterNodes(node, filterTerms, filteredRows) { + #filterNodes(node, filterTerms, filteredRows) { if (node.isFolder && (!this.useVirtualList || !this.isCollapsed(node.rowId))) { const childAdded = node.children.toReversed().reduce((acc, child) => { // we must execute the function before ORing w/ acc or we'll stop checking child nodes after the first successful match - return (this._filterNodes(child, filterTerms, filteredRows) || acc); + return (this.#filterNodes(child, filterTerms, filteredRows) || acc); }, false); if (childAdded) { @@ -2948,7 +2948,7 @@ window.qBittorrent.DynamicTable ??= (() => { const getFilteredRows = function() { const filteredRows = []; this.getRoot().children.each((child) => { - this._filterNodes(child, this.filterTerms, filteredRows); + this.#filterNodes(child, this.filterTerms, filteredRows); }); filteredRows.reverse(); return filteredRows; @@ -2973,7 +2973,7 @@ window.qBittorrent.DynamicTable ??= (() => { // sort, then filter const column = this.columns[this.sortedColumn]; - this._sortNodesByColumn(this.getRoot().children, column); + this.#sortNodesByColumn(this.getRoot().children, column); const filteredRows = getFilteredRows(); this.prevFilterTerms = this.filterTerms; From e7dee969e1fb2e7dfa2965ea6562702ce2f47070 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Thu, 1 May 2025 08:57:10 +0300 Subject: [PATCH 16/21] Remove dubious seeding time max value PR #22624. --- src/base/bittorrent/sessionimpl.cpp | 18 +++++++++--------- src/base/bittorrent/torrent.cpp | 2 -- src/base/bittorrent/torrent.h | 2 -- src/base/bittorrent/torrentimpl.cpp | 4 ---- src/webui/www/private/shareratio.html | 4 ++-- src/webui/www/private/views/preferences.html | 8 ++++---- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index f3d68cf5f..a6bf947f8 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -472,11 +472,11 @@ SessionImpl::SessionImpl(QObject *parent) , m_additionalTrackers(BITTORRENT_SESSION_KEY(u"AdditionalTrackers"_s)) , m_isAddTrackersFromURLEnabled(BITTORRENT_SESSION_KEY(u"AddTrackersFromURLEnabled"_s), false) , m_additionalTrackersURL(BITTORRENT_SESSION_KEY(u"AdditionalTrackersURL"_s)) - , m_globalMaxRatio(BITTORRENT_SESSION_KEY(u"GlobalMaxRatio"_s), -1, [](qreal r) { return r < 0 ? -1. : r;}) - , m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s), Torrent::NO_SEEDING_TIME_LIMIT - , clampValue(Torrent::NO_SEEDING_TIME_LIMIT, Torrent::MAX_SEEDING_TIME)) - , m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s), Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT - , clampValue(Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT, Torrent::MAX_INACTIVE_SEEDING_TIME)) + , m_globalMaxRatio(BITTORRENT_SESSION_KEY(u"GlobalMaxRatio"_s), -1, [](qreal r) { return r < 0 ? -1. : r; }) + , m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s) + , Torrent::NO_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_SEEDING_TIME_LIMIT)) + , m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s) + , Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT)) , m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false) , m_isAddTorrentStopped(BITTORRENT_SESSION_KEY(u"AddTorrentStopped"_s), false) , m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None) @@ -1258,7 +1258,7 @@ int SessionImpl::globalMaxSeedingMinutes() const void SessionImpl::setGlobalMaxSeedingMinutes(int minutes) { - minutes = std::clamp(minutes, Torrent::NO_SEEDING_TIME_LIMIT, Torrent::MAX_SEEDING_TIME); + minutes = std::max(minutes, Torrent::NO_SEEDING_TIME_LIMIT); if (minutes != globalMaxSeedingMinutes()) { @@ -1274,7 +1274,7 @@ int SessionImpl::globalMaxInactiveSeedingMinutes() const void SessionImpl::setGlobalMaxInactiveSeedingMinutes(int minutes) { - minutes = std::clamp(minutes, Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT, Torrent::MAX_INACTIVE_SEEDING_TIME); + minutes = std::max(minutes, Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT); if (minutes != globalMaxInactiveSeedingMinutes()) { @@ -2337,13 +2337,13 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent) description = tr("Torrent reached the share ratio limit."); } else if (const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60; - (seedingTimeLimit >= 0) && (seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit)) + (seedingTimeLimit >= 0) && (seedingTimeInMinutes >= seedingTimeLimit)) { reached = true; description = tr("Torrent reached the seeding time limit."); } else if (const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60; - (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit)) + (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit)) { reached = true; description = tr("Torrent reached the inactive seeding time limit."); diff --git a/src/base/bittorrent/torrent.cpp b/src/base/bittorrent/torrent.cpp index c92fb9aea..1fdf52f61 100644 --- a/src/base/bittorrent/torrent.cpp +++ b/src/base/bittorrent/torrent.cpp @@ -52,8 +52,6 @@ namespace BitTorrent const int Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT = -1; const qreal Torrent::MAX_RATIO = 9999; - const int Torrent::MAX_SEEDING_TIME = 525600; - const int Torrent::MAX_INACTIVE_SEEDING_TIME = 525600; TorrentID Torrent::id() const { diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index fc817b86c..644af158b 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -134,8 +134,6 @@ namespace BitTorrent static const int NO_INACTIVE_SEEDING_TIME_LIMIT; static const qreal MAX_RATIO; - static const int MAX_SEEDING_TIME; - static const int MAX_INACTIVE_SEEDING_TIME; using TorrentContentHandler::TorrentContentHandler; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index f4ae0e0fa..fb27c44dc 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -2692,8 +2692,6 @@ void TorrentImpl::setSeedingTimeLimit(int limit) { if (limit < USE_GLOBAL_SEEDING_TIME) limit = NO_SEEDING_TIME_LIMIT; - else if (limit > MAX_SEEDING_TIME) - limit = MAX_SEEDING_TIME; if (m_seedingTimeLimit != limit) { @@ -2707,8 +2705,6 @@ void TorrentImpl::setInactiveSeedingTimeLimit(int limit) { if (limit < USE_GLOBAL_INACTIVE_SEEDING_TIME) limit = NO_INACTIVE_SEEDING_TIME_LIMIT; - else if (limit > MAX_INACTIVE_SEEDING_TIME) - limit = MAX_SEEDING_TIME; if (m_inactiveSeedingTimeLimit != limit) { diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index 9205b7f76..56b70f25d 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -177,12 +177,12 @@
- +
- +
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index ec27db3a3..c8ef9de78 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -2923,8 +2923,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD let maxSeedingTime = -1; if (document.getElementById("maxSeedingTimeCheckbox").checked) { maxSeedingTime = Number(document.getElementById("maxSeedingTimeValue").value); - if (Number.isNaN(maxSeedingTime) || (maxSeedingTime < 0) || (maxSeedingTime > 525600)) { - alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); + if (Number.isNaN(maxSeedingTime) || (maxSeedingTime < 0)) { + alert("QBT_TR(Seeding time limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } @@ -2934,8 +2934,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD let maxInactiveSeedingTime = -1; if (document.getElementById("maxInactiveSeedingTimeCheckbox").checked) { maxInactiveSeedingTime = Number(document.getElementById("maxInactiveSeedingTimeValue").value); - if (Number.isNaN(maxInactiveSeedingTime) || (maxInactiveSeedingTime < 0) || (maxInactiveSeedingTime > 525600)) { - alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); + if (Number.isNaN(maxInactiveSeedingTime) || (maxInactiveSeedingTime < 0)) { + alert("QBT_TR(Seeding time limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } From 6cd6267c26a7a7bf4575621603dc839a7cd19227 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Thu, 1 May 2025 14:18:18 +0300 Subject: [PATCH 17/21] Fix ratio handling PR #22638. --- src/base/bittorrent/sessionimpl.cpp | 4 ++-- src/base/bittorrent/torrent.cpp | 4 +++- src/base/bittorrent/torrentimpl.cpp | 5 ++--- src/gui/optionsdialog.ui | 3 --- src/gui/properties/propertieswidget.cpp | 4 ++-- src/gui/torrentsharelimitswidget.ui | 3 --- src/gui/transferlistmodel.cpp | 2 +- src/webui/api/serialize/serialize_torrent.cpp | 2 +- src/webui/api/torrentscontroller.cpp | 4 ++-- src/webui/www/private/shareratio.html | 2 +- src/webui/www/private/views/preferences.html | 4 ++-- 11 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index a6bf947f8..bc3fca77e 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1242,7 +1242,7 @@ qreal SessionImpl::globalMaxRatio() const void SessionImpl::setGlobalMaxRatio(qreal ratio) { if (ratio < 0) - ratio = -1.; + ratio = Torrent::NO_RATIO_LIMIT; if (ratio != globalMaxRatio()) { @@ -2331,7 +2331,7 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent) QString description; if (const qreal ratio = torrent->realRatio(); - (ratioLimit >= 0) && (ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit)) + (ratioLimit >= 0) && (ratio >= ratioLimit)) { reached = true; description = tr("Torrent reached the share ratio limit."); diff --git a/src/base/bittorrent/torrent.cpp b/src/base/bittorrent/torrent.cpp index 1fdf52f61..b8098d77f 100644 --- a/src/base/bittorrent/torrent.cpp +++ b/src/base/bittorrent/torrent.cpp @@ -29,6 +29,8 @@ #include "torrent.h" +#include + #include #include "infohash.h" @@ -51,7 +53,7 @@ namespace BitTorrent const int Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME = -2; const int Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT = -1; - const qreal Torrent::MAX_RATIO = 9999; + const qreal Torrent::MAX_RATIO = std::numeric_limits::infinity(); TorrentID Torrent::id() const { diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index fb27c44dc..03ca62eca 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1515,7 +1515,8 @@ qreal TorrentImpl::realRatio() const const qreal ratio = upload / static_cast(download); Q_ASSERT(ratio >= 0); - return (ratio > MAX_RATIO) ? MAX_RATIO : ratio; + + return ratio; } int TorrentImpl::uploadPayloadRate() const @@ -2677,8 +2678,6 @@ void TorrentImpl::setRatioLimit(qreal limit) { if (limit < USE_GLOBAL_RATIO) limit = NO_RATIO_LIMIT; - else if (limit > MAX_RATIO) - limit = MAX_RATIO; if (m_ratioLimit != limit) { diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 263c2bf91..e87aa65ff 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -3028,9 +3028,6 @@ Disable encryption: Only connect to peers without protocol encryption false - - 9998.000000000000000 - 0.050000000000000 diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 303043a80..8a76e4663 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -441,10 +441,10 @@ void PropertiesWidget::loadDynamicData() // Update ratio info const qreal ratio = m_torrent->realRatio(); - m_ui->labelShareRatioVal->setText(ratio > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(ratio, 2)); + m_ui->labelShareRatioVal->setText(ratio >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(ratio, 2)); const qreal popularity = m_torrent->popularity(); - m_ui->labelPopularityVal->setText(popularity > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2)); + m_ui->labelPopularityVal->setText(popularity >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2)); m_ui->labelSeedsVal->setText(tr("%1 (%2 total)", "%1 and %2 are numbers, e.g. 3 (10 total)") .arg(QString::number(m_torrent->seedsCount()) diff --git a/src/gui/torrentsharelimitswidget.ui b/src/gui/torrentsharelimitswidget.ui index 9ada9ed67..13fbfe0a2 100644 --- a/src/gui/torrentsharelimitswidget.ui +++ b/src/gui/torrentsharelimitswidget.ui @@ -47,9 +47,6 @@ false - - 9998.000000000000000 - 0.050000000000000 diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp index 7c827c1a6..0298db047 100644 --- a/src/gui/transferlistmodel.cpp +++ b/src/gui/transferlistmodel.cpp @@ -293,7 +293,7 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons if (hideValues && (value <= 0)) return {}; - return ((static_cast(value) == -1) || (value > BitTorrent::Torrent::MAX_RATIO)) + return ((static_cast(value) == -1) || (value >= BitTorrent::Torrent::MAX_RATIO)) ? C_INFINITY : Utils::String::fromDouble(value, 2); }; diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index bc75a7698..1543170d4 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -96,7 +96,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent) const auto adjustRatio = [](const qreal ratio) -> qreal { - return (ratio > BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio; + return (ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio; }; const auto getLastActivityTime = [&torrent]() -> qlonglong diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index c877fd5db..83459a892 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -523,8 +523,8 @@ void TorrentsController::propertiesAction() {KEY_PROP_SEEDS_TOTAL, torrent->totalSeedsCount()}, {KEY_PROP_PEERS, torrent->leechsCount()}, {KEY_PROP_PEERS_TOTAL, torrent->totalLeechersCount()}, - {KEY_PROP_RATIO, ((ratio > BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)}, - {KEY_PROP_POPULARITY, ((popularity > BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)}, + {KEY_PROP_RATIO, ((ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)}, + {KEY_PROP_POPULARITY, ((popularity >= BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)}, {KEY_PROP_REANNOUNCE, torrent->nextAnnounce()}, {KEY_PROP_TOTAL_SIZE, torrent->totalSize()}, {KEY_PROP_PIECES_NUM, torrent->piecesCount()}, diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index 56b70f25d..8586f50cc 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -172,7 +172,7 @@
- +
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index c8ef9de78..ed3c4bcb9 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -2912,8 +2912,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD let maxRatio = -1; if (document.getElementById("maxRatioCheckbox").checked) { maxRatio = Number(document.getElementById("maxRatioValue").value); - if (isNaN(maxRatio) || (maxRatio < 0) || (maxRatio > 9998)) { - alert("QBT_TR(Share ratio limit must be between 0 and 9998.)QBT_TR[CONTEXT=HttpServer]"); + if (isNaN(maxRatio) || (maxRatio < 0)) { + alert("QBT_TR(Share ratio limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } From 380b25e22f6dc53e42deb198d52a3de69502a889 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 23 Apr 2025 00:56:31 +0800 Subject: [PATCH 18/21] WebUI: migrate 'file tree' class to JS native class --- src/webui/www/private/scripts/file-tree.js | 99 ++++++++++------------ 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/src/webui/www/private/scripts/file-tree.js b/src/webui/www/private/scripts/file-tree.js index 328806988..b7fdf93b2 100644 --- a/src/webui/www/private/scripts/file-tree.js +++ b/src/webui/www/private/scripts/file-tree.js @@ -56,51 +56,51 @@ window.qBittorrent.FileTree ??= (() => { }; Object.freeze(TriState); - const FileTree = new Class({ - root: null, - nodeMap: {}, + class FileTree { + #root = null; + #nodeMap = {}; - setRoot: function(root) { - this.root = root; - this.generateNodeMap(root); + setRoot(root) { + this.#root = root; + this.#generateNodeMap(root); - if (this.root.isFolder) - this.root.calculateSize(); - }, + if (this.#root.isFolder) + this.#root.calculateSize(); + } - getRoot: function() { - return this.root; - }, + getRoot() { + return this.#root; + } - generateNodeMap: function(root) { + #generateNodeMap(root) { const stack = [root]; while (stack.length > 0) { const node = stack.pop(); // don't store root node in map if (node.root !== null) - this.nodeMap[node.rowId] = node; + this.#nodeMap[node.rowId] = node; stack.push(...node.children); } - }, + } - getNode: function(rowId) { - return (this.nodeMap[rowId] === undefined) + getNode(rowId) { + return (this.#nodeMap[rowId] === undefined) ? null - : this.nodeMap[rowId]; - }, + : this.#nodeMap[rowId]; + } - getRowId: (node) => { + getRowId(node) { return node.rowId; - }, + } /** * Returns the nodes in DFS in-order */ - toArray: function() { + toArray() { const ret = []; - const stack = this.root.children.toReversed(); + const stack = this.#root.children.toReversed(); while (stack.length > 0) { const node = stack.pop(); ret.push(node); @@ -108,45 +108,40 @@ window.qBittorrent.FileTree ??= (() => { } return ret; } - }); + } - const FileNode = new Class({ - name: "", - path: "", - rowId: null, - size: 0, - checked: TriState.Unchecked, - remaining: 0, - progress: 0, - priority: FilePriority.Normal, - availability: 0, - depth: 0, - root: null, - data: null, - isFolder: false, - children: [], - }); - - const FolderNode = new Class({ - Extends: FileNode, + class FileNode { + name = ""; + path = ""; + rowId = null; + size = 0; + checked = TriState.Unchecked; + remaining = 0; + progress = 0; + priority = FilePriority.Normal; + availability = 0; + depth = 0; + root = null; + data = null; + isFolder = false; + children = []; + } + class FolderNode extends FileNode { /** * Will automatically tick the checkbox for a folder if all subfolders and files are also ticked */ - autoCheckFolders: true, + autoCheckFolders = true; + isFolder = true; - initialize: function() { - this.isFolder = true; - }, - - addChild: function(node) { + addChild(node) { this.children.push(node); - }, + } /** * Calculate size of node and its children */ - calculateSize: function() { + calculateSize() { const stack = [this]; const visited = []; @@ -202,7 +197,7 @@ window.qBittorrent.FileTree ??= (() => { stack.pop(); } } - }); + } return exports(); })(); From 559f47ab0c93a5a30739e2d35a8999cf3fd77728 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 23 Apr 2025 07:11:37 +0800 Subject: [PATCH 19/21] WebUI: avoid double lookup --- src/webui/www/private/scripts/file-tree.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/webui/www/private/scripts/file-tree.js b/src/webui/www/private/scripts/file-tree.js index b7fdf93b2..c56ddeaef 100644 --- a/src/webui/www/private/scripts/file-tree.js +++ b/src/webui/www/private/scripts/file-tree.js @@ -58,7 +58,7 @@ window.qBittorrent.FileTree ??= (() => { class FileTree { #root = null; - #nodeMap = {}; + #nodeMap = {}; // Object with Number as keys is faster than anything setRoot(root) { this.#root = root; @@ -86,9 +86,9 @@ window.qBittorrent.FileTree ??= (() => { } getNode(rowId) { - return (this.#nodeMap[rowId] === undefined) - ? null - : this.#nodeMap[rowId]; + // TODO: enforce caller sites to pass `rowId` as number and not string + const value = this.#nodeMap[Number(rowId)]; + return (value !== undefined) ? value : null; } getRowId(node) { From c494314a29b339a1bd7436623167583560b68e81 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 3 May 2025 23:04:55 +0800 Subject: [PATCH 20/21] Use short format for displaying RSS entry date The long format is too verbose and hard to read. PR #22646. --- src/gui/rss/rsswidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/rss/rsswidget.cpp b/src/gui/rss/rsswidget.cpp index 98c272014..2c3fe7572 100644 --- a/src/gui/rss/rsswidget.cpp +++ b/src/gui/rss/rsswidget.cpp @@ -631,7 +631,7 @@ void RSSWidget::renderArticle(const RSS::Article *article) const u"
" + u"
%3
"_s.arg(highlightedBaseColor, highlightedBaseTextColor, article->title()); if (article->date().isValid()) - html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime())); + html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Date: "), QLocale::system().toString(article->date().toLocalTime(), QLocale::ShortFormat)); if (m_ui->feedListWidget->currentItem() == m_ui->feedListWidget->stickyUnreadItem()) html += u"
%2%3
"_s.arg(alternateBaseColor, tr("Feed: "), article->feed()->title()); if (!article->author().isEmpty()) From f1b7c4572b3d4b44568470662cc61c5ffb934cac Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 5 May 2025 15:38:12 +0800 Subject: [PATCH 21/21] Revise labels for 'duplicate torrent' actions PR #22645. --- src/gui/optionsdialog.ui | 4 ++-- src/webui/www/private/views/preferences.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index e87aa65ff..a21f7af04 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -1031,7 +1031,7 @@ - When duplicate torrent is being added + When adding a duplicate torrent @@ -1047,7 +1047,7 @@ - Ask for merging trackers when torrent is being added manually + Ask to merge trackers for manually added torrent true diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index ed3c4bcb9..b6ec95f76 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -141,7 +141,7 @@
- QBT_TR(When duplicate torrent is being added)QBT_TR[CONTEXT=OptionsDialog] + QBT_TR(When adding a duplicate torrent)QBT_TR[CONTEXT=OptionsDialog]