WebUI: Add new Add Torrent experience

This PR uses the new APIs from #21015 to provide a WebUI Add Torrent experience more closely matching the GUI's.

New functionality:
- View torrent size, date, infohash, files, etc.
- Reprioritize and ignore files before adding
- Specify tags when adding torrent
- Specify save path for incomplete torrent

Closes #20557, closes #10997, closes #12499, closes #14201, closes #15071, closes #15718, closes #16207.
PR #21645.
This commit is contained in:
Thomas Piccirello
2025-08-09 03:34:38 -07:00
committed by GitHub
parent 02d72179fe
commit 02892d1250
18 changed files with 1582 additions and 1074 deletions

View File

@@ -159,10 +159,11 @@ let setQueuePositionFN = () => {};
let exportTorrentFN = () => {};
const initializeWindows = () => {
saveWindowSize = (windowId) => {
const size = document.getElementById(windowId).getSize();
LocalPreferences.set(`window_${windowId}_width`, size.x);
LocalPreferences.set(`window_${windowId}_height`, size.y);
saveWindowSize = (windowName, windowId = windowName) => {
const windowInstance = MochaUI.Windows.instances[windowId];
const size = windowInstance.contentWrapperEl.getSize();
LocalPreferences.set(`window_${windowName}_width`, size.x);
LocalPreferences.set(`window_${windowName}_height`, size.y);
};
loadWindowWidth = (windowId, defaultValue, limitToViewportWidth = true) => {
@@ -207,14 +208,13 @@ const initializeWindows = () => {
title: "QBT_TR(Download from URLs)QBT_TR[CONTEXT=downloadFromURL]",
loadMethod: "iframe",
contentURL: contentURL.toString(),
addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
scrollbars: true,
maximizable: false,
closable: true,
paddingVertical: 0,
paddingHorizontal: 0,
width: loadWindowWidth(id, 500),
height: loadWindowHeight(id, 600),
height: loadWindowHeight(id, 300),
onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => {
saveWindowSize(id);
})
@@ -297,31 +297,33 @@ const initializeWindows = () => {
});
});
addClickEvent("upload", (e) => {
e.preventDefault();
e.stopPropagation();
const id = "uploadPage";
new MochaUI.Window({
id: id,
icon: "images/qbittorrent-tray.svg",
title: "QBT_TR(Upload local torrent)QBT_TR[CONTEXT=HttpServer]",
loadMethod: "iframe",
contentURL: "upload.html?v=${CACHEID}",
addClass: "windowFrame", // fixes iframe scrolling on iOS Safari
scrollbars: true,
maximizable: false,
paddingVertical: 0,
paddingHorizontal: 0,
width: loadWindowWidth(id, 500),
height: loadWindowHeight(id, 460),
onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => {
saveWindowSize(id);
})
});
updateMainData();
document.querySelector("#uploadButton #fileselectButton").addEventListener("click", function(event) {
// clear the value so that reselecting the same file(s) still triggers the 'change' event
this.value = null;
});
// make the entire anchor tag trigger the input, despite the input's label not spanning the entire anchor
document.getElementById("uploadLink").addEventListener("click", (e) => {
const fileSelector = document.getElementById("fileselectLink");
// clear the value so that reselecting the same file(s) still triggers the 'change' event
if (e.target === fileSelector) {
e.target.value = null;
}
else {
e.preventDefault();
fileSelector.click();
}
});
for (const element of document.querySelectorAll("#uploadButton #fileselectButton, #uploadLink #fileselectLink")) {
element.addEventListener("change", (event) => {
if (element.files.length === 0)
return;
window.qBittorrent.Client.uploadTorrentFiles(element.files);
});
}
globalUploadLimitFN = () => {
const contentURL = new URL("speedlimit.html", window.location);
contentURL.search = new URLSearchParams({
@@ -1383,4 +1385,10 @@ const initializeWindows = () => {
e.stopPropagation();
});
}
const userAgent = (navigator.userAgentData?.platform ?? navigator.platform).toLowerCase();
if (userAgent.includes("ipad") || userAgent.includes("iphone") || (userAgent.includes("mac") && (navigator.maxTouchPoints > 1))) {
for (const element of document.getElementsByClassName("fileselect"))
element.accept = ".torrent";
}
};