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 @@ - - - - - - - - - - - - -
_(Name)_(Size)_(Progress)_(Priority)
-
- - 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 @@ -
- _(Transfer) - - - - -
_(Uploaded:)0 Kb_(UP limit:)xx_(Share ratio:)xx
_(Downloaded:)0 Kb_(DL limit:)xx_(Connections:)xx
_(Wasted:)0 Kb_(Time active:)xx
-
- -
- _(Information) - - - - - - -
_(Save path:)xxx
_(Created on:)xxx
_(Pieces size:)xxx
_(Torrent hash:)xxx
-
- _(Comment:) -
- -
-
-
- - - - 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 @@ +
+
+ _(Transfer) + + + + +
_(Uploaded:)_(UP limit:)_(Share ratio:)
_(Downloaded:)_(DL limit:)_(Connections:)
_(Wasted:)_(Time active:)
+
+ +
+ _(Information) + + + + + + +
_(Save path:)
_(Created on:)
_(Pieces size:)
_(Torrent hash:)
+
+ _(Comment:) +
+ +
+
+
+
+ + + + \ 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