diff --git a/src/webui/www/private/css/Layout.css b/src/webui/www/private/css/Layout.css index fb940cbf1..457a33e0e 100644 --- a/src/webui/www/private/css/Layout.css +++ b/src/webui/www/private/css/Layout.css @@ -155,7 +155,8 @@ Required by: width: 5px; } -#desktopNavbar li ul li a { +#desktopNavbar li ul li a, +#desktopNavbar li ul li div.anchor { color: var(--color-text-default); font-weight: normal; min-width: 155px; @@ -163,7 +164,8 @@ Required by: position: relative; } -#desktopNavbar li ul li a:hover { +#desktopNavbar li ul li a:hover, +#desktopNavbar li ul li div.anchor:hover { background-color: var(--color-background-hover); color: var(--color-text-white); } diff --git a/src/webui/www/private/css/Window.css b/src/webui/www/private/css/Window.css index 9aeaf365f..99128aecd 100644 --- a/src/webui/www/private/css/Window.css +++ b/src/webui/www/private/css/Window.css @@ -184,6 +184,16 @@ div.mochaToolbarWrapper.bottom { width: 16px; } +.mochaErrorIcon { + background: url("../images/error.svg") no-repeat; + background-size: 16px; + bottom: 7px; + height: 16px; + left: 6px; + position: absolute; + width: 16px; +} + .mochaIframe { width: 100%; } diff --git a/src/webui/www/private/css/style.css b/src/webui/www/private/css/style.css index 82bc99f71..86fbf79bf 100644 --- a/src/webui/www/private/css/style.css +++ b/src/webui/www/private/css/style.css @@ -676,6 +676,17 @@ td.generalLabel { width: 1px; } +td.fullWidth { + box-sizing: border-box; + max-width: none; + width: 100%; + word-break: break-all; +} + +td.noWrap { + white-space: nowrap; +} + #tristate_cb { margin-bottom: 0; margin-top: 0; @@ -839,7 +850,8 @@ td.statusBarSeparator { color: var(--color-text-green); } -#torrentFilesTableDiv .dynamicTable tr.nonAlt:hover { +#torrentFilesTableDiv .dynamicTable tr.nonAlt:hover, +#addTorrentFilesTableDiv .dynamicTable tr.nonAlt:hover { background-color: var(--color-background-hover); color: var(--color-text-white); } diff --git a/src/webui/www/private/download.html b/src/webui/www/private/download.html index 807e95f70..72768dc25 100644 --- a/src/webui/www/private/download.html +++ b/src/webui/www/private/download.html @@ -3,13 +3,11 @@ - QBT_TR(Add Torrent Links)QBT_TR[CONTEXT=downloadFromURL] + QBT_TR(Add Torrent Links)QBT_TR[CONTEXT=DownloadFromURLDialog] - - -
-
-
-

- -

QBT_TR(One link per line (HTTP links, Magnet links and info-hashes are supported))QBT_TR[CONTEXT=AddNewTorrentDialog]

-
- QBT_TR(Torrent options)QBT_TR[CONTEXT=AddNewTorrentDialog] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - -
- - -
-
- - - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - - -
- - - - -
-
- -
-
+
+
+

QBT_TR(Add torrent links)QBT_TR[CONTEXT=DownloadFromURLDialog]

+ +

QBT_TR(One link per line (HTTP links, Magnet links and info-hashes are supported))QBT_TR[CONTEXT=DownloadFromURLDialog]

