diff --git a/src/webui/webui.qrc b/src/webui/webui.qrc
index f0b7a13b8..db5f1c413 100644
--- a/src/webui/webui.qrc
+++ b/src/webui/webui.qrc
@@ -30,9 +30,10 @@
www/public/preferences.html
www/public/preferences_content.html
www/public/properties.html
- www/public/prop-files.html
- www/public/prop-general.html
- www/public/prop-trackers.html
+ www/public/properties_content.html
+ www/public/scripts/prop-general.js
+ www/public/scripts/prop-trackers.js
+ www/public/scripts/prop-files.js
www/public/transferlist.html
www/public/upload.html
www/public/uploadlimit.html
diff --git a/src/webui/www/public/prop-files.html b/src/webui/www/public/prop-files.html
deleted file mode 100644
index a5ce18d9b..000000000
--- a/src/webui/www/public/prop-files.html
+++ /dev/null
@@ -1,338 +0,0 @@
-
-
-
-
-
diff --git a/src/webui/www/public/prop-general.html b/src/webui/www/public/prop-general.html
deleted file mode 100644
index 029312dbe..000000000
--- a/src/webui/www/public/prop-general.html
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/webui/www/public/prop-trackers.html b/src/webui/www/public/prop-trackers.html
deleted file mode 100644
index bff7ae6e7..000000000
--- a/src/webui/www/public/prop-trackers.html
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-
- _(URL)  |
- _(Status) |
- _(Peers) |
- _(Message) |
-
-
-
-
-
-
-
-
diff --git a/src/webui/www/public/properties.html b/src/webui/www/public/properties.html
index 0aa80f3cd..ecf76776b 100644
--- a/src/webui/www/public/properties.html
+++ b/src/webui/www/public/properties.html
@@ -1,37 +1,8 @@
-
-
diff --git a/src/webui/www/public/properties_content.html b/src/webui/www/public/properties_content.html
new file mode 100644
index 000000000..798b30671
--- /dev/null
+++ b/src/webui/www/public/properties_content.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+ _(URL)  |
+ _(Status) |
+ _(Peers) |
+ _(Message) |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/webui/www/public/scripts/client.js b/src/webui/www/public/scripts/client.js
index 67ab70e73..1dfa9425e 100644
--- a/src/webui/www/public/scripts/client.js
+++ b/src/webui/www/public/scripts/client.js
@@ -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
});
diff --git a/src/webui/www/public/scripts/prop-files.js b/src/webui/www/public/scripts/prop-files.js
new file mode 100644
index 000000000..de326d675
--- /dev/null
+++ b/src/webui/www/public/scripts/prop-files.js
@@ -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'));
\ No newline at end of file
diff --git a/src/webui/www/public/scripts/prop-general.js b/src/webui/www/public/scripts/prop-general.js
new file mode 100644
index 000000000..5afe750d3
--- /dev/null
+++ b/src/webui/www/public/scripts/prop-general.js
@@ -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();
+ }
+}
\ No newline at end of file
diff --git a/src/webui/www/public/scripts/prop-trackers.js b/src/webui/www/public/scripts/prop-trackers.js
new file mode 100644
index 000000000..8fbd1fe04
--- /dev/null
+++ b/src/webui/www/public/scripts/prop-trackers.js
@@ -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
+ });
+});
\ No newline at end of file