From b2f454399c77859af09f53b72e17f09203f3bb02 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Wed, 27 Dec 2017 22:19:39 -0500 Subject: [PATCH 1/5] Add ability to pass urls to the webui download page --- src/webui/www/private/download.html | 13 +++++++++++++ src/webui/www/private/scripts/mocha-init.js | 12 ++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/webui/www/private/download.html b/src/webui/www/private/download.html index a2312ddc8..7cef3f000 100644 --- a/src/webui/www/private/download.html +++ b/src/webui/www/private/download.html @@ -7,7 +7,9 @@ + + @@ -71,6 +73,17 @@ diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index f99ac217b..230e242d0 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -24,6 +24,8 @@ torrentsTable = new TorrentsTable(); torrentPeersTable = new TorrentPeersTable(); +searchResultsTable = new SearchResultsTable(); +searchPluginsTable = new SearchPluginsTable(); var updatePropertiesPanel = function() {}; @@ -76,8 +78,9 @@ window.addEvent('load', function() { }; window.addEvent('resize', function() { - // Resizing might takes some time. - saveColumnSizes.delay(200); + // only save sizes if the columns are visible + if (!$("mainColumn").hasClass("invisible")) + saveColumnSizes.delay(200); // Resizing might takes some time. }); /*MochaUI.Desktop = new MochaUI.Desktop(); @@ -87,22 +90,40 @@ window.addEvent('load', function() { });*/ MochaUI.Desktop.initialize(); - var filt_w = localStorage.getItem('filters_width'); - if ($defined(filt_w)) - filt_w = filt_w.toInt(); - else - filt_w = 120; - new MochaUI.Column({ - id: 'filtersColumn', - placement: 'left', - onResize: saveColumnSizes, - width: filt_w, - resizeLimit: [1, 300] - }); - new MochaUI.Column({ - id: 'mainColumn', - placement: 'main' - }); + var buildTransfersTab = function() { + var filt_w = localStorage.getItem('filters_width'); + if ($defined(filt_w)) + filt_w = filt_w.toInt(); + else + filt_w = 120; + new MochaUI.Column({ + id: 'filtersColumn', + placement: 'left', + onResize: saveColumnSizes, + width: filt_w, + resizeLimit: [1, 300] + }); + + new MochaUI.Column({ + id: 'mainColumn', + placement: 'main' + }); + }; + + var buildSearchTab = function() { + new MochaUI.Column({ + id: 'searchTabColumn', + placement: 'main', + width: null + }); + + // start off hidden + $("searchTabColumn").addClass("invisible"); + }; + + buildTransfersTab(); + buildSearchTab(); + MochaUI.initializeTabs('mainWindowTabsList'); setCategoryFilter = function(hash) { selected_category = hash; @@ -184,6 +205,15 @@ window.addEvent('load', function() { $('speedInBrowserTitleBarLink').firstChild.style.opacity = '0'; // After showing/hiding the toolbar + status bar + var showSearchEngine = localStorage.getItem('show_search_engine') === "true"; + if (!showSearchEngine) { + // uncheck menu option + $('showSearchEngineLink').firstChild.style.opacity = '0'; + // hide tabs + $('mainWindowTabs').addClass('invisible'); + } + + // After Show Top Toolbar MochaUI.Desktop.setDesktopSize(); var syncMainDataLastResponseId = 0; @@ -543,8 +573,83 @@ window.addEvent('load', function() { processServerState(); }); + $('showSearchEngineLink').addEvent('click', function(e) { + showSearchEngine = !showSearchEngine; + localStorage.setItem('show_search_engine', showSearchEngine.toString()); + if (showSearchEngine) { + $('showSearchEngineLink').firstChild.style.opacity = '1'; + $('mainWindowTabs').removeClass('invisible'); + + addMainWindowTabsEventListener(); + if (!MochaUI.Panels.instances.SearchPanel) + addSearchPanel(); + } + else { + $('showSearchEngineLink').firstChild.style.opacity = '0'; + $('mainWindowTabs').addClass('invisible'); + $("transfersTabLink").click(); + + removeMainWindowTabsEventListener(); + } + }); + $('StatisticsLink').addEvent('click', StatisticsLinkFN); + // main window tabs + + var showTransfersTab = function() { + $("filtersColumn").removeClass("invisible"); + $("filtersColumn_handle").removeClass("invisible"); + $("mainColumn").removeClass("invisible"); + hideSearchTab(); + }; + + var hideTransfersTab = function() { + $("filtersColumn").addClass("invisible"); + $("filtersColumn_handle").addClass("invisible"); + $("mainColumn").addClass("invisible"); + MochaUI.Desktop.resizePanels(); + }; + + var showSearchTab = function() { + $("searchTabColumn").removeClass("invisible"); + hideTransfersTab(); + }; + + var hideSearchTab = function() { + $("searchTabColumn").addClass("invisible"); + MochaUI.Desktop.resizePanels(); + }; + + var addMainWindowTabsEventListener = function() { + $('transfersTabLink').addEvent('click', showTransfersTab); + $('searchTabLink').addEvent('click', showSearchTab); + }; + + var removeMainWindowTabsEventListener = function() { + $('transfersTabLink').removeEvent('click', showTransfersTab); + $('searchTabLink').removeEvent('click', showSearchTab); + }; + + var addSearchPanel = function() { + new MochaUI.Panel({ + id : 'SearchPanel', + title : 'Search', + header : false, + padding : { + top : 0, + right : 0, + bottom : 0, + left : 0 + }, + loadMethod : 'xhr', + contentURL : 'search.html', + content: '', + column : 'searchTabColumn', + height : null + }); + }; + new MochaUI.Panel({ id: 'transferList', title: 'Panel', @@ -658,6 +763,12 @@ window.addEvent('load', function() { column: 'mainColumn', height: prop_h }); + + if (showSearchEngine) { + addMainWindowTabsEventListener(); + addSearchPanel(); + } + }); function closeWindows() { @@ -677,6 +788,8 @@ function setupCopyEventHandler() { return copyMagnetLinkFN(); case "CopyHash": return copyHashFN(); + case "copyDescriptionPageUrl": + return copySearchTorrentUrl(); default: return ""; } diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js index 2c26dc037..b41c9e538 100644 --- a/src/webui/www/private/scripts/contextmenu.js +++ b/src/webui/www/private/scripts/contextmenu.js @@ -400,3 +400,21 @@ var CategoriesFilterContextMenu = new Class({ } } }); + +var SearchPluginsTableContextMenu = new Class({ + Extends: ContextMenu, + + updateMenuItems: function () { + var enabledColumnIndex = function(text) { + var columns = $("searchPluginsTableFixedHeaderRow").getChildren("th"); + for (var i = 0; i < columns.length; ++i) + if (columns[i].get("html") === "Enabled") + return i; + }; + + this.showItem('Enabled'); + this.setItemChecked('Enabled', this.options.element.getChildren("td")[enabledColumnIndex()].get("html") === "Yes"); + + this.showItem('Uninstall'); + } +}); diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index ae5121569..13cc1e724 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -1384,4 +1384,165 @@ var TorrentPeersTable = new Class({ } }); +var SearchResultsTable = new Class({ + Extends: DynamicTable, + + initColumns: function () { + 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); + this.newColumn('nbLeechers', '', 'QBT_TR(Leechers)QBT_TR[CONTEXT=SearchResultsTable]', 100, true); + this.newColumn('siteUrl', '', 'QBT_TR(Search engine)QBT_TR[CONTEXT=SearchResultsTable]', 250, true); + + this.initColumnsFunctions(); + }, + + initColumnsFunctions: function () { + var displayText = function (td, row) { + var value = this.getRowValue(row); + td.set('html', escapeHtml(value)); + } + var displaySize = function(td, row) { + var size = this.getRowValue(row); + td.set('html', friendlyUnit(size, false)); + } + var displayNum = function (td, row) { + var value = escapeHtml(this.getRowValue(row)); + td.set('html', (value === "-1") ? "Unknown" : value); + } + + this.columns['fileName'].updateTd = displayText; + this.columns['fileSize'].updateTd = displaySize; + this.columns['nbSeeders'].updateTd = displayNum; + this.columns['nbLeechers'].updateTd = displayNum; + this.columns['siteUrl'].updateTd = displayText; + }, + + getFilteredAndSortedRows: function () { + var containsAll = function(text, searchTerms) { + text = text.toLowerCase(); + for (var i = 0; i < searchTerms.length; ++i) { + if (text.indexOf(searchTerms[i].toLowerCase()) === -1) + return false; + } + + return true; + }; + + var getSizeFilters = function() { + var minSize = (searchSizeFilter.min > 0.00) ? (searchSizeFilter.min * Math.pow(1024, searchSizeFilter.minUnit)) : 0.00; + var maxSize = (searchSizeFilter.max > 0.00) ? (searchSizeFilter.max * Math.pow(1024, searchSizeFilter.maxUnit)) : 0.00; + + if ((minSize > maxSize) && (maxSize > 0.00)) { + var tmp = minSize; + minSize = maxSize; + maxSize = tmp; + } + + return { + min: minSize, + max: maxSize + } + }; + + var getSeedsFilters = function() { + var minSeeds = (searchSeedsFilter.min > 0) ? searchSeedsFilter.min : 0; + var maxSeeds = (searchSeedsFilter.max > 0) ? searchSeedsFilter.max : 0; + + if ((minSeeds > maxSeeds) && (maxSeeds > 0)) { + var tmp = minSeeds; + minSeeds = maxSeeds; + maxSeeds = tmp; + } + + return { + min: minSeeds, + max: maxSeeds + } + } + + var filteredRows = []; + var rows = this.rows.getValues(); + var searchTerms = searchPattern.toLowerCase().split(" "); + var filterTerms = searchFilterPattern.toLowerCase().split(" "); + var sizeFilters = getSizeFilters(); + var seedsFilters = getSeedsFilters(); + var searchInTorrentName = $('searchInTorrentName').get('value') === "names"; + + if (searchInTorrentName || filterTerms.length || (searchSizeFilter.min > 0.00) || (searchSizeFilter.max > 0.00)) { + for (var i = 0; i < rows.length; ++i) { + var row = rows[i]; + + if (searchInTorrentName && !containsAll(row.full_data.fileName, searchTerms)) continue; + if (filterTerms.length && !containsAll(row.full_data.fileName, filterTerms)) continue; + if ((sizeFilters.min > 0.00) && (row.full_data.fileSize < sizeFilters.min)) continue; + if ((sizeFilters.max > 0.00) && (row.full_data.fileSize > sizeFilters.max)) continue; + if ((seedsFilters.min > 0) && (row.full_data.nbSeeders < seedsFilters.min)) continue; + if ((seedsFilters.max > 0) && (row.full_data.nbSeeders > seedsFilters.max)) continue; + + filteredRows.push(row); + } + } + else { + filteredRows = rows; + } + + filteredRows.sort(function (row1, row2) { + var column = this.columns[this.sortedColumn]; + var res = column.compareRows(row1, row2); + if (this.reverseSort == '0') + return res; + else + return -res; + }.bind(this)); + + return filteredRows; + }, + + setupTr: function (tr) { + tr.addClass("searchTableRow"); + } + }); + +var SearchPluginsTable = new Class({ + Extends: DynamicTable, + + initColumns: function () { + 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 () { + var displayText = function (td, row) { + var value = this.getRowValue(row); + td.set('html', escapeHtml(value)); + } + + this.columns['fullName'].updateTd = displayText; + this.columns['version'].updateTd = displayText; + this.columns['url'].updateTd = displayText; + this.columns['enabled'].updateTd = function(td, row) { + var value = this.getRowValue(row); + if (value) { + td.set('html', "Yes"); + td.getParent("tr").addClass("green"); + td.getParent("tr").removeClass("red"); + } + else { + td.set('html', "No"); + td.getParent("tr").addClass("red"); + td.getParent("tr").removeClass("green"); + } + }; + }, + + setupTr: function (tr) { + tr.addClass("searchPluginsTableRow"); + } + }); + /*************************************************************/ diff --git a/src/webui/www/private/search.html b/src/webui/www/private/search.html new file mode 100644 index 000000000..c7921e7f3 --- /dev/null +++ b/src/webui/www/private/search.html @@ -0,0 +1,644 @@ + + +
+
+
+ + + + +
+
+ +
+ + + + + + +
+ There aren't any search plugins installed.
Click the "Search plugins..." button at the bottom right of the window to install some. +
+ +
+ +
+ + + QBT_TR(Results (showing)QBT_TR[CONTEXT=SearchEngineWidget] 0 QBT_TR(out of)QBT_TR[CONTEXT=SearchEngineWidget] 0): + +
+ + + + QBT_TR(Seeds:)QBT_TR[CONTEXT=SearchEngineWidget] + + to + + + QBT_TR(Size:)QBT_TR[CONTEXT=SearchEngineWidget] + + + to + + +
+
+ +
+
+ + + + +
+
+
+ + + + + +
+
+
+ +
+ + + + +
+
+ + diff --git a/src/webui/www/private/searchplugins.html b/src/webui/www/private/searchplugins.html new file mode 100644 index 000000000..2c93410cd --- /dev/null +++ b/src/webui/www/private/searchplugins.html @@ -0,0 +1,219 @@ + + +
+

QBT_TR(Installed search plugins:)QBT_TR[CONTEXT=PluginSelectDlg]

+ +
+
+ + + + +
+
+
+ + + + + +
+
+
+ + QBT_TR(Warning: Be sure to comply with your country's copyright laws when downloading torrents from any of these search engines.)QBT_TR[CONTEXT=PluginSelectDlg] + QBT_TR(You can get new search engine plugins here:)QBT_TR[CONTEXT=PluginSelectDlg] http://plugins.qbittorrent.org +
+ + + +
+
+ + + + diff --git a/src/webui/www/webui.qrc b/src/webui/www/webui.qrc index 6fc7a9670..999fa25a4 100644 --- a/src/webui/www/webui.qrc +++ b/src/webui/www/webui.qrc @@ -13,12 +13,15 @@ private/downloadlimit.html private/filters.html private/index.html + private/installsearchplugin.html private/newcategory.html private/preferences.html private/preferences_content.html private/properties.html private/properties_content.html private/rename.html + private/search.html + private/searchplugins.html private/scripts/client.js private/scripts/contextmenu.js private/scripts/download.js From a8d5b146be252f8e78b0282613100aaa974dda26 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Mon, 3 Sep 2018 03:03:29 -0400 Subject: [PATCH 5/5] Fetch data less frequently when torrents tab isn't visible --- src/webui/www/private/scripts/client.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 230e242d0..1901a6296 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -38,7 +38,8 @@ var updateTorrentFilesData = function() {}; var updateMainData = function() {}; var alternativeSpeedLimits = false; var queueing_enabled = true; -var syncMainDataTimerPeriod = 1500; +var serverSyncMainDataInterval = 1500; +var customSyncMainDataInterval = null; var clipboardEvent; @@ -68,6 +69,10 @@ function genHash(string) { return hash; } +function getSyncMainDataInterval() { + return customSyncMainDataInterval ? customSyncMainDataInterval : serverSyncMainDataInterval; +} + window.addEvent('load', function() { var saveColumnSizes = function() { @@ -421,7 +426,7 @@ window.addEvent('load', function() { torrentsTable.reselectRows(torrentsTableSelectedRows); } clearTimeout(syncMainDataTimer); - syncMainDataTimer = syncMainData.delay(syncMainDataTimerPeriod); + syncMainDataTimer = syncMainData.delay(getSyncMainDataInterval()); } }).send(); }; @@ -502,9 +507,7 @@ window.addEvent('load', function() { updateAltSpeedIcon(alternativeSpeedLimits); } - syncMainDataTimerPeriod = serverState.refresh_interval; - if (syncMainDataTimerPeriod < 500) - syncMainDataTimerPeriod = 500; + serverSyncMainDataInterval = Math.max(serverState.refresh_interval, 500); }; var updateAltSpeedIcon = function(enabled) { @@ -601,6 +604,11 @@ window.addEvent('load', function() { $("filtersColumn").removeClass("invisible"); $("filtersColumn_handle").removeClass("invisible"); $("mainColumn").removeClass("invisible"); + + customSyncMainDataInterval = null; + clearTimeout(syncMainDataTimer); + syncMainDataTimer = syncMainData.delay(100); + hideSearchTab(); }; @@ -613,6 +621,7 @@ window.addEvent('load', function() { var showSearchTab = function() { $("searchTabColumn").removeClass("invisible"); + customSyncMainDataInterval = 30000; hideTransfersTab(); }; @@ -828,7 +837,7 @@ var loadTorrentPeersData = function() { syncTorrentPeersLastResponseId = 0; torrentPeersTable.clear(); clearTimeout(loadTorrentPeersTimer); - loadTorrentPeersTimer = loadTorrentPeersData.delay(syncMainDataTimerPeriod); + loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval()); return; } var url = new URI('api/v2/sync/torrentPeers'); @@ -882,7 +891,7 @@ var loadTorrentPeersData = function() { torrentPeersTable.clear(); } clearTimeout(loadTorrentPeersTimer); - loadTorrentPeersTimer = loadTorrentPeersData.delay(syncMainDataTimerPeriod); + loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval()); } }).send(); };