From 09e3abea3ed68bd0ae21f86d9e6a76d6210f966b Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sat, 16 Jul 2016 21:47:02 +0800 Subject: [PATCH] support display peer client information --- bower.json | 1 + src/index.html | 1 + src/langs/zh_CN.json | 1 + src/scripts/config/defaultLanguage.js | 1 + src/scripts/core/app.js | 1 + src/scripts/directives/tooltip.js | 53 ++++++++++++++++++--- src/scripts/filters/peerOrderBy.js | 2 + src/scripts/services/aria2TaskService.js | 14 +++++- src/scripts/services/ariaNgCommonService.js | 21 ++++++++ src/styles/controls/task-table.css | 8 ++++ src/styles/theme/default.css | 5 ++ src/views/task-detail.html | 53 ++++++++++++++------- 12 files changed, 136 insertions(+), 25 deletions(-) diff --git a/bower.json b/bower.json index 40c01b8..1cd6689 100644 --- a/bower.json +++ b/bower.json @@ -45,6 +45,7 @@ "angular-utf8-base64": "^0.0.5", "angular-local-storage": "^0.2.7", "angular-notification": "775ee861c1737b284588bcb878ba1f4e43c70c97", + "angular-bittorrent-peerid": "^1.0.2", "angular-busy": "^4.1.3", "angular-promise-buttons": "^0.1.14", "angular-dragula": "^1.2.7", diff --git a/src/index.html b/src/index.html index 5aa9df1..3e3e9ef 100644 --- a/src/index.html +++ b/src/index.html @@ -276,6 +276,7 @@ + diff --git a/src/langs/zh_CN.json b/src/langs/zh_CN.json index 973ea71..108687b 100644 --- a/src/langs/zh_CN.json +++ b/src/langs/zh_CN.json @@ -82,6 +82,7 @@ "Applications": "应用程序", "Archives": "存档文件", "Address": "地址", + "Client": "客户端", "Status": "状态", "Speed": "速度", "(local)": "(本机)", diff --git a/src/scripts/config/defaultLanguage.js b/src/scripts/config/defaultLanguage.js index 926dd6a..49b7b62 100644 --- a/src/scripts/config/defaultLanguage.js +++ b/src/scripts/config/defaultLanguage.js @@ -86,6 +86,7 @@ 'Applications': 'Applications', 'Archives': 'Archives', 'Address': 'Address', + 'Client': 'Client', 'Status': 'Status', 'Speed': 'Speed', '(local)': '(local)', diff --git a/src/scripts/core/app.js b/src/scripts/core/app.js index 2cce7e2..783ac26 100644 --- a/src/scripts/core/app.js +++ b/src/scripts/core/app.js @@ -14,6 +14,7 @@ 'ab-base64', 'LocalStorageModule', 'notification', + 'angularBittorrentPeerid', 'cgBusy', 'angularPromiseButtons', 'oitozero.ngSweetAlert', diff --git a/src/scripts/directives/tooltip.js b/src/scripts/directives/tooltip.js index fc0a2f2..2b6c8bd 100644 --- a/src/scripts/directives/tooltip.js +++ b/src/scripts/directives/tooltip.js @@ -9,6 +9,7 @@ }, link: function (scope, element, attrs) { var options = { + ngTooltipIf: true, ngTooltipPlacement: 'top', ngTooltipContainer: null, ngTooltipTrigger: 'hover' @@ -16,15 +17,53 @@ angular.extend(options, attrs); - angular.element(element).tooltip({ - title: scope.title, - placement: options.ngTooltipPlacement, - container: options.ngTooltipContainer, - trigger: options.ngTooltipTrigger - }); + var showTooltip = options.ngTooltipIf === true || options.ngTooltipIf === 'true'; + + var addTooltip = function () { + angular.element(element).tooltip({ + title: scope.title, + placement: options.ngTooltipPlacement, + container: options.ngTooltipContainer, + trigger: options.ngTooltipTrigger + }); + }; + + var refreshTooltip = function () { + angular.element(element).attr('title', scope.title).tooltip('fixTitle'); + }; + + var removeTooltip = function () { + angular.element(element).tooltip('destroy'); + }; + + if (showTooltip) { + addTooltip(); + } scope.$watch('title', function () { - angular.element(element).attr('title', scope.title).tooltip('fixTitle'); + if (showTooltip) { + refreshTooltip(); + } + }); + + scope.$watch('ngTooltipIf', function (value) { + if (angular.isUndefined(value)) { + return; + } + + value = (value === true || value === 'true'); + + if (showTooltip == value) { + return; + } + + if (value) { + addTooltip(); + } else { + removeTooltip(); + } + + showTooltip = value; }); } }; diff --git a/src/scripts/filters/peerOrderBy.js b/src/scripts/filters/peerOrderBy.js index ff4aa7a..8380cf8 100644 --- a/src/scripts/filters/peerOrderBy.js +++ b/src/scripts/filters/peerOrderBy.js @@ -15,6 +15,8 @@ if (orderType.type == 'address') { return $filter('orderBy')(array, ['ip', 'port'], orderType.reverse); + } else if (orderType.type == 'client') { + return $filter('orderBy')(array, ['client.name', 'client.version'], orderType.reverse); } else if (orderType.type == 'percent') { return $filter('orderBy')(array, ['completePercent'], orderType.reverse); } else if (orderType.type == 'dspeed') { diff --git a/src/scripts/services/aria2TaskService.js b/src/scripts/services/aria2TaskService.js index 94c7b76..d3ddefb 100644 --- a/src/scripts/services/aria2TaskService.js +++ b/src/scripts/services/aria2TaskService.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - angular.module('ariaNg').factory('aria2TaskService', ['$q', '$translate', 'aria2RpcService', 'ariaNgCommonService', function ($q, $translate, aria2RpcService, ariaNgCommonService) { + angular.module('ariaNg').factory('aria2TaskService', ['$q', '$translate', 'bittorrentPeeridService', 'aria2RpcService', 'ariaNgCommonService', function ($q, $translate, bittorrentPeeridService, aria2RpcService, ariaNgCommonService) { var getFileName = function (file) { if (!file) { return ''; @@ -122,6 +122,18 @@ if (completedPieceCount == localTaskCompletedPieceCount && peer.completePercent != localTaskCompletedPercent) { peer.completePercent = localTaskCompletedPercent; } + + if (peer.peerId) { + var peerId = ariaNgCommonService.decodePercentEncodedString(peer.peerId); + var client = (peerId ? bittorrentPeeridService.parseClient(peerId) : null); + + if (client && client.client != 'unknown') { + peer.client = { + name: (client.client ? client.client.trim() : ''), + version: (client.version ? client.version.trim() : '') + }; + } + } } if (includeLocalPeer) { diff --git a/src/scripts/services/ariaNgCommonService.js b/src/scripts/services/ariaNgCommonService.js index f550dbc..a60a230 100644 --- a/src/scripts/services/ariaNgCommonService.js +++ b/src/scripts/services/ariaNgCommonService.js @@ -58,6 +58,27 @@ return filePath.substring(filePath.lastIndexOf('.')); }, + decodePercentEncodedString: function (s) { + if (!s) { + return s; + } + + var ret = ''; + + for (var i = 0; i < s.length; i++) { + var ch = s.charAt(i); + + if (ch == '%' && i < s.length - 2) { + var code = s.substring(i + 1, i + 3); + ret += String.fromCharCode(parseInt(code, 16)); + i += 2; + } else { + ret += ch; + } + } + + return ret; + }, extendArray: function (sourceArray, targetArray, keyProperty) { if (!targetArray || !sourceArray || sourceArray.length != targetArray.length) { return false; diff --git a/src/styles/controls/task-table.css b/src/styles/controls/task-table.css index 952b834..9075105 100644 --- a/src/styles/controls/task-table.css +++ b/src/styles/controls/task-table.css @@ -51,6 +51,14 @@ text-overflow: ellipsis; } +.task-table .peer-name-wrapper { + display: inline-block; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + .task-table .task-files, .task-table .task-size { font-size: 12px; display: block; diff --git a/src/styles/theme/default.css b/src/styles/theme/default.css index bf4f6c8..dde68c7 100644 --- a/src/styles/theme/default.css +++ b/src/styles/theme/default.css @@ -413,6 +413,11 @@ background-color: #f5f5f5; } +.skin-aria-ng .task-table .peer-client { + color: #888; + font-size: 12px; +} + /* settings-table */ .skin-aria-ng .settings-table { background-color: #fff; diff --git a/src/views/task-detail.html b/src/views/task-detail.html index 5f8e1c2..8b69fca 100644 --- a/src/views/task-detail.html +++ b/src/views/task-detail.html @@ -221,7 +221,7 @@
- +
@@ -245,18 +245,25 @@
-
+
Address + / + Client +
-
- Status +
+
+
+ Status +
+
+ Progress + +
+
-
- Progress - -
-
+
Download / @@ -268,18 +275,30 @@
-
- -
-
-
- +
+
+ +
-
+
+
+
+
+ +
+
+ +
+
+
-
+