support display peer client information
This commit is contained in:
parent
5f5fd7087b
commit
09e3abea3e
|
@ -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",
|
||||
|
|
|
@ -276,6 +276,7 @@
|
|||
<script src="../bower_components/angular-utf8-base64/angular-utf8-base64.min.js"></script>
|
||||
<script src="../bower_components/angular-local-storage/dist/angular-local-storage.min.js"></script>
|
||||
<script src="../bower_components/angular-notification/angular-notification.js"></script>
|
||||
<script src="../bower_components/angular-bittorrent-peerid/angular-bittorrent-peerid.min.js"></script>
|
||||
<script src="../bower_components/angular-busy/dist/angular-busy.min.js"></script>
|
||||
<script src="../bower_components/angular-promise-buttons/dist/angular-promise-buttons.min.js"></script>
|
||||
<script src="../bower_components/angular-dragula/dist/angular-dragula.min.js"></script>
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
"Applications": "应用程序",
|
||||
"Archives": "存档文件",
|
||||
"Address": "地址",
|
||||
"Client": "客户端",
|
||||
"Status": "状态",
|
||||
"Speed": "速度",
|
||||
"(local)": "(本机)",
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
'Applications': 'Applications',
|
||||
'Archives': 'Archives',
|
||||
'Address': 'Address',
|
||||
'Client': 'Client',
|
||||
'Status': 'Status',
|
||||
'Speed': 'Speed',
|
||||
'(local)': '(local)',
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
'ab-base64',
|
||||
'LocalStorageModule',
|
||||
'notification',
|
||||
'angularBittorrentPeerid',
|
||||
'cgBusy',
|
||||
'angularPromiseButtons',
|
||||
'oitozero.ngSweetAlert',
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
<div class="checkbox checkbox-primary">
|
||||
<input id="{{'file_' + file.index}}" type="checkbox" ng-disabled="!task || !task.files || task.files.length < 2 || (task.status != 'waiting' && task.status != 'paused')"
|
||||
ng-model="file.selected" ng-change="setSelectedFile()"/>
|
||||
<label for="{{'file_' + file.index}}" ng-bind="file.fileName"></label>
|
||||
<label for="{{'file_' + file.index}}" ng-bind="file.fileName" ng-tooltip="{{file.fileName}}" ng-tooltip-container="body"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
|
@ -245,18 +245,25 @@
|
|||
<div class="task-table">
|
||||
<div class="task-table-title">
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="col-md-4 col-sm-4">
|
||||
<a ng-click="changePeerListDisplayOrder('address:asc', true)" translate>Address</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetPeerListDisplayOrder('address:asc'), 'fa-sort-desc fa-order-desc': isSetPeerListDisplayOrder('address:desc')}"></i>
|
||||
<span>/</span>
|
||||
<a ng-click="changePeerListDisplayOrder('client:asc', true)" translate>Client</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetPeerListDisplayOrder('client:asc'), 'fa-sort-desc fa-order-desc': isSetPeerListDisplayOrder('client:desc')}"></i>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<span translate>Status</span>
|
||||
<div class="col-md-5 col-sm-4">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<span translate>Status</span>
|
||||
</div>
|
||||
<div class="col-sm-6 text-right">
|
||||
<a ng-click="changePeerListDisplayOrder('percent:desc', true)" translate>Progress</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetPeerListDisplayOrder('percent:asc'), 'fa-sort-desc fa-order-desc': isSetPeerListDisplayOrder('percent:desc')}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a ng-click="changePeerListDisplayOrder('percent:desc', true)" translate>Progress</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetPeerListDisplayOrder('percent:asc'), 'fa-sort-desc fa-order-desc': isSetPeerListDisplayOrder('percent:desc')}"></i>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-md-3 col-sm-4">
|
||||
<a ng-click="changePeerListDisplayOrder('dspeed:desc', true)" translate>Download</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetPeerListDisplayOrder('dspeed:asc'), 'fa-sort-desc fa-order-desc': isSetPeerListDisplayOrder('dspeed:desc')}"></i>
|
||||
<span>/</span>
|
||||
|
@ -268,18 +275,30 @@
|
|||
</div>
|
||||
<div class="task-table-body">
|
||||
<div class="row" ng-repeat="peer in context.btPeers | peerOrderBy: getPeerListOrderType()">
|
||||
<div class="col-sm-3">
|
||||
<span ng-bind="peer.name | translate"></span><i class="icon-seeder fa fa-angle-double-up" title="{{'Seeding' | translate}}" ng-if="peer && peer.seeder"></i>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="piece-bar-wrapper">
|
||||
<ng-piece-bar bit-field="peer.bitfield" piece-count="task.numPieces" color="#208fe5"></ng-piece-bar>
|
||||
<div class="col-md-4 col-sm-4 col-xs-12">
|
||||
<div class="peer-name-wrapper" ng-tooltip-if="{{!!peer.client}}" ng-tooltip-container="body"
|
||||
ng-tooltip="{{(peer.client ? (peer.client.name + (peer.client.version ? ' ' + peer.client.version : '')) : ('Unknown Client' | translate)) + (peer.seeder ? ', ' + ('Seeding' | translate) : '')}}">
|
||||
<span ng-bind="peer.name | translate"></span><i class="icon-seeder fa fa-angle-double-up" ng-if="peer && peer.seeder"></i>
|
||||
<span class="peer-client" ng-if="!!peer.client"
|
||||
ng-bind="peer.client ? ('(' + peer.client.name + (peer.client.version ? ' ' + peer.client.version : '') + ')') : ''"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2 col-xs-4">
|
||||
<div class="col-md-5 col-sm-4 col-xs-12">
|
||||
<div class="row">
|
||||
<div class="col-md-9 col-sm-7 col-xs-12">
|
||||
<div class="piece-bar-wrapper">
|
||||
<ng-piece-bar bit-field="peer.bitfield" piece-count="task.numPieces" color="#208fe5"></ng-piece-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-5 hidden-xs text-right">
|
||||
<span ng-bind="(peer.completePercent | percent: 2) + '%'"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="visible-xs col-xs-4">
|
||||
<span ng-bind="(peer.completePercent | percent: 2) + '%'"></span>
|
||||
</div>
|
||||
<div class="col-sm-4 col-xs-8">
|
||||
<div class="col-md-3 col-sm-4 col-xs-8">
|
||||
<div class="task-peer-download-speed">
|
||||
<i class="icon-download fa fa-arrow-down"></i>
|
||||
<span ng-bind="(peer.downloadSpeed | readableVolumn) + '/s'"></span>
|
||||
|
|
Reference in a new issue