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:
Gabriele 2014-12-08 21:00:00 +01:00
parent cb9ed13d69
commit c54271638b
10 changed files with 654 additions and 647 deletions

View file

@ -30,9 +30,10 @@
<file>www/public/preferences.html</file>
<file>www/public/preferences_content.html</file>
<file>www/public/properties.html</file>
<file>www/public/prop-files.html</file>
<file>www/public/prop-general.html</file>
<file>www/public/prop-trackers.html</file>
<file>www/public/properties_content.html</file>
<file>www/public/scripts/prop-general.js</file>
<file>www/public/scripts/prop-trackers.js</file>
<file>www/public/scripts/prop-files.js</file>
<file>www/public/transferlist.html</file>
<file>www/public/upload.html</file>
<file>www/public/uploadlimit.html</file>

View file

@ -1,338 +0,0 @@
<span id="torrentFiles">
<table class="torrentTable" cellpadding="0" cellspacing="0" style="width: 100%">
<thead>
<tr>
<th style="width: 30px"><input type="checkbox" id="tristate_cb" style="display: none;" onclick="javascript:switchCBState()" /><label id="all_files_cb" class="tristate" for="tristate_cb"></label></th>
<th>_(Name)</th>
<th>_(Size)</th>
<th style="width: 90px;">_(Progress)</th>
<th>_(Priority)</th>
</tr>
</thead>
<tbody id="filesTable"></tbody>
</table>
</span>
<script type="text/javascript">
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(!$defined($('filesTable'))) {
// Tab changed
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'));
// Initial loading
loadTorrentFilesData();
</script>

View file

@ -1,123 +0,0 @@
<fieldset>
<legend><b>_(Transfer)</b></legend>
<table>
<tr><td style="text-align:right; padding: 4px;">_(Uploaded:)</td><td style="padding-right: 20px;" id="total_uploaded">0 Kb</td><td style="text-align:right; padding: 4px;">_(UP limit:)</td><td style="padding-right: 20px;" id="up_limit">xx</td><td style="text-align:right; padding: 4px;">_(Share ratio:)</td><td id="share_ratio">xx</td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Downloaded:)</td><td style="padding-right: 20px;" id="total_downloaded">0 Kb</td><td style="text-align:right; padding: 4px;">_(DL limit:)</td><td style="padding-right: 20px;" id="dl_limit">xx</td><td style="text-align:right; padding: 4px;">_(Connections:)</td><td id="nb_connections">xx</td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Wasted:)</td><td style="padding-right: 20px;" id="total_wasted">0 Kb</td><td style="text-align:right; padding: 4px;">_(Time active:)</td><td style="padding-right: 20px;" id="time_elapsed">xx</td><td></td></tr>
</table>
</fieldset>
<fieldset>
<legend><b>_(Information)</b></legend>
<table>
<tr><td style="text-align:right; padding: 4px;">_(Save path:)</td><td id="save_path">xxx</td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Created on:)</td><td id="creation_date">xxx</td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Pieces size:)</td><td id="piece_size">xxx</td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Torrent hash:)</td><td id="torrent_hash">xxx</td></tr>
<tr><td style="vertical-align: top; padding: 4px; text-align:right;">
<br/>
_(Comment:)
</td><td>
<textarea name="comment" id="comment" rows="15" cols="80">
xxx
</textarea>
</td></tr>
</table>
<br/>
</fieldset>
<!--
static information: save_path, creation_date, torrent_hash, comment
dynamic information: total_downloaded, total_uploaded, total_wasted, up_limit, dl_limit, time_elapsed, share_ratio, nb_connections
-->
<script type="text/javascript">
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(!$defined($('torrent_hash'))) {
// Tab changed
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();
}
}
// Initial loading
loadData();
</script>

View file

@ -1,146 +0,0 @@
<span id="trackers">
<table class="torrentTable" cellpadding="0" cellspacing="0" style="width: 100%">
<thead>
<tr>
<th>_(URL) <img src="theme/list-add" id="addTrackersPlus"/></th>
<th>_(Status)</th>
<th>_(Peers)</th>
<th>_(Message)</th>
</tr>
</thead>
<tbody id="trackersTable"></tbody>
</table>
</span>
<script type="text/javascript">
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(!$defined($('trackersTable'))) {
// Tab changed
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'));
// Initial loading
loadTrackersData();
// 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
});
});
</script>

View file

