support tree view for bittorrent files
This commit is contained in:
parent
26d9eafbe7
commit
4305b80c21
|
@ -372,6 +372,7 @@
|
|||
<script src="scripts/directives/pieceBar.js"></script>
|
||||
<script src="scripts/directives/pieceMap.js"></script>
|
||||
<script src="scripts/directives/chart.js"></script>
|
||||
<script src="scripts/directives/indeterminate.js"></script>
|
||||
<script src="scripts/directives/placeholder.js"></script>
|
||||
<script src="scripts/directives/setting.js"></script>
|
||||
<script src="scripts/directives/settingDialog.js"></script>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
defaultLanguage: 'en',
|
||||
defaultHost: 'localhost',
|
||||
defaultSecureProtocol: 'https',
|
||||
defaultPathSeparator: '/',
|
||||
globalStatStorageCapacity: 120,
|
||||
taskStatStorageCapacity: 300,
|
||||
lazySaveTimeout: 500,
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
};
|
||||
|
||||
var includeLocalPeer = true;
|
||||
var addVirtualFileNode = true;
|
||||
|
||||
if (!$scope.task) {
|
||||
return aria2TaskService.getTaskStatus($routeParams.gid, function (response) {
|
||||
|
@ -82,7 +83,7 @@
|
|||
}
|
||||
}, silent, includeLocalPeer);
|
||||
}
|
||||
}, silent);
|
||||
}, silent, addVirtualFileNode);
|
||||
} else {
|
||||
return aria2TaskService.getTaskStatusAndBtPeers($routeParams.gid, function (response) {
|
||||
if (!response.success) {
|
||||
|
@ -91,7 +92,7 @@
|
|||
|
||||
processTask(response.task);
|
||||
processPeers(response.peers);
|
||||
}, silent, requireBtPeers($scope.task), includeLocalPeer);
|
||||
}, silent, requireBtPeers($scope.task), includeLocalPeer, addVirtualFileNode);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -106,7 +107,7 @@
|
|||
for (var i = 0; i < $scope.task.files.length; i++) {
|
||||
var file = $scope.task.files[i];
|
||||
|
||||
if (file && file.selected) {
|
||||
if (file && file.selected && !file.isDir) {
|
||||
selectedFileIndex.push(file.index);
|
||||
}
|
||||
}
|
||||
|
@ -122,10 +123,78 @@
|
|||
}, silent);
|
||||
};
|
||||
|
||||
var setSelectedNode = function (node, value) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.files && node.files.length) {
|
||||
for (var i = 0; i < node.files.length; i++) {
|
||||
var fileNode = node.files[i];
|
||||
fileNode.selected = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.subDirs && node.subDirs.length) {
|
||||
for (var i = 0; i < node.subDirs.length; i++) {
|
||||
var dirNode = node.subDirs[i];
|
||||
setSelectedNode(dirNode, value);
|
||||
}
|
||||
}
|
||||
|
||||
node.selected = value;
|
||||
node.partialSelected = false;
|
||||
};
|
||||
|
||||
var updateDirNodeSelectedStatus = function (node) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedSubNodesCount = 0;
|
||||
var partitalSelectedSubNodesCount = 0;
|
||||
|
||||
if (node.files && node.files.length) {
|
||||
for (var i = 0; i < node.files.length; i++) {
|
||||
var fileNode = node.files[i];
|
||||
selectedSubNodesCount += (fileNode.selected ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.subDirs && node.subDirs.length) {
|
||||
for (var i = 0; i < node.subDirs.length; i++) {
|
||||
var dirNode = node.subDirs[i];
|
||||
updateDirNodeSelectedStatus(dirNode);
|
||||
selectedSubNodesCount += (dirNode.selected ? 1 : 0);
|
||||
partitalSelectedSubNodesCount += (dirNode.partialSelected ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
node.selected = (selectedSubNodesCount > 0 && selectedSubNodesCount === (node.subDirs.length + node.files.length));
|
||||
node.partialSelected = ((selectedSubNodesCount > 0 && selectedSubNodesCount < (node.subDirs.length + node.files.length)) || partitalSelectedSubNodesCount > 0);
|
||||
};
|
||||
|
||||
var updateAllDirNodesSelectedStatus = function () {
|
||||
if (!$scope.task || !$scope.task.multiDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < $scope.task.files.length; i++) {
|
||||
var node = $scope.task.files[i];
|
||||
|
||||
if (!node.isDir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
updateDirNodeSelectedStatus(node);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.context = {
|
||||
currentTab: 'overview',
|
||||
isEnableSpeedChart: ariaNgSettingService.getDownloadTaskRefreshInterval() > 0,
|
||||
showChooseFilesToolbar: false,
|
||||
collapsedDirs: {},
|
||||
btPeers: [],
|
||||
healthPercent: 0,
|
||||
collapseTrackers: true,
|
||||
|
@ -165,6 +234,10 @@
|
|||
};
|
||||
|
||||
$scope.changeFileListDisplayOrder = function (type, autoSetReverse) {
|
||||
if ($scope.task && $scope.task.multiDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getFileListDisplayOrder());
|
||||
var newType = ariaNgCommonService.parseOrderType(type);
|
||||
|
||||
|
@ -183,6 +256,10 @@
|
|||
};
|
||||
|
||||
$scope.getFileListOrderType = function () {
|
||||
if ($scope.task && $scope.task.multiDir) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ariaNgSettingService.getFileListDisplayOrder();
|
||||
};
|
||||
|
||||
|
@ -191,14 +268,16 @@
|
|||
$scope.context.showChooseFilesToolbar = true;
|
||||
};
|
||||
|
||||
$scope.getSelectedFileCount = function () {
|
||||
var count = 0;
|
||||
|
||||
$scope.isAnyFileSelected = function () {
|
||||
for (var i = 0; i < $scope.task.files.length; i++) {
|
||||
count += $scope.task.files[i].selected ? 1 : 0;
|
||||
var file = $scope.task.files[i];
|
||||
|
||||
if (!file.isDir && file.selected) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.selectFiles = function (type) {
|
||||
|
@ -207,14 +286,22 @@
|
|||
}
|
||||
|
||||
for (var i = 0; i < $scope.task.files.length; i++) {
|
||||
var file = $scope.task.files[i];
|
||||
|
||||
if (file.isDir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type === 'all') {
|
||||
$scope.task.files[i].selected = true;
|
||||
file.selected = true;
|
||||
} else if (type === 'none') {
|
||||
$scope.task.files[i].selected = false;
|
||||
file.selected = false;
|
||||
} else if (type === 'reverse') {
|
||||
$scope.task.files[i].selected = !$scope.task.files[i].selected;
|
||||
file.selected = !file.selected;
|
||||
}
|
||||
}
|
||||
|
||||
updateAllDirNodesSelectedStatus();
|
||||
};
|
||||
|
||||
$scope.chooseSpecifiedFiles = function (type) {
|
||||
|
@ -222,12 +309,19 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var files = $scope.task.files;
|
||||
var extensions = ariaNgFileTypes[type];
|
||||
var fileIndexes = [];
|
||||
var isAllSelected = true;
|
||||
|
||||
for (var i = 0; i < $scope.task.files.length; i++) {
|
||||
var extension = ariaNgCommonService.getFileExtension($scope.task.files[i].fileName);
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var file = files[i];
|
||||
|
||||
if (file.isDir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var extension = ariaNgCommonService.getFileExtension(file.fileName);
|
||||
|
||||
if (extension) {
|
||||
extension = extension.toLowerCase();
|
||||
|
@ -236,7 +330,7 @@
|
|||
if (extensions.indexOf(extension) >= 0) {
|
||||
fileIndexes.push(i);
|
||||
|
||||
if (!$scope.task.files[i].selected) {
|
||||
if (!file.selected) {
|
||||
isAllSelected = false;
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +338,14 @@
|
|||
|
||||
for (var i = 0; i < fileIndexes.length; i++) {
|
||||
var index = fileIndexes[i];
|
||||
$scope.task.files[index].selected = !isAllSelected;
|
||||
var file = files[index];
|
||||
|
||||
if (file && !file.isDir) {
|
||||
file.selected = !isAllSelected;
|
||||
}
|
||||
}
|
||||
|
||||
updateAllDirNodesSelectedStatus();
|
||||
};
|
||||
|
||||
$scope.saveChoosedFiles = function () {
|
||||
|
@ -263,12 +363,43 @@
|
|||
}
|
||||
};
|
||||
|
||||
$scope.setSelectedFile = function () {
|
||||
$scope.setSelectedFile = function (updateNodeSelectedStatus) {
|
||||
if (updateNodeSelectedStatus) {
|
||||
updateAllDirNodesSelectedStatus();
|
||||
}
|
||||
|
||||
if (!$scope.context.showChooseFilesToolbar) {
|
||||
setSelectFiles(true);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.collapseDir = function (dirNode, newValue) {
|
||||
var nodePath = dirNode.nodePath;
|
||||
|
||||
if (angular.isUndefined(newValue)) {
|
||||
newValue = !$scope.context.collapsedDirs[nodePath];
|
||||
}
|
||||
|
||||
if (newValue) {
|
||||
for (var i = 0; i < dirNode.subDirs.length; i++) {
|
||||
$scope.collapseDir(dirNode.subDirs[i], newValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodePath) {
|
||||
$scope.context.collapsedDirs[nodePath] = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setSelectedNode = function (dirNode) {
|
||||
setSelectedNode(dirNode, dirNode.selected);
|
||||
updateAllDirNodesSelectedStatus();
|
||||
|
||||
if (!$scope.context.showChooseFilesToolbar) {
|
||||
$scope.setSelectedFile(false);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.changePeerListDisplayOrder = function (type, autoSetReverse) {
|
||||
var oldType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getPeerListDisplayOrder());
|
||||
var newType = ariaNgCommonService.parseOrderType(type);
|
||||
|
|
17
src/scripts/directives/indeterminate.js
Normal file
17
src/scripts/directives/indeterminate.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular.module('ariaNg').directive('ngIndeterminate', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
indeterminate: '=ngIndeterminate'
|
||||
},
|
||||
link: function (scope, element) {
|
||||
scope.$watch('indeterminate', function () {
|
||||
element[0].indeterminate = (scope.indeterminate === 'true' || scope.indeterminate === true);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
}());
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
angular.module('ariaNg').filter('fileOrderBy', ['$filter', 'ariaNgCommonService', function ($filter, ariaNgCommonService) {
|
||||
return function (array, type) {
|
||||
if (!angular.isArray(array)) {
|
||||
if (!angular.isArray(array) || !type) {
|
||||
return array;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular.module('ariaNg').factory('aria2TaskService', ['$q', 'bittorrentPeeridService', 'aria2Errors', 'aria2RpcService', 'ariaNgCommonService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgSettingService', function ($q, bittorrentPeeridService, aria2Errors, aria2RpcService, ariaNgCommonService, ariaNgLocalizationService, ariaNgLogService, ariaNgSettingService) {
|
||||
angular.module('ariaNg').factory('aria2TaskService', ['$q', 'bittorrentPeeridService', 'ariaNgConstants', 'aria2Errors', 'aria2RpcService', 'ariaNgCommonService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgSettingService', function ($q, bittorrentPeeridService, ariaNgConstants, aria2Errors, aria2RpcService, ariaNgCommonService, ariaNgLocalizationService, ariaNgLogService, ariaNgSettingService) {
|
||||
var getFileName = function (file) {
|
||||
if (!file) {
|
||||
ariaNgLogService.warn('[aria2TaskService.getFileName] file is null');
|
||||
|
@ -54,6 +54,150 @@
|
|||
};
|
||||
};
|
||||
|
||||
var getRelativePath = function (task, file) {
|
||||
var downloadPath = task.dir;
|
||||
var relativePath = file.path;
|
||||
|
||||
if (downloadPath) {
|
||||
downloadPath = downloadPath.replace(/\\/g, ariaNgConstants.defaultPathSeparator);
|
||||
}
|
||||
|
||||
if (relativePath) {
|
||||
relativePath = relativePath.replace(/\\/g, ariaNgConstants.defaultPathSeparator);
|
||||
}
|
||||
|
||||
var trimStartPathSeparator = function () {
|
||||
if (relativePath.length > 1 && relativePath.charAt(0) === ariaNgConstants.defaultPathSeparator) {
|
||||
relativePath = relativePath.substr(1);
|
||||
}
|
||||
};
|
||||
|
||||
var trimEndPathSeparator = function () {
|
||||
if (relativePath.length > 1 && relativePath.charAt(relativePath.length - 1) === ariaNgConstants.defaultPathSeparator) {
|
||||
relativePath = relativePath.substr(0, relativePath.length - 1);
|
||||
}
|
||||
};
|
||||
|
||||
if (downloadPath && relativePath.indexOf(downloadPath) === 0) {
|
||||
relativePath = relativePath.substr(downloadPath.length);
|
||||
}
|
||||
|
||||
trimStartPathSeparator();
|
||||
|
||||
if (task.bittorrent && task.bittorrent.mode === 'multi' && task.bittorrent.info && task.bittorrent.info.name) {
|
||||
var bittorrentName = task.bittorrent.info.name;
|
||||
|
||||
if (relativePath.indexOf(bittorrentName) === 0) {
|
||||
relativePath = relativePath.substr(bittorrentName.length);
|
||||
}
|
||||
}
|
||||
|
||||
trimStartPathSeparator();
|
||||
|
||||
if (file.fileName && ((relativePath.lastIndexOf(file.fileName) + file.fileName.length) === relativePath.length)) {
|
||||
relativePath = relativePath.substr(0, relativePath.length - file.fileName.length);
|
||||
}
|
||||
|
||||
trimEndPathSeparator();
|
||||
|
||||
return relativePath;
|
||||
};
|
||||
|
||||
var getDirectoryNode = function (path, allDirectories, allDirectoryMap) {
|
||||
var node = allDirectoryMap[path];
|
||||
|
||||
if (node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
var parentNode = null;
|
||||
var nodeName = path;
|
||||
|
||||
if (path.length) {
|
||||
var parentPath = '';
|
||||
var lastSeparatorIndex = path.lastIndexOf(ariaNgConstants.defaultPathSeparator);
|
||||
|
||||
if (lastSeparatorIndex > 0) {
|
||||
parentPath = path.substring(0, lastSeparatorIndex);
|
||||
nodeName = path.substring(lastSeparatorIndex + 1);
|
||||
}
|
||||
|
||||
parentNode = getDirectoryNode(parentPath, allDirectories, allDirectoryMap);
|
||||
}
|
||||
|
||||
node = {
|
||||
isDir: true,
|
||||
nodePath: path,
|
||||
nodeName: nodeName,
|
||||
relativePath: (parentNode && parentNode.nodePath) || '',
|
||||
level: (parentNode && parentNode.level + 1) || 0,
|
||||
length: 0,
|
||||
selected: true,
|
||||
partialSelected: false,
|
||||
files: [],
|
||||
subDirs: []
|
||||
};
|
||||
|
||||
allDirectories.push(node);
|
||||
allDirectoryMap[path] = node;
|
||||
|
||||
if (parentNode) {
|
||||
parentNode.subDirs.push(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
var pushFileToDirectoryNode = function (file, allDirectories, allDirectoryMap) {
|
||||
if (!file || !allDirectories || !allDirectoryMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
var nodePath = file.relativePath || '';
|
||||
var directoryNode = getDirectoryNode(nodePath, allDirectories, allDirectoryMap);
|
||||
|
||||
directoryNode.files.push(file);
|
||||
|
||||
return directoryNode;
|
||||
};
|
||||
|
||||
var fillAllNodes = function (node, allDirectoryMap, allNodes) {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allSubNodesLength = 0;
|
||||
var selectedSubNodesCount = 0;
|
||||
var partitalSelectedSubNodesCount = 0;
|
||||
|
||||
if (node.subDirs && node.subDirs.length) {
|
||||
for (var i = 0; i < node.subDirs.length; i++) {
|
||||
var dirNode = node.subDirs[i];
|
||||
allNodes.push(dirNode);
|
||||
|
||||
fillAllNodes(dirNode, allDirectoryMap, allNodes);
|
||||
|
||||
allSubNodesLength += dirNode.length;
|
||||
selectedSubNodesCount += (dirNode.selected ? 1 : 0);
|
||||
partitalSelectedSubNodesCount += (dirNode.partialSelected ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.files && node.files.length) {
|
||||
for (var i = 0; i < node.files.length; i++) {
|
||||
var fileNode = node.files[i];
|
||||
allNodes.push(fileNode);
|
||||
|
||||
allSubNodesLength += fileNode.length;
|
||||
selectedSubNodesCount += (fileNode.selected ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
node.length = allSubNodesLength;
|
||||
node.selected = (selectedSubNodesCount > 0 && selectedSubNodesCount === (node.subDirs.length + node.files.length));
|
||||
node.partialSelected = ((selectedSubNodesCount > 0 && selectedSubNodesCount < (node.subDirs.length + node.files.length)) || partitalSelectedSubNodesCount > 0);
|
||||
};
|
||||
|
||||
var getTaskErrorDescription = function (task) {
|
||||
if (!task.errorCode) {
|
||||
return '';
|
||||
|
@ -121,12 +265,14 @@
|
|||
return combinedPieces;
|
||||
};
|
||||
|
||||
var processDownloadTask = function (task) {
|
||||
var processDownloadTask = function (task, addVirtualFileNode) {
|
||||
if (!task) {
|
||||
ariaNgLogService.warn('[aria2TaskService.processDownloadTask] task is null');
|
||||
return task;
|
||||
}
|
||||
|
||||
addVirtualFileNode = addVirtualFileNode && task.bittorrent && task.bittorrent.mode === 'multi';
|
||||
|
||||
var pieceStatus = getPieceStatus(task.bitfield, task.numPieces);
|
||||
|
||||
task.totalLength = parseInt(task.totalLength);
|
||||
|
@ -156,6 +302,8 @@
|
|||
|
||||
if (task.files) {
|
||||
var selectedFileCount = 0;
|
||||
var allDirectories = [];
|
||||
var allDirectoryMap = {};
|
||||
|
||||
for (var i = 0; i < task.files.length; i++) {
|
||||
var file = task.files[i];
|
||||
|
@ -166,9 +314,24 @@
|
|||
file.completedLength = parseInt(file.completedLength);
|
||||
file.completePercent = (file.length > 0 ? file.completedLength / file.length * 100 : 0);
|
||||
|
||||
if (addVirtualFileNode) {
|
||||
file.relativePath = getRelativePath(task, file);
|
||||
var dirNode = pushFileToDirectoryNode(file, allDirectories, allDirectoryMap);
|
||||
file.level = dirNode.level + 1;
|
||||
}
|
||||
|
||||
selectedFileCount += file.selected ? 1 : 0;
|
||||
}
|
||||
|
||||
if (addVirtualFileNode && allDirectories.length > 1) {
|
||||
var allNodes = [];
|
||||
var rootNode = allDirectoryMap[''];
|
||||
fillAllNodes(rootNode, allDirectoryMap, allNodes);
|
||||
|
||||
task.files = allNodes;
|
||||
task.multiDir = true;
|
||||
}
|
||||
|
||||
task.selectedFileCount = selectedFileCount;
|
||||
}
|
||||
|
||||
|
@ -304,7 +467,7 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
getTaskStatus: function (gid, callback, silent) {
|
||||
getTaskStatus: function (gid, callback, silent, addVirtualFileNode) {
|
||||
return aria2RpcService.tellStatus({
|
||||
gid: gid,
|
||||
silent: !!silent,
|
||||
|
@ -315,7 +478,7 @@
|
|||
}
|
||||
|
||||
if (response.success) {
|
||||
processDownloadTask(response.data);
|
||||
processDownloadTask(response.data, addVirtualFileNode);
|
||||
}
|
||||
|
||||
callback(response);
|
||||
|
@ -371,7 +534,7 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
getTaskStatusAndBtPeers: function (gid, callback, silent, requirePeers, includeLocalPeer) {
|
||||
getTaskStatusAndBtPeers: function (gid, callback, silent, requirePeers, includeLocalPeer, addVirtualFileNode) {
|
||||
var methods = [
|
||||
aria2RpcService.tellStatus({ gid: gid }, true)
|
||||
];
|
||||
|
@ -393,7 +556,7 @@
|
|||
|
||||
if (response.success && response.data.length > 0) {
|
||||
response.task = response.data[0][0];
|
||||
processDownloadTask(response.task);
|
||||
processDownloadTask(response.task, addVirtualFileNode);
|
||||
}
|
||||
|
||||
if (response.success && response.task.bittorrent && response.data.length > 1) {
|
||||
|
@ -685,14 +848,14 @@
|
|||
callback: createTaskEventCallback(this.getTaskStatus, callback, 'error')
|
||||
});
|
||||
},
|
||||
processDownloadTasks: function (tasks) {
|
||||
processDownloadTasks: function (tasks, addVirtualFileNode) {
|
||||
if (!angular.isArray(tasks)) {
|
||||
ariaNgLogService.warn('[aria2TaskService.processDownloadTasks] tasks is not array', tasks);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tasks.length; i++) {
|
||||
processDownloadTask(tasks[i]);
|
||||
processDownloadTask(tasks[i], addVirtualFileNode);
|
||||
}
|
||||
},
|
||||
getPieceStatus: function (bitField, pieceCount) {
|
||||
|
|
|
@ -110,6 +110,14 @@
|
|||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.checkbox-inline {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.icon-expand + .checkbox {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* angular-input-dropdown */
|
||||
input-dropdown[input-class-name="form-control"] > .input-dropdown {
|
||||
width: 100%
|
||||
|
|
|
@ -454,7 +454,10 @@
|
|||
}
|
||||
|
||||
/* awesome-bootstrap-checkbox extend */
|
||||
.skin-aria-ng .checkbox-primary input[type="checkbox"]:checked + label::before, .checkbox-primary input[type="radio"]:checked + label::before {
|
||||
.skin-aria-ng .checkbox-primary input[type="checkbox"]:checked + label::before,
|
||||
.skin-aria-ng .checkbox-primary input[type="radio"]:checked + label::before,
|
||||
.skin-aria-ng .checkbox-primary input[type="checkbox"]:indeterminate + label::before,
|
||||
.skin-aria-ng .checkbox-primary input[type="radio"]:indeterminate + label::before {
|
||||
background-color: #208fe5;
|
||||
border-color: #208fe5;
|
||||
}
|
||||
|
|
|
@ -182,17 +182,17 @@
|
|||
<div class="task-table-title">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<a ng-click="changeFileListDisplayOrder('name:asc', true)" translate>File Name</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('name:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('name:desc')}"></i>
|
||||
<a ng-click="changeFileListDisplayOrder('name:asc', true)" ng-class="{true: 'default-cursor'}[task.multiDir]" translate>File Name</a>
|
||||
<i ng-if="!task.multiDir" class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('name:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('name:desc')}"></i>
|
||||
<a ng-click="showChooseFilesToolbar()" ng-if="task && task.files && task.files.length > 1 && (task.status === 'waiting' || task.status === 'paused')" translate>(Choose Files)</a>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a ng-click="changeFileListDisplayOrder('percent:desc', true)" translate>Progress</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('percent:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('percent:desc')}"></i>
|
||||
<a ng-click="changeFileListDisplayOrder('percent:desc', true)" ng-class="{true: 'default-cursor'}[task.multiDir]" translate>Progress</a>
|
||||
<i ng-if="!task.multiDir" class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('percent:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('percent:desc')}"></i>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<a ng-click="changeFileListDisplayOrder('size:asc', true)" translate>File Size</a>
|
||||
<i class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('size:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('size:desc')}"></i>
|
||||
<a ng-click="changeFileListDisplayOrder('size:asc', true)" ng-class="{true: 'default-cursor'}[task.multiDir]" translate>File Size</a>
|
||||
<i ng-if="!task.multiDir" class="fa" ng-class="{'fa-sort-asc fa-order-asc': isSetFileListDisplayOrder('size:asc'), 'fa-sort-desc fa-order-desc': isSetFileListDisplayOrder('size:desc')}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -226,21 +226,32 @@
|
|||
<i class="fa fa-file-archive-o"></i>
|
||||
<span translate>Archives</span>
|
||||
</button>
|
||||
<button class="btn btn-xs btn-success" ng-click="saveChoosedFiles()" ng-disabled="getSelectedFileCount() < 1" translate>Confirm</button>
|
||||
<button class="btn btn-xs btn-success" ng-click="saveChoosedFiles()" ng-disabled="!isAnyFileSelected()" translate>Confirm</button>
|
||||
<button class="btn btn-xs btn-default" ng-click="cancelChooseFiles()" translate>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-table-body">
|
||||
<div class="row" ng-repeat="file in task.files | fileOrderBy: getFileListOrderType()" data-file-index="{{file.index}}">
|
||||
<div class="col-sm-8">
|
||||
<div class="row" ng-repeat="file in task.files | fileOrderBy: getFileListOrderType()"
|
||||
ng-if="!context.collapsedDirs[file.relativePath]" data-file-index="{{file.index}}">
|
||||
<div class="col-sm-10" ng-if="file.isDir" style="{{'padding-left: ' + (file.level * 16) + 'px'}}">
|
||||
<i class="icon-expand pointer-cursor fa" ng-click="collapseDir(file)"
|
||||
ng-class="{true: 'fa-plus', false: 'fa-minus'}[!!context.collapsedDirs[file.nodePath]]"
|
||||
title="{{(context.collapsedDirs[file.nodePath] ? 'Expand' : 'Collapse') | translate}}"></i>
|
||||
<div class="checkbox checkbox-primary checkbox-inline">
|
||||
<input id="{{'node_' + file.nodePath}}" type="checkbox" ng-disabled="!task || !task.files || task.files.length <= 1 || (task.status !== 'waiting' && task.status !== 'paused')"
|
||||
ng-model="file.selected" ng-indeterminate="file.partialSelected" ng-change="setSelectedNode(file)"/>
|
||||
<label for="{{'node_' + file.nodePath}}" class="allow-word-break" ng-bind="file.nodeName" title="{{file.nodeName}}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8" ng-if="!file.isDir" style="{{'padding-left: ' + (11 + 3 + 4 + file.level * 16) + 'px'}}">
|
||||
<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()"/>
|
||||
<input id="{{'file_' + file.index}}" type="checkbox" ng-disabled="!task || !task.files || task.files.length <= 1 || (task.status !== 'waiting' && task.status !== 'paused')"
|
||||
ng-model="file.selected" ng-change="setSelectedFile(true)"/>
|
||||
<label for="{{'file_' + file.index}}" class="allow-word-break" ng-bind="file.fileName" title="{{file.fileName}}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2" ng-if="!file.isDir">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-primary" role="progressbar"
|
||||
aria-valuenow="{{file.completePercent}}" aria-valuemin="1"
|
||||
|
|
Reference in a new issue