add task detail page

This commit is contained in:
MaysWind 2016-05-24 01:06:50 +08:00
parent c30c0751ef
commit 82f454dbf2
10 changed files with 347 additions and 1 deletions

View file

@ -237,10 +237,13 @@
<script src="scripts/controllers/settings-aria2.js"></script>
<script src="scripts/controllers/settings-ariang.js"></script>
<script src="scripts/controllers/status.js"></script>
<script src="scripts/controllers/task-detail.js"></script>
<script src="scripts/filters/dateDuration.js"></script>
<script src="scripts/filters/filename.js"></script>
<script src="scripts/filters/percent.js"></script>
<script src="scripts/filters/substring.js"></script>
<script src="scripts/filters/taskOrderBy.js"></script>
<script src="scripts/filters/taskStatus.js"></script>
<script src="scripts/filters/volumn.js"></script>
<script src="scripts/langs/config.js"></script>
<script src="scripts/langs/en-US.js"></script>

View file

@ -0,0 +1,35 @@
(function () {
'use strict';
angular.module('ariaNg').controller('TaskDetailController', ['$scope', '$routeParams', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($scope, $routeParams, $interval, aria2RpcService, ariaNgSettingService, utils) {
var downloadTaskRefreshPromise = null;
var refreshDownloadTask = function () {
return aria2RpcService.tellStatus({
params: [$routeParams.gid],
callback: function (result) {
var task = utils.processDownloadTask(result);
$scope.task = utils.copyObjectTo(task, $scope.task);
}
})
};
$scope.context = {
currentTab: 'overview'
};
$scope.loadPromise = refreshDownloadTask();
if (ariaNgSettingService.getDownloadTaskRefreshInterval() > 0) {
downloadTaskRefreshPromise = $interval(function () {
refreshDownloadTask();
}, ariaNgSettingService.getDownloadTaskRefreshInterval());
}
$scope.$on('$destroy', function () {
if (downloadTaskRefreshPromise) {
$interval.cancel(downloadTaskRefreshPromise);
}
});
}]);
})();

View file