@ -1,37 +1,8 @@
<script type="text/javascript">
MochaUI.initializeTabs('propertiesTabs');
/*MochaUI.updateContent({
'element': $('properties'),
'url': 'prop-general.html'
});*/
$('PropGeneralLink').addEvent('click', function(e){
MochaUI.updateContent({
'element': $('propertiesPanel'),
'url': 'prop-general.html'
});
});
$('PropTrackersLink').addEvent('click', function(e){
MochaUI.updateContent({
'element': $('propertiesPanel'),
'url': 'prop-trackers.html'
});
});
$('PropFilesLink').addEvent('click', function(e){
MochaUI.updateContent({
'element': $('propertiesPanel'),
'url': 'prop-files.html'
});
});
</script>
<div class="toolbarTabs">
<ul id="propertiesTabs" class="tab-menu">
<li id="PropGeneralLink" class="selected"><a>_(General)</a></li>
<li id="PropTrackersLink"><a>_(Trackers)</a></li>
<li id="PropFilesLink"><a>_(Content)</a></li>
</ul>
<div class="clear"></div>
<ul id="propertiesTabs" class="tab-menu">
<li id="PropGeneralLink" class="selected"><a>_(General)</a></li>
<li id="PropTrackersLink"><a>_(Trackers)</a></li>
<li id="PropFilesLink"><a>_(Content)</a></li>
</ul>
<div class="clear"></div>
</div>

View file

@ -0,0 +1,61 @@
<div id="prop_general">
<fieldset>
<legend><b>_(Transfer)</b></legend>
<table>
<tr><td style="text-align:right; padding: 4px;">_(Uploaded:)</td><td style="padding-right: 20px;" id="total_uploaded"></td><td style="text-align:right; padding: 4px;">_(UP limit:)</td><td style="padding-right: 20px;" id="up_limit"></td><td style="text-align:right; padding: 4px;">_(Share ratio:)</td><td id="share_ratio"></td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Downloaded:)</td><td style="padding-right: 20px;" id="total_downloaded"></td><td style="text-align:right; padding: 4px;">_(DL limit:)</td><td style="padding-right: 20px;" id="dl_limit"></td><td style="text-align:right; padding: 4px;">_(Connections:)</td><td id="nb_connections"></td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Wasted:)</td><td style="padding-right: 20px;" id="total_wasted"></td><td style="text-align:right; padding: 4px;">_(Time active:)</td><td style="padding-right: 20px;" id="time_elapsed"></td><td></td></tr>
</table>
</fieldset>
<fieldset>
<legend><b>_(Information)</b></legend>
<table>
<tr><td style="text-align:right; padding: 4px;">_(Save path:)</td><td id="save_path"></td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Created on:)</td><td id="creation_date"></td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Pieces size:)</td><td id="piece_size"></td></tr>
<tr><td style="text-align:right; padding: 4px;">_(Torrent hash:)</td><td id="torrent_hash"></td></tr>
<tr><td style="vertical-align: top; padding: 4px; text-align:right;">
<br/>
_(Comment:)
</td><td>
<textarea name="comment" id="comment" rows="15" cols="80">
</textarea>
</td></tr>
</table>
<br/>
</fieldset>
</div>
<div id="prop_trackers" class="invisible">
<div id="trackers">
<table class="torrentTable" cellpadding="0" cellspacing="0" style="width: 100%">
<thead>
<tr>
<th>_(URL) <img src="theme/list-add" id="addTrackersPlus"/></th>
<th style="width: 250px;">_(Status)</th>
<th style="width: 150px;">_(Peers)</th>
<th style="width: 200px;">_(Message)</th>
</tr>
</thead>
<tbody id="trackersTable"></tbody>
</table>
</div>
</div>
<div id="prop_files" class="invisible">
<div id="torrentFiles">
<table class="torrentTable" cellpadding="0" cellspacing="0" style="width: 100%">
<thead>
<tr>
<th style="width: 30px; border-right: 0"><input type="checkbox" id="tristate_cb" style="display: none;" onclick="javascript:switchCBState()" /><label id="all_files_cb" class="tristate" for="tristate_cb"></label></th>
<th>_(Name)</th>
<th style="width: 150px;">_(Size)</th>
<th style="width: 90px;">_(Progress)</th>
<th style="width: 150px; border-right: 0">_(Priority)</th>
</tr>
</thead>
<tbody id="filesTable"></tbody>
</table>
</div>
</div>

View file

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

View 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'));

View 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();
}
}

View 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
});
});