diff --git a/src/webui/www/public/css/dynamicTable.css b/src/webui/www/public/css/dynamicTable.css index fe3751880..ccbc8bd98 100644 --- a/src/webui/www/public/css/dynamicTable.css +++ b/src/webui/www/public/css/dynamicTable.css @@ -30,6 +30,7 @@ #torrentsTable tr:nth-child(even), +#torrentPeersTable tr:nth-child(even), #filesTable tr:nth-child(even), #properties #torrentFiles tr.alt, #properties #trackers tr.alt, @@ -50,8 +51,13 @@ background-color: #415A8D; color: #fff; } +#torrentPeersTable tr.selected { + background-color: #354158; + color: #fff; +} #torrentsTable tr:hover, +#torrentPeersTable tr:hover, #filesTable tr:hover, #properties #torrentFiles tr.over, #properties #trackers tr.over, @@ -60,6 +66,7 @@ color: #fff; } +#torrentsTable tr:hover, #torrentsTable tr:hover, #properties #torrentFiles tr.over, #properties #trackers tr.over, diff --git a/src/webui/www/public/properties_content.html b/src/webui/www/public/properties_content.html index e21cf2850..a35ce4f31 100644 --- a/src/webui/www/public/properties_content.html +++ b/src/webui/www/public/properties_content.html @@ -65,6 +65,13 @@ @@ -97,3 +104,7 @@ + + \ 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 0819308e1..ba28bcfbb 100644 --- a/src/webui/www/public/scripts/client.js +++ b/src/webui/www/public/scripts/client.js @@ -23,8 +23,10 @@ */ torrentsTable = new TorrentsTable(); +torrentPeersTable = new TorrentPeersTable(); var updatePropertiesPanel = function(){}; +var updateTorrentPeersData = function(){}; var updateMainData = function(){}; var alternativeSpeedLimits = false; var queueing_enabled = true; @@ -286,7 +288,7 @@ window.addEvent('load', function () { var update_labels = false; var full_update = (response['full_update'] == true); if (full_update) { - torrentsTable.rows.erase(); + torrentsTable.clear(); label_list = {}; } if (response['rid']) { @@ -485,7 +487,7 @@ window.addEvent('load', function () { }, contentURL : 'properties_content.html', require : { - css : ['css/Tabs.css'], + css : ['css/Tabs.css', 'css/dynamicTable.css'], js : ['scripts/prop-general.js', 'scripts/prop-trackers.js', 'scripts/prop-webseeds.js', 'scripts/prop-files.js'], }, tabsURL : 'properties.html', @@ -497,6 +499,8 @@ window.addEvent('load', function () { updateTorrentData(); else if (!$('prop_trackers').hasClass('invisible')) updateTrackersData(); + else if (!$('prop_peers').hasClass('invisible')) + updateTorrentPeersData(); else if (!$('prop_webseeds').hasClass('invisible')) updateWebSeedsData(); else if (!$('prop_files').hasClass('invisible')) @@ -576,3 +580,78 @@ var keyboardEvents = new Keyboard({ }); keyboardEvents.activate(); + +var loadTorrentPeersTimer; +var syncTorrentPeersLastResponseId = 0; +var show_flags = true; +var loadTorrentPeersData = function(){ + if ($('prop_peers').hasClass('invisible') || + $('propertiesPanel_collapseToggle').hasClass('panel-expand')) { + syncTorrentPeersLastResponseId = 0; + torrentPeersTable.clear(); + return; + } + var current_hash = torrentsTable.getCurrentTorrentHash(); + if (current_hash == "") { + syncTorrentPeersLastResponseId = 0; + torrentPeersTable.clear(); + clearTimeout(loadTorrentPeersTimer); + loadTorrentPeersTimer = loadTorrentPeersData.delay(syncMainDataTimerPeriod); + return; + } + var url = new URI('sync/torrent_peers'); + url.setData('rid', syncTorrentPeersLastResponseId); + url.setData('hash', current_hash); + var request = new Request.JSON({ + url: url, + noCache: true, + method: 'get', + onFailure: function() { + $('error_div').set('html', 'QBT_TR(qBittorrent client is not reachable)QBT_TR'); + clearTimeout(loadTorrentPeersTimer); + loadTorrentPeersTimer = loadTorrentPeersData.delay(5000); + }, + onSuccess: function(response) { + $('error_div').set('html', ''); + if (response) { + var full_update = (response['full_update'] == true); + if (full_update) { + torrentPeersTable.clear(); + } + if (response['rid']) { + syncTorrentPeersLastResponseId = response['rid']; + } + if (response['peers']) { + for (var key in response['peers']) { + response['peers'][key]['rowId'] = key; + torrentPeersTable.updateRowData(response['peers'][key]); + } + } + if (response['peers_removed']) + response['peers_removed'].each(function (hash) { + torrentPeersTable.removeRow(hash); + }); + torrentPeersTable.updateTable(full_update); + torrentPeersTable.altRow(); + + if (response['show_flags']) { + if (show_flags != response['show_flags']) { + show_flags = response['show_flags']; + torrentPeersTable.columns['country'].force_hide = !show_flags; + torrentPeersTable.updateColumn('country'); + } + } + } + else { + torrentPeersTable.clear(); + } + clearTimeout(loadTorrentPeersTimer); + loadTorrentPeersTimer = loadTorrentPeersData.delay(syncMainDataTimerPeriod); + } + }).send(); +}; + +updateTorrentPeersData = function(){ + clearTimeout(loadTorrentPeersTimer); + loadTorrentPeersData(); +}; \ No newline at end of file diff --git a/src/webui/www/public/scripts/dynamicTable.js b/src/webui/www/public/scripts/dynamicTable.js index d38c90635..018ace08c 100644 --- a/src/webui/www/public/scripts/dynamicTable.js +++ b/src/webui/www/public/scripts/dynamicTable.js @@ -412,6 +412,16 @@ var DynamicTable = new Class({ return false; }, + clear : function () { + this.cur.empty(); + this.rows.empty(); + var trs = this.table.getElements('tr'); + while (trs.length > 0) { + trs[trs.length - 1].dispose(); + trs.pop(); + } + }, + selectedRowsIds : function () { return this.cur; }, @@ -690,4 +700,117 @@ var TorrentsTable = new Class({ } }); +var TorrentPeersTable = new Class({ + Extends: DynamicTable, + + initColumns : function () { + this.newColumn('country', 'width: 4px', ''); + this.newColumn('ip', 'width: 80px', 'QBT_TR(IP)QBT_TR'); + this.newColumn('port', 'width: 35px', 'QBT_TR(Port)QBT_TR'); + this.newColumn('client', 'width: 110px', 'QBT_TR(Client)QBT_TR'); + this.newColumn('progress', 'width: 30px', 'QBT_TR(Progress)QBT_TR'); + this.newColumn('dl_speed', 'width: 30px', 'QBT_TR(Down Speed)QBT_TR'); + this.newColumn('up_speed', 'width: 30px', 'QBT_TR(Up Speed)QBT_TR'); + this.newColumn('downloaded', 'width: 30px', 'QBT_TR(Downloaded)QBT_TR'); + this.newColumn('uploaded', 'width: 30px', 'QBT_TR(Uploaded)QBT_TR'); + this.newColumn('connection', 'width: 30px', 'QBT_TR(Connection)QBT_TR'); + this.newColumn('flags', 'width: 30px', 'QBT_TR(Flags)QBT_TR'); + this.newColumn('relevance', 'min-width: 30px', 'QBT_TR(Relevance)QBT_TR'); + + this.columns['country'].dataProperties.push('country_code'); + this.columns['flags'].dataProperties.push('flags_desc'); + this.initColumnsFunctions(); + }, + + initColumnsFunctions : function () { + + // country + + this.columns['country'].updateTd = function (td, row) { + var country = this.getRowValue(row, 0); + var country_code = this.getRowValue(row, 1); + + if (!country_code) { + if (td.getChildren('img').length) + td.getChildren('img')[0].dispose(); + return; + } + + var img_path = 'images/flags/' + country_code + '.png'; + + if (td.getChildren('img').length) { + var img = td.getChildren('img')[0]; + img.set('src', img_path); + img.set('alt', country); + img.set('title', country); + } + else + td.adopt(new Element('img', { + 'src' : img_path, + 'alt' : country, + 'title' : country + })); + }; + + // ip + + this.columns['ip'].compareRows = function (row1, row2) { + var ip1 = this.getRowValue(row1); + var ip2 = this.getRowValue(row2); + + var a = ip1.split("."); + var b = ip2.split("."); + + for (var i = 0; i < 4; i++){ + if (a[i] != b[i]) + return a[i] - b[i]; + } + + return 0; + }; + + // progress, relevance + + this.columns['progress'].updateTd = function (td, row) { + var progress = this.getRowValue(row); + var progressFormated = (progress * 100).round(1); + if (progressFormated == 100.0 && progress != 1.0) + progressFormated = 99.9; + progressFormated += "%"; + td.set('html', progressFormated); + }; + + this.columns['relevance'].updateTd = this.columns['progress'].updateTd; + + // dl_speed, up_speed + + this.columns['dl_speed'].updateTd = function (td, row) { + var speed = this.getRowValue(row); + if (speed == 0) + td.set('html', ''); + else + td.set('html', friendlyUnit(speed, true)); + }; + + this.columns['up_speed'].updateTd = this.columns['dl_speed'].updateTd; + + // downloaded, uploaded + + this.columns['downloaded'].updateTd = function (td, row) { + var downloaded = this.getRowValue(row); + td.set('html', friendlyUnit(downloaded, false)); + }; + + this.columns['uploaded'].updateTd = this.columns['downloaded'].updateTd; + + // flags + + this.columns['flags'].updateTd = function (td, row) { + td.innerHTML = this.getRowValue(row, 0); + td.title = this.getRowValue(row, 1); + }; + + } + }); + /*************************************************************/