Merge pull request #9758 from Piccirello/new-search-webui-2

Add Search feature to WebUI
This commit is contained in:
Mike Tzou
2018-12-09 16:01:21 +08:00
committed by GitHub
11 changed files with 1379 additions and 64 deletions

View File

@@ -24,6 +24,8 @@
torrentsTable = new TorrentsTable();
torrentPeersTable = new TorrentPeersTable();
searchResultsTable = new SearchResultsTable();
searchPluginsTable = new SearchPluginsTable();
var updatePropertiesPanel = function() {};
@@ -36,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;
@@ -66,6 +69,10 @@ function genHash(string) {
return hash;
}
function getSyncMainDataInterval() {
return customSyncMainDataInterval ? customSyncMainDataInterval : serverSyncMainDataInterval;
}
window.addEvent('load', function() {
var saveColumnSizes = function() {
@@ -76,8 +83,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 +95,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 +210,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;
@@ -391,7 +426,7 @@ window.addEvent('load', function() {
torrentsTable.reselectRows(torrentsTableSelectedRows);
}
clearTimeout(syncMainDataTimer);
syncMainDataTimer = syncMainData.delay(syncMainDataTimerPeriod);
syncMainDataTimer = syncMainData.delay(getSyncMainDataInterval());
}
}).send();
};
@@ -472,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) {
@@ -543,8 +576,89 @@ 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");
customSyncMainDataInterval = null;
clearTimeout(syncMainDataTimer);
syncMainDataTimer = syncMainData.delay(100);
hideSearchTab();
};
var hideTransfersTab = function() {
$("filtersColumn").addClass("invisible");
$("filtersColumn_handle").addClass("invisible");
$("mainColumn").addClass("invisible");
MochaUI.Desktop.resizePanels();
};
var showSearchTab = function() {
$("searchTabColumn").removeClass("invisible");
customSyncMainDataInterval = 30000;
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 +772,12 @@ window.addEvent('load', function() {
column: 'mainColumn',
height: prop_h
});
if (showSearchEngine) {
addMainWindowTabsEventListener();
addSearchPanel();
}
});
function closeWindows() {
@@ -670,21 +790,18 @@ function setupCopyEventHandler() {
clipboardEvent = new ClipboardJS('.copyToClipboard', {
text: function(trigger) {
var textToCopy;
switch (trigger.id) {
case "CopyName":
textToCopy = copyNameFN();
break;
return copyNameFN();
case "CopyMagnetLink":
textToCopy = copyMagnetLinkFN();
break;
return copyMagnetLinkFN();
case "CopyHash":
textToCopy = copyHashFN();
break;
return copyHashFN();
case "copyDescriptionPageUrl":
return copySearchTorrentUrl();
default:
return "";
}
return textToCopy;
}
});
}
@@ -720,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');
@@ -774,7 +891,7 @@ var loadTorrentPeersData = function() {
torrentPeersTable.clear();
}
clearTimeout(loadTorrentPeersTimer);
loadTorrentPeersTimer = loadTorrentPeersData.delay(syncMainDataTimerPeriod);
loadTorrentPeersTimer = loadTorrentPeersData.delay(getSyncMainDataInterval());
}
}).send();
};

View File

@@ -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');
}
});

View File

@@ -66,39 +66,42 @@ var DynamicTable = new Class({
$(this.dynamicTableDivId).addEvent('scroll', scrollFn);
var resizeFn = function() {
var panel = $(this.dynamicTableDivId).getParent('.panel');
var h = panel.getBoundingClientRect().height - $(this.dynamicTableFixedHeaderDivId).getBoundingClientRect().height;
$(this.dynamicTableDivId).style.height = h + 'px';
// Workaround due to inaccurate calculation of elements heights by browser
var n = 2;
while (panel.clientWidth != panel.offsetWidth && n > 0) { // is panel vertical scrollbar visible ?
--n;
h -= 0.5;
// if the table exists within a panel
if ($(this.dynamicTableDivId).getParent('.panel')) {
var resizeFn = function() {
var panel = $(this.dynamicTableDivId).getParent('.panel');
var h = panel.getBoundingClientRect().height - $(this.dynamicTableFixedHeaderDivId).getBoundingClientRect().height;
$(this.dynamicTableDivId).style.height = h + 'px';
}
this.lastPanelHeight = panel.getBoundingClientRect().height;
}.bind(this);
// Workaround due to inaccurate calculation of elements heights by browser
$(this.dynamicTableDivId).getParent('.panel').addEvent('resize', resizeFn);
var n = 2;
this.lastPanelHeight = 0;
while (panel.clientWidth != panel.offsetWidth && n > 0) { // is panel vertical scrollbar visible ?
--n;
h -= 0.5;
$(this.dynamicTableDivId).style.height = h + 'px';
}
// Workaround. Resize event is called not always (for example it isn't called when browser window changes it's size)
var checkResizeFn = function() {
var panel = $(this.dynamicTableDivId).getParent('.panel');
if (this.lastPanelHeight != panel.getBoundingClientRect().height) {
this.lastPanelHeight = panel.getBoundingClientRect().height;
panel.fireEvent('resize');
}
}.bind(this);
}.bind(this);
setInterval(checkResizeFn, 500);
$(this.dynamicTableDivId).getParent('.panel').addEvent('resize', resizeFn);
this.lastPanelHeight = 0;
// Workaround. Resize event is called not always (for example it isn't called when browser window changes it's size)
var checkResizeFn = function() {
var panel = $(this.dynamicTableDivId).getParent('.panel');
if (this.lastPanelHeight != panel.getBoundingClientRect().height) {
this.lastPanelHeight = panel.getBoundingClientRect().height;
panel.fireEvent('resize');
}
}.bind(this);
setInterval(checkResizeFn, 500);
}
},
setupHeaderEvents: function() {
@@ -1381,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");
}
});
/*************************************************************/

View File

@@ -59,12 +59,20 @@ initializeWindows = function() {
addClickEvent('download', function(e) {
new Event(e).stop();
showDownloadPage();
});
showDownloadPage = function(urls) {
var id = 'downloadPage';
var contentUrl = 'download.html';
if (urls && urls.length)
contentUrl += '?urls=' + urls.join("|");
new MochaUI.Window({
id: id,
title: "QBT_TR(Download from URLs)QBT_TR[CONTEXT=downloadFromURL]",
loadMethod: 'iframe',
contentURL: 'download.html',
contentURL: contentUrl,
addClass: 'windowFrame', // fixes iframe scrolling on iOS Safari
scrollbars: true,
maximizable: false,
@@ -78,7 +86,7 @@ initializeWindows = function() {
}
});
updateMainData();
});
};
addClickEvent('preferences', function(e) {
new Event(e).stop();