support change options before start download

This commit is contained in:
MaysWind 2016-06-19 23:10:26 +08:00
parent 96a1a487fd
commit 5411660e31
9 changed files with 154 additions and 39 deletions

View file

@ -4,6 +4,7 @@
"Error": "错误", "Error": "错误",
"OK": "确定", "OK": "确定",
"Cancel": "取消", "Cancel": "取消",
"Options": "选项",
"New": "新建", "New": "新建",
"Start": "开始下载任务", "Start": "开始下载任务",
"Pause": "暂停下载任务", "Pause": "暂停下载任务",
@ -76,9 +77,11 @@
"Are you sure you want to clear stopped tasks?": "您是否要清除已结束的任务?", "Are you sure you want to clear stopped tasks?": "您是否要清除已结束的任务?",
"Download Links:": "下载链接:", "Download Links:": "下载链接:",
"Start Download": "立即下载", "Start Download": "立即下载",
"Manual Download": "手动下载",
"Open Torrent File": "打开种子文件", "Open Torrent File": "打开种子文件",
"Open Metalink File": "打开 Metalink 文件", "Open Metalink File": "打开 Metalink 文件",
"Support multiple URLs, one URL per line.": "支持多个 URL 地址, 每个地址占一行.", "Support multiple URLs, one URL per line.": "支持多个 URL 地址, 每个地址占一行.",
"More Options": "更多选项",
"Language": "语言", "Language": "语言",
"Aria2 RPC Host": "Aria2 RPC 主机", "Aria2 RPC Host": "Aria2 RPC 主机",
"Aria2 RPC Port": "Aria2 RPC 端口", "Aria2 RPC Port": "Aria2 RPC 端口",

View file

@ -563,6 +563,7 @@
activeBtTaskOptions: ['max-download-limit', 'max-upload-limit', 'bt-max-peers', 'bt-request-peer-speed-limit', 'bt-remove-unselected-file', 'force-save'], activeBtTaskOptions: ['max-download-limit', 'max-upload-limit', 'bt-max-peers', 'bt-request-peer-speed-limit', 'bt-remove-unselected-file', 'force-save'],
inactiveNormalTaskOptions: ['max-download-limit', 'max-upload-limit', 'split', 'min-split-size', 'max-connection-per-server', 'force-save'], inactiveNormalTaskOptions: ['max-download-limit', 'max-upload-limit', 'split', 'min-split-size', 'max-connection-per-server', 'force-save'],
inactiveBtTaskOptions: ['max-download-limit', 'max-upload-limit', 'split', 'min-split-size', 'max-connection-per-server', 'bt-max-peers', 'bt-request-peer-speed-limit', 'bt-remove-unselected-file', 'force-save'], inactiveBtTaskOptions: ['max-download-limit', 'max-upload-limit', 'split', 'min-split-size', 'max-connection-per-server', 'bt-max-peers', 'bt-request-peer-speed-limit', 'bt-remove-unselected-file', 'force-save'],
activeTaskReadonlyOptions: ['split', 'min-split-size', 'max-connection-per-server'] activeTaskReadonlyOptions: ['split', 'min-split-size', 'max-connection-per-server'],
newTaskOptions: ['dir', 'max-download-limit', 'max-upload-limit']
}); });
})(); })();

View file

@ -8,6 +8,7 @@
'Error': 'Error', 'Error': 'Error',
'OK': 'OK', 'OK': 'OK',
'Cancel': 'Cancel', 'Cancel': 'Cancel',
'Options': 'Options',
'New': 'New', 'New': 'New',
'Start': 'Start', 'Start': 'Start',
'Pause': 'Pause', 'Pause': 'Pause',
@ -82,7 +83,9 @@
'Open Torrent File': 'Open Torrent File', 'Open Torrent File': 'Open Torrent File',
'Open Metalink File': 'Open Metalink File', 'Open Metalink File': 'Open Metalink File',
'Start Download': 'Start Download', 'Start Download': 'Start Download',
'Manual Download': 'Manual Download',
'Support multiple URLs, one URL per line.': 'Support multiple URLs, one URL per line.', 'Support multiple URLs, one URL per line.': 'Support multiple URLs, one URL per line.',
'More Options': 'More Options',
'Language': 'Language', 'Language': 'Language',
'Aria2 RPC Host': 'Aria2 RPC Host', 'Aria2 RPC Host': 'Aria2 RPC Host',
'Aria2 RPC Port': 'Aria2 RPC Port', 'Aria2 RPC Port': 'Aria2 RPC Port',