@ -15,6 +15,10 @@
templateUrl: 'views/list.html',
controller: 'DownloadListController'
})
.when('/task/detail/:gid', {
templateUrl: 'views/task-detail.html',
controller: 'TaskDetailController'
})
.when('/settings/ariang', {
templateUrl: 'views/settings-ariang.html',
controller: 'AriaNgSettingsController'

View file

@ -78,8 +78,41 @@
task.taskName = translateFilter('Unknown');
}
if (task.files) {
for (var i = 0; i < task.files.length; i++) {
var file = task.files[i];
file.length = parseInt(file.length);
file.completedLength = parseInt(file.completedLength);
file.completePercent = (file.length > 0 ? file.completedLength / file.length * 100 : 0);
}
}
return task;
},
copyObjectTo: function (from, to) {
if (!to) {
return from;
}
for (var name in from) {
if (!from.hasOwnProperty(name)) {
continue;
}
var fromValue = from[name];
var toValue = to[name];
if (angular.isObject(fromValue) || angular.isArray(fromValue)) {
to[name] = this.copyObjectTo(from[name], to[name]);
} else {
if (fromValue != toValue) {
to[name] = fromValue;
}
}
}
return to;
},
isUrlMatchUrl2: function (url, url2) {
if (url === url2) {
return true;

View file

@ -0,0 +1,9 @@
(function () {
'use strict';
angular.module("ariaNg").filter('filename', ['utils', function (utils) {
return function (path) {
return utils.getFileNameFromPath(path);
}
}]);
})();

View file

@ -0,0 +1,31 @@
(function () {
'use strict';
angular.module("ariaNg").filter('taskStatus', ['translateFilter', function (translateFilter) {
return function (task) {
if (!task) {
return '';
}
if (task.status == 'active') {
if (task.seeder === true || task.seeder === 'true') {
return translateFilter('Seeding');
} else {
return translateFilter('Downloading');
}
} else if (task.status == 'waiting') {
return translateFilter('Waiting');
} else if (task.status == 'paused') {
return translateFilter('Paused');
} else if (task.status == 'complete') {
return translateFilter('Completed');
} else if (task.status == 'error') {
return translateFilter('Error Occurred');
} else if (task.status == 'removed') {
return translateFilter('Removed');
} else {
return '';
}
}
}]);
})();

View file

@ -23,8 +23,14 @@
'By Remain Time': 'By Remain Time',
'By Download Speed': 'By Download Speed',
'Download': 'Download',
'Upload': 'Upload',
'Downloading': 'Downloading',
'Seeding': 'Seeding',
'Waiting': 'Waiting',
'Paused': 'Paused',
'Completed': 'Completed',
'Error Occurred': 'Error Occurred',
'Removed': 'Removed',
'Downloaded / Stopped': 'Downloaded / Stopped',
'Settings': 'Settings',
'AriaNg Settings': 'AriaNg Settings',
@ -45,6 +51,16 @@
'Remain Time': 'Remain',
'Download Speed': 'Download Speed',
'Files': 'Files',
'Overview': 'Overview',
'Download Info': 'Download Info',
'File List': 'File List',
'BT Trackers': 'BT Trackers',
'Tracker': 'Tracker',
'Task Status': 'Task Status',
'Info Hash': 'Info Hash',
'Seeders': 'Seeders',
'Connections': 'Connections',
'Download Dir': 'Download Dir',
'Language': 'Language',
'Aria2 RPC Host': 'Aria2 RPC Host',
'Aria2 RPC Port': 'Aria2 RPC Port',

View file

@ -23,8 +23,14 @@
'By Remain Time': '按剩余时间',
'By Download Speed': '按下载速度',
'Download': '下载',
'Upload': '上传',
'Downloading': '正在下载',
'Seeding': '正在做种',
'Waiting': '正在等待',
'Paused': '已暂停',
'Completed': '已完成',
'Error Occurred': '发生错误',
'Removed': '已删除',
'Downloaded / Stopped': '已完成 / 已停止',
'Settings': '系统设置',
'AriaNg Settings': 'AriaNg 设置',
@ -45,6 +51,16 @@
'Remain Time': '剩余时间',
'Download Speed': '下载速度',
'Files': '个文件',
'Overview': '总览',
'Download Info': '下载信息',
'File List': '文件列表',
'BT Trackers': 'BT Trackers',
'Tracker': 'Tracker',
'Task Status': '任务状态',
'Info Hash': '特征值',
'Seeders': '种子数',
'Connections': '连接数',
'Download Dir': '下载路径',
'Language': '语言',
'Aria2 RPC Host': 'Aria2 RPC 主机',
'Aria2 RPC Port': 'Aria2 RPC 端口',

View file

@ -161,6 +161,39 @@
color: #3c8dbc;
}
.skin-aria-ng .nav-tabs-custom {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
margin-bottom: 0;
}
.skin-aria-ng .nav-tabs-custom > .nav-tabs {
border-bottom: 1px dotted #ddd;
}
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li {
border-top: 0;
margin-top: 1px;
margin-right: 2px;
}
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li.active {
border-bottom: 2px solid #208fe5;
}
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li > a {
color: #aaa;
border: 0;
}
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li > a:hover,
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li > a:active,
.skin-aria-ng .nav-tabs-custom > .nav-tabs > li.active > a{
color: #208fe5;
}
/* override */
td {
vertical-align: middle !important;
@ -301,7 +334,7 @@ td {
display: block;
}
.task-table .task-files {
.task-table .task-files, .task-table .task-size {
font-size: 12px;
display: block;
}

166
app/views/task-detail.html Normal file
View file

@ -0,0 +1,166 @@
<section class="content no-padding">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li ng-class="{'active': context.currentTab == 'overview'}">
<a class="pointer-cursor" ng-click="context.currentTab = 'overview'" translate>Overview</a>
</li>
<li ng-class="{'active': context.currentTab == 'downloadinfo'}">
<a class="pointer-cursor" ng-click="context.currentTab = 'downloadinfo'" translate>Download Info</a>
</li>
<li ng-class="{'active': context.currentTab == 'filelist'}">
<a class="pointer-cursor" ng-click="context.currentTab = 'filelist'" translate>File List</a>
</li>
<li ng-class="{'active': context.currentTab == 'bttrackers'}" ng-if="task.bittorrent">
<a class="pointer-cursor" ng-click="context.currentTab = 'bttrackers'" translate>BT Trackers</a>
</li>
</ul>
<div class="tab-content no-padding">
<div class="tab-pane" ng-class="{'active': context.currentTab == 'overview'}">
<div class="settings-table">
<div class="row">
<div class="setting-key col-sm-4">
<span translate>File Name</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="task.taskName"></span>
</div>
</div>
<div class="row">
<div class="setting-key col-sm-4">
<span translate>File Size</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="task.totalLength | readableVolumn"></span>
<span ng-bind="'(' + task.files.length + ' ' + ('Files' | translate) + ')'"></span>
</div>
</div>
<div class="row">
<div class="setting-key col-sm-4">
<span translate>Task Status</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="task | taskStatus"></span>
</div>
</div>
<div class="row">
<div class="setting-key col-sm-4">
<span translate>Completed Percent</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="(task.completePercent | percent: 2) + '%'"></span>
</div>
</div>
<div class="row">
<div class="setting-key col-sm-4">
<span translate>Download</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="(task.completedLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.downloadSpeed | readableVolumn) + '/s' : '')"></span>
</div>
</div>
<div class="row" ng-if="task.bittorrent">
<div class="setting-key col-sm-4">
<span translate>Upload</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="(task.uploadLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.uploadSpeed | readableVolumn) + '/s' : '')"></span>
</div>
</div>
<div class="row" ng-if="task.status == 'active' && task.completedLength < task.totalLength">
<div class="setting-key col-sm-4">
<span translate>Remain Time</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="0 <= task.remainTime && task.remainTime < 86400? (task.remainTime | dateDuration: 'second': 'HH:mm:ss') : ('More Than One Day' | translate)"></span>
</div>
</div>
<div class="row" ng-if="task.infoHash">
<div class="setting-key col-sm-4">
<span translate>Info Hash</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="task.infoHash"></span>
</div>
</div>
<div class="row" ng-if="task.status == 'active'">
<div class="setting-key col-sm-4">
<span ng-bind="(task.bittorrent ? ('Seeders' | translate) + ' / ' : '') + ('Connections' | translate)">Connections</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="(task.numSeeders ? (task.numSeeders + ' / ') : '') + task.connections"></span>
</div>
</div>
<div class="row">
<div class="setting-key col-sm-4">
<span translate>Download Dir</span>
</div>
<div class="setting-value col-sm-8">
<span ng-bind="task.dir"></span>
</div>
</div>
</div>
</div>
<div class="tab-pane" ng-class="{'active': context.currentTab == 'downloadinfo'}">
</div>
<div class="tab-pane" ng-class="{'active': context.currentTab == 'filelist'}">
<div class="task-table">
<div class="task-table-title hidden-xs">
<div class="row">
<div class="col-sm-8">
<span translate>File Name</span>
</div>
<div class="col-sm-2">
<span translate>Completed Percent</span>
</div>
<div class="col-sm-2">
<span translate>File Size</span>
</div>
</div>
</div>
<div class="task-table-body">
<div class="row" ng-repeat="file in task.files">
<div class="col-sm-8">
<input type="checkbox" ng-checked="file.selected == 'true'" disabled="disabled"/>
<span ng-bind="file.path | filename"></span>
</div>
<div class="col-sm-2">
<div class="progress">
<div class="progress-bar progress-bar-primary" role="progressbar"
aria-valuenow="{{file.completePercent}}" aria-valuemin="1"
aria-valuemax="100" ng-style="{ width: file.completePercent + '%' }">
<span ng-class="{'progress-lower': file.completePercent < 50}"
ng-bind="(file.completePercent | percent: 2) + '%'"></span>
</div>
</div>
</div>
<div class="col-sm-2">
<span class="task-size" ng-bind="file.length | readableVolumn"></span>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" ng-class="{'active': context.currentTab == 'bttrackers'}" ng-if="task.bittorrent">
<div class="task-table">
<div class="task-table-title hidden-xs">
<div class="row">
<div class="col-sm-12">
<span translate>Tracker</span>
<span ng-bind="'(' + task.bittorrent.announceList.length + ')'"></span>
</div>
</div>
</div>
<div class="task-table-body">
<div class="row" ng-repeat="announce in task.bittorrent.announceList">
<div class="col-sm-12">
<span ng-bind="announce"></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div><!-- /.nav-tabs-custom -->
</section>