+
+
- -
+
diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index 73c02fe4c..88ceef914 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -60,7 +60,15 @@
  • QBT_TR(File)QBT_TR[CONTEXT=MainWindow]
  •    - QBT_TR(Add Torrent File...)QBT_TR[CONTEXT=MainWindow] +
    + + +
    QBT_TR(Add Torrent Link...)QBT_TR[CONTEXT=MainWindow] QBT_TR(Remove)QBT_TR[CONTEXT=TransferListWidget] QBT_TR(Start)QBT_TR[CONTEXT=TransferListWidget] diff --git a/src/webui/www/private/scripts/download.js b/src/webui/www/private/scripts/addtorrent.js similarity index 55% rename from src/webui/www/private/scripts/download.js rename to src/webui/www/private/scripts/addtorrent.js index f62e57ae0..ceec92e0a 100644 --- a/src/webui/www/private/scripts/download.js +++ b/src/webui/www/private/scripts/addtorrent.js @@ -24,16 +24,23 @@ "use strict"; window.qBittorrent ??= {}; -window.qBittorrent.Download ??= (() => { +window.qBittorrent.AddTorrent ??= (() => { const exports = () => { return { changeCategorySelect: changeCategorySelect, - changeTMM: changeTMM + changeTMM: changeTMM, + loadMetadata: loadMetadata, + metadataCompleted: metadataCompleted, + populateMetadata: populateMetadata, + setWindowId: setWindowId, + submitForm: submitForm }; }; let categories = {}; let defaultSavePath = ""; + let windowId = ""; + let source = ""; const getCategories = () => { fetch("api/v2/torrents/categories", { @@ -131,6 +138,100 @@ window.qBittorrent.Download ??= (() => { } }; + let loadMetadataTimer = -1; + const loadMetadata = (sourceUrl = undefined) => { + if (sourceUrl !== undefined) + source = sourceUrl; + + fetch("api/v2/torrents/fetchMetadata", { + method: "POST", + body: new URLSearchParams({ + source: source + }) + }) + .then(async (response) => { + if (!response.ok) { + metadataFailed(); + return; + } + + const data = await response.json(); + populateMetadata(data); + + if (response.status === 200) + metadataCompleted(); + else + loadMetadataTimer = loadMetadata.delay(1000); + }); + }; + + const metadataCompleted = (showDownloadButton = true) => { + clearTimeout(loadMetadataTimer); + loadMetadataTimer = -1; + + document.getElementById("metadataStatus").destroy(); + document.getElementById("loadingSpinner").style.display = "none"; + + if (showDownloadButton) + document.getElementById("saveTorrent").classList.remove("invisible"); + }; + + const metadataFailed = () => { + clearTimeout(loadMetadataTimer); + loadMetadataTimer = -1; + + document.getElementById("metadataStatus").textContent = "Metadata retrieval failed"; + document.getElementById("metadataStatus").classList.add("red"); + document.getElementById("loadingSpinner").style.display = "none"; + document.getElementById("errorIcon").classList.remove("invisible"); + }; + + const populateMetadata = (metadata) => { + // update window title + if (metadata.info?.name !== undefined) + window.parent.document.getElementById(`${windowId}_title`).textContent = metadata.info.name; + + const notAvailable = "QBT_TR(Not available)QBT_TR[CONTEXT=AddNewTorrentDialog]"; + const notApplicable = "QBT_TR(N/A)QBT_TR[CONTEXT=AddNewTorrentDialog]"; + document.getElementById("infoHashV1").textContent = (metadata.infohash_v1 === undefined) ? notAvailable : (metadata.infohash_v1 || notApplicable); + document.getElementById("infoHashV2").textContent = (metadata.infohash_v2 === undefined) ? notAvailable : (metadata.infohash_v2 || notApplicable); + + if (metadata.info?.length !== undefined) + document.getElementById("size").textContent = window.qBittorrent.Misc.friendlyUnit(metadata.info.length, false); + if ((metadata.creation_date !== undefined) && (metadata.creation_date > 1)) + document.getElementById("createdDate").textContent = new Date(metadata.creation_date * 1000).toLocaleString(); + if (metadata.comment !== undefined) + document.getElementById("comment").textContent = metadata.comment; + + if (metadata.info?.files !== undefined) { + const files = metadata.info.files.map((file, index) => ({ + index: index, + name: file.path, + size: file.length, + priority: window.qBittorrent.FileTree.FilePriority.Normal, + })); + window.qBittorrent.TorrentContent.updateData(files); + } + }; + + const setWindowId = (id) => { + windowId = id; + }; + + const submitForm = () => { + document.getElementById("startTorrentHidden").value = document.getElementById("startTorrent").checked ? "false" : "true"; + + document.getElementById("dlLimitHidden").value = Number(document.getElementById("dlLimitText").value) * 1024; + document.getElementById("upLimitHidden").value = Number(document.getElementById("upLimitText").value) * 1024; + + document.getElementById("filePriorities").value = [...document.getElementsByClassName("combo_priority")] + .filter((el) => !window.qBittorrent.TorrentContent.isFolder(Number(el.dataset.fileId))) + .sort((el1, el2) => Number(el1.dataset.fileId) - Number(el2.dataset.fileId)) + .map((el) => Number(el.value)); + + document.getElementById("loadingSpinner").style.display = "block"; + }; + window.addEventListener("load", async (event) => { // user might load this page directly (via browser magnet handler) // so wait for crucial initialization to complete @@ -142,4 +243,4 @@ window.qBittorrent.Download ??= (() => { return exports(); })(); -Object.freeze(window.qBittorrent.Download); +Object.freeze(window.qBittorrent.AddTorrent); diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 0ccc5fc49..4c17cb5b1 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -43,6 +43,8 @@ window.qBittorrent.Client ??= (() => { isShowSearchEngine: isShowSearchEngine, isShowRssReader: isShowRssReader, isShowLogViewer: isShowLogViewer, + createAddTorrentWindow: createAddTorrentWindow, + uploadTorrentFiles: uploadTorrentFiles, categoryMap: categoryMap, tagMap: tagMap }; @@ -128,6 +130,82 @@ window.qBittorrent.Client ??= (() => { return showingLogViewer; }; + const createAddTorrentWindow = (title, source, metadata = undefined) => { + const isFirefox = navigator.userAgent.includes("Firefox"); + const isSafari = navigator.userAgent.includes("AppleWebKit") && !navigator.userAgent.includes("Chrome"); + let height = 855; + if (isSafari) + height -= 40; + else if (isFirefox) + height -= 10; + + const staticId = "uploadPage"; + const id = `${staticId}-${encodeURIComponent(source)}`; + + const contentURL = new URL("addtorrent.html", window.location); + contentURL.search = new URLSearchParams({ + v: "${CACHEID}", + source: source, + fetch: metadata === undefined, + windowId: id + }); + + new MochaUI.Window({ + id: id, + icon: "images/qbittorrent-tray.svg", + title: title, + loadMethod: "iframe", + contentURL: contentURL.toString(), + scrollbars: true, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: loadWindowWidth(staticId, 980), + height: loadWindowHeight(staticId, height), + onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => { + saveWindowSize(staticId, id); + }), + onContentLoaded: () => { + if (metadata !== undefined) + document.getElementById(`${id}_iframe`).contentWindow.postMessage(metadata, window.origin); + } + }); + }; + + const uploadTorrentFiles = (files) => { + const fileNames = []; + const formData = new FormData(); + for (const file of files) { + fileNames.push(file.name); + formData.append("file", file); + } + + fetch("api/v2/torrents/parseMetadata", { + method: "POST", + body: formData + }) + .then(async (response) => { + if (!response.ok) { + alert(await response.text()); + return; + } + + const json = await response.json(); + for (const fileName of fileNames) { + let title = fileName; + const metadata = json[fileName]; + if (metadata !== undefined) + title = metadata.name; + + const hash = metadata.infohash_v2 || metadata.infohash_v1; + createAddTorrentWindow(title, hash, metadata); + } + }) + .catch((error) => { + alert(`QBT_TR(Unable to parse response.)QBT_TR[CONTEXT=HttpServer] ${error.toString()}`); + }); + }; + return exports(); })(); Object.freeze(window.qBittorrent.Client); @@ -1687,32 +1765,11 @@ window.addEventListener("DOMContentLoaded", (event) => { // can't handle folder due to cannot put the filelist (from dropped folder) // to `files` field for (const item of ev.dataTransfer.items) { - if (item.webkitGetAsEntry().isDirectory) + if ((item.kind !== "file") || (item.webkitGetAsEntry().isDirectory)) return; } - 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); - }), - onContentLoaded: () => { - const fileInput = document.getElementById(`${id}_iframe`).contentDocument.getElementById("fileselect"); - fileInput.files = droppedFiles; - } - }); + window.qBittorrent.Client.uploadTorrentFiles(droppedFiles); } const droppedText = ev.dataTransfer.getData("text"); @@ -1730,33 +1787,8 @@ window.addEventListener("DOMContentLoaded", (event) => { || ((str.length === 32) && !(/[^2-7A-Z]/i.test(str))); // v1 Base32 encoded SHA-1 info-hash }); - if (urls.length <= 0) - return; - - const id = "downloadPage"; - const contentURL = new URL("download.html", window.location); - contentURL.search = new URLSearchParams({ - v: "${CACHEID}", - urls: urls.map(encodeURIComponent).join("|") - }); - new MochaUI.Window({ - id: id, - icon: "images/qbittorrent-tray.svg", - 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), - onResize: window.qBittorrent.Misc.createDebounceHandler(500, (e) => { - saveWindowSize(id); - }) - }); + for (const url of urls) + qBittorrent.Client.createAddTorrentWindow(url, url); } }); }; diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index c10b0c02f..cadf2dfdb 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -44,6 +44,7 @@ window.qBittorrent.DynamicTable ??= (() => { TorrentTrackersTable: TorrentTrackersTable, BulkRenameTorrentFilesTable: BulkRenameTorrentFilesTable, TorrentFilesTable: TorrentFilesTable, + AddTorrentFilesTable: AddTorrentFilesTable, LogMessageTable: LogMessageTable, LogPeerTable: LogPeerTable, RssFeedTable: RssFeedTable, @@ -66,6 +67,9 @@ window.qBittorrent.DynamicTable ??= (() => { let DynamicTableHeaderContextMenuClass = null; + if (typeof LocalPreferences === "undefined") + window.LocalPreferences = new window.qBittorrent.LocalPreferences.LocalPreferences(); + class DynamicTable { setup(dynamicTableDivId, dynamicTableFixedHeaderDivId, contextMenu, useVirtualList = false) { this.dynamicTableDivId = dynamicTableDivId; @@ -2889,16 +2893,18 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["size"].updateTd = displaySize; // progress - this.columns["progress"].updateTd = function(td, row) { - const value = Number(this.getRowValue(row)); + if (this.columns["progress"] !== undefined) { + this.columns["progress"].updateTd = function(td, row) { + const value = Number(this.getRowValue(row)); - const progressBar = td.firstElementChild; - if (progressBar === null) - td.append(new window.qBittorrent.ProgressBar.ProgressBar(value)); - else - progressBar.setValue(value); - }; - this.columns["progress"].staticWidth = 100; + const progressBar = td.firstElementChild; + if (progressBar === null) + td.append(new window.qBittorrent.ProgressBar.ProgressBar(value)); + else + progressBar.setValue(value); + }; + this.columns["progress"].staticWidth = 100; + } // priority this.columns["priority"].updateTd = function(td, row) { @@ -2914,8 +2920,10 @@ window.qBittorrent.DynamicTable ??= (() => { this.columns["priority"].staticWidth = 140; // remaining, availability - this.columns["remaining"].updateTd = displaySize; - this.columns["availability"].updateTd = displayPercentage; + if (this.columns["remaining"] !== undefined) + this.columns["remaining"].updateTd = displaySize; + if (this.columns["availability"] !== undefined) + this.columns["availability"].updateTd = displayPercentage; } #sortNodesByColumn(root, column) { @@ -3070,6 +3078,17 @@ window.qBittorrent.DynamicTable ??= (() => { } } + class AddTorrentFilesTable extends TorrentFilesTable { + initColumns() { + this.newColumn("checked", "", "", 50, true); + this.newColumn("name", "", "QBT_TR(Name)QBT_TR[CONTEXT=TrackerListWidget]", 190, true); + this.newColumn("size", "", "QBT_TR(Total Size)QBT_TR[CONTEXT=TrackerListWidget]", 75, true); + this.newColumn("priority", "", "QBT_TR(Download Priority)QBT_TR[CONTEXT=TrackerListWidget]", 140, true); + + this.initColumnsFunctions(); + } + } + class RssFeedTable extends DynamicTable { initColumns() { this.newColumn("state_icon", "", "", 30, true); @@ -3248,7 +3267,8 @@ window.qBittorrent.DynamicTable ??= (() => { if (!tr) return; - showDownloadPage([this.getRow(tr.rowId).full_data.torrentURL]); + const { name, torrentURL } = this._this.rows.get(this.rowId).full_data; + qBittorrent.Client.createAddTorrentWindow(name, torrentURL); }); } updateRow(tr, fullUpdate) { diff --git a/src/webui/www/private/scripts/mocha-init.js b/src/webui/www/private/scripts/mocha-init.js index 976551f97..e6feb940d 100644 --- a/src/webui/www/private/scripts/mocha-init.js +++ b/src/webui/www/private/scripts/mocha-init.js @@ -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"; + } }; diff --git a/src/webui/www/private/scripts/search.js b/src/webui/www/private/scripts/search.js index 51915e62f..a8367255b 100644 --- a/src/webui/www/private/scripts/search.js +++ b/src/webui/www/private/scripts/search.js @@ -559,15 +559,10 @@ window.qBittorrent.Search ??= (() => { }; const downloadSearchTorrent = () => { - const urls = []; - for (const rowID of searchResultsTable.selectedRowsIds()) - urls.push(searchResultsTable.getRow(rowID).full_data.fileUrl); - - // only proceed if at least 1 row was selected - if (!urls.length) - return; - - showDownloadPage(urls); + for (const rowID of searchResultsTable.selectedRowsIds()) { + const { fileName, fileUrl } = searchResultsTable.getRow(rowID).full_data; + qBittorrent.Client.createAddTorrentWindow(fileName, fileUrl); + } }; const manageSearchPlugins = () => { diff --git a/src/webui/www/private/upload.html b/src/webui/www/private/upload.html index 3cf21f84e..e4a8f461f 100644 --- a/src/webui/www/private/upload.html +++ b/src/webui/www/private/upload.html @@ -3,13 +3,22 @@ - QBT_TR(Upload local torrent)QBT_TR[CONTEXT=HttpServer] + QBT_TR(Add torrent)QBT_TR[CONTEXT=AddNewTorrentDialog] + + + - + + + + + + + + + + + -
    -
    - -
    -
    - QBT_TR(Torrent options)QBT_TR[CONTEXT=AddNewTorrentDialog] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - -
    - - - -
    - - - -
    - - -
    - - -
    -
    - - - - -
    - - - -
    - - - -
    - - - -
    - - - -
    - - - -
    - - - -
    - - - - -
    - - - - -
    -
    - + + + +
    +
    +
    + QBT_TR(Save at)QBT_TR[CONTEXT=AddNewTorrentDialog] + + + + + + + + + + + +
    + + + +
    + + + +
    +
    +
    + QBT_TR(Torrent settings)QBT_TR[CONTEXT=AddNewTorrentDialog] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + +
    + + +
    +
    + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + + +
    + + + + +
    +
    + +
    + QBT_TR(Torrent information)QBT_TR[CONTEXT=AddNewTorrentDialog] + + + + + + + + + + + + + + + + + + + + + + + +
    + + + QBT_TR(Not available)QBT_TR[CONTEXT=AddNewTorrentDialog] +
    + + + QBT_TR(Not available)QBT_TR[CONTEXT=AddNewTorrentDialog] +
    + + + QBT_TR(Not available)QBT_TR[CONTEXT=AddNewTorrentDialog] +
    + + + QBT_TR(Not available)QBT_TR[CONTEXT=AddNewTorrentDialog] +
    + + + +
    +
    -
    +
    +
    + QBT_TR(Files)QBT_TR[CONTEXT=AddNewTorrentDialog] +
    + +
    +
    +
    + + + + +
    +
    +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + + Retrieving metadata + + +   +
    + +
    +
    -
    diff --git a/src/webui/www/private/views/rss.html b/src/webui/www/private/views/rss.html index 147bc1132..e6f8f3157 100644 --- a/src/webui/www/private/views/rss.html +++ b/src/webui/www/private/views/rss.html @@ -294,10 +294,10 @@ menu: "rssArticleMenu", actions: { Download: (el) => { - let dlString = ""; - for (const rowID of rssArticleTable.selectedRows) - dlString += `${rssArticleTable.getRow(rowID).full_data.torrentURL}\n`; - showDownloadPage([dlString]); + for (const rowID of rssArticleTable.selectedRows) { + const { name, torrentURL } = rssArticleTable.getRow(rowID).full_data; + window.qBittorrent.Client.createAddTorrentWindow(name, torrentURL); + } }, OpenNews: (el) => { for (const rowID of rssArticleTable.selectedRows) diff --git a/src/webui/www/webui.qrc b/src/webui/www/webui.qrc index baf2fe633..99a9110cf 100644 --- a/src/webui/www/webui.qrc +++ b/src/webui/www/webui.qrc @@ -392,11 +392,11 @@ private/rename_file.html private/rename_files.html private/rename_rule.html + private/scripts/addtorrent.js private/scripts/cache.js private/scripts/client.js private/scripts/color-scheme.js private/scripts/contextmenu.js - private/scripts/download.js private/scripts/dynamicTable.js private/scripts/file-tree.js private/scripts/filesystem.js