View file

@ -1,18 +1,70 @@
(function () { (function () {
'use strict'; 'use strict';
angular.module('ariaNg').controller('NewTaskController', ['$rootScope', '$scope', '$location', 'ariaNgCommonService', 'aria2TaskService', function ($rootScope, $scope, $location, ariaNgCommonService, aria2TaskService) { angular.module('ariaNg').controller('NewTaskController', ['$rootScope', '$scope', '$location', 'aria2SettingService', 'aria2TaskService', function ($rootScope, $scope, $location, aria2SettingService, aria2TaskService) {
$scope.urls = ''; var tabOrders = ['download', 'options'];
$scope.options = {};
$scope.startDownload = function () { $scope.context = {
var urls = $scope.urls.split('\n'); currentTab: 'download',
urls: '',
globalOptions: null,
availableOptions: [],
options: {}
};
$scope.context.availableOptions = (function () {
var keys = aria2SettingService.getNewTaskOptionKeys();
return aria2SettingService.getSpecifiedOptions(keys);
})();
$rootScope.swipeActions.extentLeftSwipe = function () {
var tabIndex = tabOrders.indexOf($scope.context.currentTab);
if (tabIndex < tabOrders.length - 1) {
$scope.context.currentTab = tabOrders[tabIndex + 1];
return true;
} else {
return false;
}
};
$rootScope.swipeActions.extentRightSwipe = function () {
var tabIndex = tabOrders.indexOf($scope.context.currentTab);
if (tabIndex > 0) {
$scope.context.currentTab = tabOrders[tabIndex - 1];
return true;
} else {
return false;
}
};
$scope.loadDefaultOption = function () {
if ($scope.context.globalOptions) {
return;
}
$rootScope.loadPromise = aria2SettingService.getGlobalOption(function (response) {
if (response.success) {
$scope.context.globalOptions = response.data;
}
});
};
$scope.startDownload = function (pauseOnAdded) {
var urls = $scope.context.urls.split('\n');
var options = angular.copy($scope.context.options);
var tasks = []; var tasks = [];
if (pauseOnAdded) {
options.pause = 'true';
}
for (var i = 0; i < urls.length; i++) { for (var i = 0; i < urls.length; i++) {
tasks.push({ tasks.push({
urls: [urls[i].trim()], urls: [urls[i].trim()],
options: $scope.options options: options
}); });
} }
@ -21,8 +73,22 @@
return; return;
} }
if (pauseOnAdded) {
$location.path('/waiting');
} else {
$location.path('/downloading'); $location.path('/downloading');
}
}); });
}; };
$scope.setOption = function (key, value, optionStatus) {
if (value != '') {
$scope.context.options[key] = value;
} else {
delete $scope.context.options[key];
}
optionStatus.setReady();
};
}]); }]);
})(); })();

View file

