mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-01-03 06:02:29 -06:00
WebUI: Load properties tabs once
Don't reload HTML on tab change. Load the entire structure once and keep the unused bits hidden. Keep also the JS code separately, one file per tab. NOTE: tabs content is not loaded. This will be fixed in the next commit.
This commit is contained in:
@@ -311,11 +311,33 @@ window.addEvent('load', function () {
|
||||
bottom : 0,
|
||||
left : 0
|
||||
},
|
||||
contentURL : 'prop-general.html',
|
||||
contentURL : 'properties_content.html',
|
||||
require : {
|
||||
css : ['css/Tabs.css']
|
||||
css : ['css/Tabs.css'],
|
||||
js : ['scripts/prop-general.js', 'scripts/prop-trackers.js', 'scripts/prop-files.js'],
|
||||
},
|
||||
tabsURL : 'properties.html',
|
||||
tabsOnload : function() {
|
||||
MochaUI.initializeTabs('propertiesTabs');
|
||||
|
||||
$('PropGeneralLink').addEvent('click', function(e){
|
||||
$('prop_general').removeClass("invisible");
|
||||
$('prop_trackers').addClass("invisible");
|
||||
$('prop_files').addClass("invisible");
|
||||
});
|
||||
|
||||
$('PropTrackersLink').addEvent('click', function(e){
|
||||
$('prop_trackers').removeClass("invisible");
|
||||
$('prop_general').addClass("invisible");
|
||||
$('prop_files').addClass("invisible");
|
||||
});
|
||||
|
||||
$('PropFilesLink').addEvent('click', function(e){
|
||||
$('prop_files').removeClass("invisible");
|
||||
$('prop_general').addClass("invisible");
|
||||
$('prop_trackers').addClass("invisible");
|
||||
});
|
||||
},
|
||||
column : 'mainColumn',
|
||||
height : prop_h
|
||||
});
|
||||
|
||||
348
src/webui/www/public/scripts/prop-files.js
Normal file
348
src/webui/www/public/scripts/prop-files.js
Normal file
@@ -0,0 +1,348 @@
|
||||
var waitingTorrentFiles = false;
|
||||
var is_seed = true;
|
||||
var current_hash = "";
|
||||
|
||||
if (!(Browser.name == "ie" && Browser.version < 9)) {
|
||||
$("all_files_cb").removeClass("tristate");
|
||||
$("all_files_cb").removeClass("partial");
|
||||
$("all_files_cb").removeClass("checked");
|
||||
$("tristate_cb").style.display = "inline";
|
||||
}
|
||||
|
||||
var setCBState = function(state) {
|
||||
if (Browser.name == "ie" && Browser.version < 9) {
|
||||
if (state == "partial") {
|
||||
if (!$("all_files_cb").hasClass("partial")) {
|
||||
$("all_files_cb").removeClass("checked");
|
||||
$("all_files_cb").addClass("partial");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (state == "checked") {
|
||||
if (!$("all_files_cb").hasClass("checked")) {
|
||||
$("all_files_cb").removeClass("partial");
|
||||
$("all_files_cb").addClass("checked");
|
||||
}
|
||||
return;
|
||||
}
|
||||
$("all_files_cb").removeClass("partial");
|
||||
$("all_files_cb").removeClass("checked");
|
||||
}
|
||||
else {
|
||||
if (state == "partial") {
|
||||
$("tristate_cb").indeterminate = true;
|
||||
}
|
||||
else if (state == "checked") {
|
||||
$("tristate_cb").indeterminate = false;
|
||||
$("tristate_cb").checked = true;
|
||||
}
|
||||
else {
|
||||
$("tristate_cb").indeterminate = false;
|
||||
$("tristate_cb").checked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var switchCBState = function() {
|
||||
// Uncheck
|
||||
if ($("all_files_cb").hasClass("partial")) {
|
||||
$("all_files_cb").removeClass("partial");
|
||||
// Uncheck all checkboxes
|
||||
$$('input.DownloadedCB').each(function(item, index) {
|
||||
item.erase("checked");
|
||||
setFilePriority(index, 0);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if ($("all_files_cb").hasClass("checked")) {
|
||||
$("all_files_cb").removeClass("checked");
|
||||
// Uncheck all checkboxes
|
||||
$$('input.DownloadedCB').each(function(item, index) {
|
||||
item.erase("checked");
|
||||
setFilePriority(index, 0);
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Check
|
||||
$("all_files_cb").addClass("checked");
|
||||
// Check all checkboxes
|
||||
$$('input.DownloadedCB').each(function(item, index) {
|
||||
item.set("checked", "checked");
|
||||
setFilePriority(index, 1);
|
||||
});
|
||||
}
|
||||
|
||||
var allCBChecked = function() {
|
||||
var CBs = $$('input.DownloadedCB');
|
||||
for (var i = 0; i < CBs.length; i += 1) {
|
||||
var item = CBs[i];
|
||||
if (!$defined(item.get('checked')) || !item.get('checked'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var allCBUnchecked = function() {
|
||||
var CBs = $$('input.DownloadedCB');
|
||||
for (var i = 0; i < CBs.length; i += 1) {
|
||||
var item = CBs[i];
|
||||
if ($defined(item.get('checked')) && item.get('checked'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var setFilePriority = function(id, priority) {
|
||||
if (current_hash == "") return;
|
||||
new Request({
|
||||
url: 'command/setFilePrio',
|
||||
method: 'post',
|
||||
data: {
|
||||
'hash': current_hash,
|
||||
'id': id,
|
||||
'priority': priority
|
||||
}
|
||||
}).send();
|
||||
// Display or add combobox
|
||||
if (priority > 0) {
|
||||
$('comboPrio' + id).set("value", 1);
|
||||
$('comboPrio' + id).removeClass("invisible");
|
||||
}
|
||||
else {
|
||||
$('comboPrio' + id).addClass("invisible");
|
||||
}
|
||||
}
|
||||
|
||||
var createDownloadedCB = function(id, downloaded) {
|
||||
var CB = new Element('input');
|
||||
CB.set('type', 'checkbox');
|
||||
if (downloaded)
|
||||
CB.set('checked', 'checked');
|
||||
CB.set('id', 'cbPrio' + id);
|
||||
CB.set('class', 'DownloadedCB');
|
||||
CB.addEvent('change', function(e) {
|
||||
var checked = 0;
|
||||
if ($defined($('cbPrio' + id).get('checked')) && $('cbPrio' + id).get('checked'))
|
||||
checked = 1;
|
||||
setFilePriority(id, checked);
|
||||
if (allCBChecked()) {
|
||||
setCBState("checked");
|
||||
}
|
||||
else {
|
||||
if (allCBUnchecked()) {
|
||||
setCBState("unchecked");
|
||||
}
|
||||
else {
|
||||
setCBState("partial");
|
||||
}
|
||||
}
|
||||
});
|
||||
return CB;
|
||||
}
|
||||
|
||||
var createPriorityCombo = function(id, selected_prio) {
|
||||
var select = new Element('select');
|
||||
select.set('id', 'comboPrio' + id);
|
||||
select.addEvent('change', function(e) {
|
||||
var new_prio = $('comboPrio' + id).get('value');
|
||||
setFilePriority(id, new_prio);
|
||||
});
|
||||
var opt = new Element("option");
|
||||
opt.set('value', '1')
|
||||
opt.set('html', "_(Normal)");
|
||||
if (selected_prio <= 1)
|
||||
opt.setAttribute('selected', '');
|
||||
opt.injectInside(select);
|
||||
opt = new Element("option");
|
||||
opt.set('value', '2')
|
||||
opt.set('html', "_(High)");
|
||||
if (selected_prio == 2)
|
||||
opt.setAttribute('selected', '');
|
||||
opt.injectInside(select);
|
||||
opt = new Element("option");
|
||||
opt.set('value', '7')
|
||||
opt.set('html', "_(Maximum)");
|
||||
if (selected_prio == 7)
|
||||
opt.setAttribute('selected', '');
|
||||
opt.injectInside(select);
|
||||
if (is_seed || selected_prio < 1) {
|
||||
select.addClass("invisible");
|
||||
}
|
||||
else {
|
||||
select.removeClass("invisible");
|
||||
}
|
||||
select.addClass("combo_priority");
|
||||
return select;
|
||||
}
|
||||
|
||||
var filesDynTable = new Class({
|
||||
|
||||
initialize: function() {},
|
||||
|
||||
setup: function(table) {
|
||||
this.table = $(table);
|
||||
this.rows = new Hash();
|
||||
},
|
||||
|
||||
removeRow: function(id) {
|
||||
if (this.rows.has(id)) {
|
||||
var tr = this.rows.get(id);
|
||||
tr.dispose();
|
||||
this.rows.erase(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
removeAllRows: function() {
|
||||
this.rows.each(function(tr, id) {
|
||||
this.removeRow(id);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
updateRow: function(tr, row, id) {
|
||||
var tds = tr.getElements('td');
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
if (i == 3) {
|
||||
$('pbf_' + id).setValue(row[i].toFloat());
|
||||
}
|
||||
else {
|
||||
if (i == 0) {
|
||||
if (row[i] > 0)
|
||||
tds[i].getChildren('input')[0].set('checked', 'checked');
|
||||
else
|
||||
tds[i].getChildren('input')[0].removeProperty('checked')
|
||||
}
|
||||
else {
|
||||
if (i == 4) {
|
||||
if (!is_seed && row[i] > 0) {
|
||||
tds[i].getChildren('select').set('value', row[i]);
|
||||
$('comboPrio' + id).removeClass("invisible");
|
||||
}
|
||||
else {
|
||||
if (!$('comboPrio' + id).hasClass("invisible"))
|
||||
$('comboPrio' + id).addClass("invisible");
|
||||
}
|
||||
}
|
||||
else {
|
||||
tds[i].set('html', row[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
insertRow: function(id, row) {
|
||||
if (this.rows.has(id)) {
|
||||
var tr = this.rows.get(id);
|
||||
this.updateRow(tr, row, id);
|
||||
return;
|
||||
}
|
||||
//this.removeRow(id);
|
||||
var tr = new Element('tr');
|
||||
this.rows.set(id, tr);
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
var td = new Element('td');
|
||||
if (i == 3) {
|
||||
td.adopt(new ProgressBar(row[i].toFloat(), {
|
||||
'id': 'pbf_' + id,
|
||||
'width': 80
|
||||
}));
|
||||
}
|
||||
else {
|
||||
if (i == 0) {
|
||||
var tree_img = new Element('img', {
|
||||
src: 'images/L.gif',
|
||||
style: 'margin-bottom: -2px'
|
||||
});
|
||||
td.adopt(tree_img, createDownloadedCB(id, row[i]));
|
||||
}
|
||||
else {
|
||||
if (i == 4) {
|
||||
td.adopt(createPriorityCombo(id, row[i]));
|
||||
}
|
||||
else {
|
||||
td.set('html', row[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
td.injectInside(tr);
|
||||
}
|
||||
tr.injectInside(this.table);
|
||||
},
|
||||
});
|
||||
|
||||
var loadTorrentFilesData = function() {
|
||||
if ($('prop_files').hasClass('invisible')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
var new_hash = myTable.getCurrentTorrentHash();
|
||||
if (new_hash == "") {
|
||||
fTable.removeAllRows();
|
||||
loadTorrentFilesData.delay(1500);
|
||||
return;
|
||||
}
|
||||
if (new_hash != current_hash) {
|
||||
fTable.removeAllRows();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
var url = 'json/propertiesFiles/' + current_hash;
|
||||
if (!waitingTorrentFiles) {
|
||||
waitingTorrentFiles = true;
|
||||
var request = new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', '_(qBittorrent client is not reachable)');
|
||||
waitingTorrentFiles = false;
|
||||
loadTorrentFilesData.delay(2000);
|
||||
},
|
||||
onSuccess: function(files) {
|
||||
$('error_div').set('html', '');
|
||||
if (files) {
|
||||
// Update Trackers data
|
||||
var i = 0;
|
||||
files.each(function(file) {
|
||||
if (i == 0) {
|
||||
is_seed = file.is_seed;
|
||||
}
|
||||
var row = new Array();
|
||||
row.length = 4;
|
||||
row[0] = file.priority;
|
||||
row[1] = file.name;
|
||||
row[2] = friendlyUnit(file.size, false);
|
||||
row[3] = (file.progress * 100).round(1);
|
||||
if (row[3] == 100.0 && file.progress < 1.0)
|
||||
row[3] = 99.9
|
||||
row[4] = file.priority;
|
||||
fTable.insertRow(i, row);
|
||||
i++;
|
||||
}.bind(this));
|
||||
// Set global CB state
|
||||
if (allCBChecked()) {
|
||||
setCBState("checked");
|
||||
}
|
||||
else {
|
||||
if (allCBUnchecked()) {
|
||||
setCBState("unchecked");
|
||||
}
|
||||
else {
|
||||
setCBState("partial");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fTable.removeAllRows();
|
||||
}
|
||||
waitingTorrentFiles = false;
|
||||
loadTorrentFilesData.delay(1500);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
}
|
||||
fTable = new filesDynTable();
|
||||
fTable.setup($('filesTable'));
|
||||
84
src/webui/www/public/scripts/prop-general.js
Normal file
84
src/webui/www/public/scripts/prop-general.js
Normal file
@@ -0,0 +1,84 @@
|
||||
var waiting = false;
|
||||
|
||||
var clearData = function() {
|
||||
$('torrent_hash').set('html', '');
|
||||
$('save_path').set('html', '');
|
||||
$('creation_date').set('html', '');
|
||||
$('piece_size').set('html', '');
|
||||
$('comment').set('html', '');
|
||||
$('total_uploaded').set('html', '');
|
||||
$('total_downloaded').set('html', '');
|
||||
$('total_wasted').set('html', '');
|
||||
$('up_limit').set('html', '');
|
||||
$('dl_limit').set('html', '');
|
||||
$('time_elapsed').set('html', '');
|
||||
$('nb_connections').set('html', '');
|
||||
$('share_ratio').set('html', '');
|
||||
}
|
||||
|
||||
var loadData = function() {
|
||||
if ($('prop_general').hasClass('invisible')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
var current_hash = myTable.getCurrentTorrentHash();
|
||||
if (current_hash == "") {
|
||||
clearData();
|
||||
loadData.delay(1500);
|
||||
return;
|
||||
}
|
||||
// Display hash
|
||||
$('torrent_hash').set('html', current_hash);
|
||||
var url = 'json/propertiesGeneral/' + current_hash;
|
||||
if (!waiting) {
|
||||
waiting = true;
|
||||
var request = new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', '_(qBittorrent client is not reachable)');
|
||||
waiting = false;
|
||||
loadData.delay(2000);
|
||||
},
|
||||
onSuccess: function(data) {
|
||||
$('error_div').set('html', '');
|
||||
if (data) {
|
||||
var temp;
|
||||
// Update Torrent data
|
||||
$('save_path').set('html', data.save_path);
|
||||
temp = data.creation_date;
|
||||
var timestamp = "_(Unknown)";
|
||||
if (temp != -1)
|
||||
timestamp = new Date(data.creation_date * 1000).toISOString();
|
||||
$('creation_date').set('html', timestamp);
|
||||
$('piece_size').set('html', friendlyUnit(data.piece_size));
|
||||
$('comment').set('html', data.comment);
|
||||
$('total_uploaded').set('html', friendlyUnit(data.total_uploaded) +
|
||||
" (" + friendlyUnit(data.total_uploaded_session) +
|
||||
" (" + "_(this session)" + ")");
|
||||
$('total_downloaded').set('html', friendlyUnit(data.total_downloaded) +
|
||||
" (" + friendlyUnit(data.total_downloaded_session) +
|
||||
" (" + "_(this session)" + ")");
|
||||
$('total_wasted').set('html', data.total_wasted);
|
||||
temp = data.up_limit;
|
||||
$('up_limit').set('html', temp == -1 ? "∞" : temp);
|
||||
temp = data.dl_limit;
|
||||
$('dl_limit').set('html', temp == -1 ? "∞" : temp);
|
||||
temp = friendlyDuration(status.active_time);
|
||||
if (status.is_seed)
|
||||
temp += " (" + "_(Seeded for %1)".replace("%1", status.seeding_time) + ")";
|
||||
$('time_elapsed').set('html', temp);
|
||||
temp = data.nb_connections + " (" + "_(%1 max)".replace("%1", status.nb_connections_limit) + ")";
|
||||
$('nb_connections').set('html', temp);
|
||||
$('share_ratio').set('html', data.share_ratio.toFixed(2));
|
||||
}
|
||||
else {
|
||||
clearData();
|
||||
}
|
||||
waiting = false;
|
||||
loadData.delay(1500);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
127
src/webui/www/public/scripts/prop-trackers.js
Normal file
127
src/webui/www/public/scripts/prop-trackers.js
Normal file
@@ -0,0 +1,127 @@
|
||||
var trackersDynTable = new Class({
|
||||
|
||||
initialize: function() {},
|
||||
|
||||
setup: function(table) {
|
||||
this.table = $(table);
|
||||
this.rows = new Hash();
|
||||
},
|
||||
|
||||
removeRow: function(url) {
|
||||
if (this.rows.has(url)) {
|
||||
var tr = this.rows.get(url);
|
||||
tr.dispose();
|
||||
this.rows.erase(url);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
removeAllRows: function() {
|
||||
this.rows.each(function(tr, url) {
|
||||
this.removeRow(url);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
updateRow: function(tr, row) {
|
||||
var tds = tr.getElements('td');
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
tds[i].set('html', row[i]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
insertRow: function(row) {
|
||||
var url = row[0];
|
||||
if (this.rows.has(url)) {
|
||||
var tr = this.rows.get(url);
|
||||
this.updateRow(tr, row);
|
||||
return;
|
||||
}
|
||||
//this.removeRow(id);
|
||||
var tr = new Element('tr');
|
||||
this.rows.set(url, tr);
|
||||
for (var i = 0; i < row.length; i++) {
|
||||
var td = new Element('td');
|
||||
td.set('html', row[i]);
|
||||
td.injectInside(tr);
|
||||
}
|
||||
tr.injectInside(this.table);
|
||||
},
|
||||
});
|
||||
|
||||
var waitingTrackers = false;
|
||||
var current_hash = "";
|
||||
|
||||
var loadTrackersData = function() {
|
||||
if ($('prop_trackers').hasClass('invisible')) {
|
||||
// Tab changed, don't do anything
|
||||
return;
|
||||
}
|
||||
var new_hash = myTable.getCurrentTorrentHash();
|
||||
if (new_hash == "") {
|
||||
tTable.removeAllRows();
|
||||
loadTrackersData.delay(1500);
|
||||
return;
|
||||
}
|
||||
if (new_hash != current_hash) {
|
||||
tTable.removeAllRows();
|
||||
current_hash = new_hash;
|
||||
}
|
||||
var url = 'json/propertiesTrackers/' + current_hash;
|
||||
if (!waitingTrackers) {
|
||||
waitingTrackers = true;
|
||||
var request = new Request.JSON({
|
||||
url: url,
|
||||
noCache: true,
|
||||
method: 'get',
|
||||
onFailure: function() {
|
||||
$('error_div').set('html', '_(qBittorrent client is not reachable)');
|
||||
waitingTrackers = false;
|
||||
loadTrackersData.delay(2000);
|
||||
},
|
||||
onSuccess: function(trackers) {
|
||||
$('error_div').set('html', '');
|
||||
if (trackers) {
|
||||
// Update Trackers data
|
||||
trackers.each(function(tracker) {
|
||||
var row = new Array();
|
||||
row.length = 4;
|
||||
row[0] = tracker.url;
|
||||
row[1] = tracker.status;
|
||||
row[2] = tracker.num_peers;
|
||||
row[3] = tracker.msg;
|
||||
tTable.insertRow(row);
|
||||
});
|
||||
}
|
||||
else {
|
||||
tTable.removeAllRows();
|
||||
}
|
||||
waitingTrackers = false;
|
||||
loadTrackersData.delay(1500);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
}
|
||||
tTable = new trackersDynTable();
|
||||
tTable.setup($('trackersTable'));
|
||||
|
||||
// Add trackers code
|
||||
$('addTrackersPlus').addEvent('click', function addTrackerDlg() {
|
||||
if (current_hash.length == 0) return;
|
||||
new MochaUI.Window({
|
||||
id: 'trackersPage',
|
||||
title: "_(Trackers addition dialog)",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'addtrackers.html?hash=' + current_hash,
|
||||
scrollbars: true,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
closable: true,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 500,
|
||||
height: 250
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user