@ -10,6 +10,7 @@
scope: { scope: {
option: '=', option: '=',
ngModel: '=', ngModel: '=',
placeholder: '=?',
onChangeValue: '&' onChangeValue: '&'
}, },
link: function (scope, element, attrs, ngModel) { link: function (scope, element, attrs, ngModel) {
@ -121,11 +122,13 @@
} }
}; };
if (!angular.isUndefined(ngModel)) {
scope.$watch(function () { scope.$watch(function () {
return ngModel.$viewValue; return ngModel.$viewValue;
}, function (value) { }, function (value) {
scope.optionValue = value; scope.optionValue = value;
}); });
}
scope.$watch('option', function () { scope.$watch('option', function () {
element.find('[data-toggle="popover"]').popover(); element.find('[data-toggle="popover"]').popover();

View file

@ -63,6 +63,9 @@
return false; return false;
} }
}, },
getNewTaskOptionKeys: function (isBittorrent) {
return aria2TaskAvailableOptions.newTaskOptions;
},
getSpecifiedOptions: function (keys, readonly) { getSpecifiedOptions: function (keys, readonly) {
var options = []; var options = [];

View file

@ -25,6 +25,11 @@ td {
overflow-y: scroll; overflow-y: scroll;
} }
.dropdown-menu.right-align {
left: inherit;
right: 0;
}
.default-cursor { .default-cursor {
cursor: default !important; cursor: default !important;
} }
@ -909,11 +914,6 @@ td {
margin-right: 20px; margin-right: 20px;
} }
.new-task-table .description {
color: #a8a8a8;
margin-left: 5px;
}
@media (max-width: 767px) { @media (max-width: 767px) {
.new-task-table .new-task-toollink > a { .new-task-table .new-task-toollink > a {
display: block; display: block;

View file

@ -1,12 +1,29 @@
<section class="content no-padding"> <section class="content no-padding">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li ng-class="{'active': context.currentTab == 'download'}">
<a class="pointer-cursor" ng-click="context.currentTab = 'download'" translate>Download</a>
</li>
<li ng-class="{'active': context.currentTab == 'options'}">
<a class="pointer-cursor" ng-click="context.currentTab = 'options';loadDefaultOption();" translate>Options</a>
</li>
</ul>
<div class="tab-content no-padding">
<div class="tab-pane" ng-class="{'active': context.currentTab == 'download'}">
<form name="newTaskForm" ng-submit="startDownload()" novalidate>
<div class="new-task-table"> <div class="new-task-table">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<p> <p translate>Download Links:</p>
<span translate>Download Links:</span> <div class="form-group has-feedback no-margin" ng-class="{ 'has-error' : newTaskForm.urls.$invalid && newTaskForm.urls.$dirty, 'has-success' : newTaskForm.urls.$valid && newTaskForm.urls.$dirty }">
<small class="description inline" translate>Support multiple URLs, one URL per line.</small> <textarea name="urls" class="form-control" rows="8" ng-model="context.urls" ng-required="true"
</p> ng-placeholder="'Support multiple URLs, one URL per line.' | translate"
<textarea class="form-control" rows="8" ng-model="urls"></textarea> ng-pattern="/^(\n?(http|https|ftp|ssh):\/\/.+)*$/"></textarea>
<div class="form-control-icon" ng-if="newTaskForm.urls.$dirty">
<i class="fa form-control-feedback" ng-class="{'fa-check':newTaskForm.urls.$valid, 'fa-times':newTaskForm.urls.$invalid}"></i>
</div>
</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -18,7 +35,26 @@
</div> </div>
<div class="col-xs-6"> <div class="col-xs-6">
<div class="pull-right"> <div class="pull-right">
<button class="btn btn-sm btn-default" ng-disabled="urls == ''" ng-click="startDownload()" translate>Start Download</button> <div class="btn-group">
<button type="submit" class="btn btn-sm btn-default" ng-disabled="newTaskForm.$invalid" translate>Start Download</button>
<button type="button" class="btn btn-sm btn-default dropdown-toggle" ng-disabled="newTaskForm.$invalid" data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu right-align">
<li><a class="pointer-cursor" ng-click="startDownload(true)" translate>Manual Download</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="tab-pane" ng-class="{'active': context.currentTab == 'options'}">
<div class="settings-table striped hoverable">
<ng-setting ng-repeat="option in context.availableOptions" option="option" lazy-save-timeout="0"
placeholder="context.globalOptions[option.key]"
on-change-value="setOption(key, value, optionStatus)"></ng-setting>
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,10 +10,10 @@
<div class="setting-value col-sm-8"> <div class="setting-value col-sm-8">
<div ng-class="{'input-group': !!option.suffix}"> <div ng-class="{'input-group': !!option.suffix}">
<div class="form-group has-feedback" ng-class="[optionStatus.getStatusFeedbackStyle()]"> <div class="form-group has-feedback" ng-class="[optionStatus.getStatusFeedbackStyle()]">
<input class="form-control" type="text" ng-disabled="!!option.readonly" <input class="form-control" type="text" placeholder="{{::placeholder}}" ng-disabled="!!option.readonly"
ng-if="option.type == 'string' || option.type == 'integer' || option.type == 'float'" ng-if="option.type == 'string' || option.type == 'integer' || option.type == 'float'"
ng-model="optionValue" ng-change="changeValue(optionValue, true)"/> ng-model="optionValue" ng-change="changeValue(optionValue, true)"/>
<textarea class="form-control" rows="6" ng-disabled="!!option.readonly" <textarea class="form-control" rows="6" placeholder="{{::placeholder}}" ng-disabled="!!option.readonly"
ng-if="option.type == 'text'" ng-if="option.type == 'text'"
ng-model="optionValue" ng-change="changeValue(optionValue, true)"></textarea> ng-model="optionValue" ng-change="changeValue(optionValue, true)"></textarea>
<select class="form-control" style="width: 100%;" ng-disabled="!!option.readonly" <select class="form-control" style="width: 100%;" ng-disabled="!!option.readonly"