support select files by file extension

master
MaysWind 2018-11-11 20:27:32 +08:00
parent c21c77ff99
commit e42884a50f
6 changed files with 390 additions and 190 deletions

View File

@ -5,6 +5,7 @@ Error=错误
OK=确定 OK=确定
Confirm=确认 Confirm=确认
Cancel=取消 Cancel=取消
Close=关闭
True=是 True=是
False=否 False=否
Connecting=连接中 Connecting=连接中
@ -100,6 +101,9 @@ Pictures=图片
Documents=文档 Documents=文档
Applications=应用程序 Applications=应用程序
Archives=存档文件 Archives=存档文件
Other=其他
Custom=自定义
Custom Choose File=自定义选择文件
Address=地址 Address=地址
Client=客户端 Client=客户端
Status=状态 Status=状态

View File

@ -5,6 +5,7 @@ Error=錯誤
OK=確定 OK=確定
Confirm=確認 Confirm=確認
Cancel=取消 Cancel=取消
Close=關閉
True=是 True=是
False=否 False=否
Connecting=連線中 Connecting=連線中
@ -100,6 +101,9 @@ Pictures=圖片
Documents=文件 Documents=文件
Applications=應用程式 Applications=應用程式
Archives=封存檔案 Archives=封存檔案
Other=其他
Custom=自訂
Custom Choose File=自訂選擇檔案
Address=位址 Address=位址
Client=客戶端 Client=客戶端
Status=狀態 Status=狀態

View File

@ -9,6 +9,7 @@
'OK': 'OK', 'OK': 'OK',
'Confirm': 'Confirm', 'Confirm': 'Confirm',
'Cancel': 'Cancel', 'Cancel': 'Cancel',
'Close': 'Close',
'True': 'True', 'True': 'True',
'False': 'False', 'False': 'False',
'Connecting': 'Connecting', 'Connecting': 'Connecting',
@ -104,6 +105,9 @@
'Documents': 'Documents', 'Documents': 'Documents',
'Applications': 'Applications', 'Applications': 'Applications',
'Archives': 'Archives', 'Archives': 'Archives',
'Other': 'Other',
'Custom': 'Custom',
'Custom Choose File': 'Custom Choose File',
'Address': 'Address', 'Address': 'Address',
'Client': 'Client', 'Client': 'Client',
'Status': 'Status', 'Status': 'Status',

View File

@ -1,194 +1,212 @@
(function () { (function () {
'use strict'; 'use strict';
angular.module('ariaNg').constant('ariaNgFileTypes', { angular.module('ariaNg').constant('ariaNgFileTypes', {
video: [ video: {
'.3g2', name: 'Videos',
'.3gp', extensions: [
'.3gp2', '.3g2',
'.3gpp', '.3gp',
'.asf', '.3gp2',
'.asx', '.3gpp',
'.avi', '.asf',
'.dat', '.asx',
'.divx', '.avi',
'.flv', '.dat',
'.m1v', '.divx',
'.m2ts', '.flv',
'.m2v', '.m1v',
'.m4v', '.m2ts',
'.mkv', '.m2v',
'.mov', '.m4v',
'.mp4', '.mkv',
'.mpe', '.mov',
'.mpeg', '.mp4',
'.mpg', '.mpe',
'.mts', '.mpeg',
'.ogv', '.mpg',
'.qt', '.mts',
'.ram', '.ogv',
'.rm', '.qt',
'.rmvb', '.ram',
'.ts', '.rm',
'.vob', '.rmvb',
'.wmv' '.ts',
], '.vob',
audio: [ '.wmv'
'.aac', ]
'.ac3', },
'.adts', audio: {
'.amr', name: 'Audios',
'.ape', extensions: [
'.eac3', '.aac',
'.flac', '.ac3',
'.m1a', '.adts',
'.m2a', '.amr',
'.m4a', '.ape',
'.mid', '.eac3',
'.mka', '.flac',
'.mp2', '.m1a',
'.mp3', '.m2a',
'.mpa', '.m4a',
'.mpc', '.mid',
'.ogg', '.mka',
'.ra', '.mp2',
'.tak', '.mp3',
'.vqf', '.mpa',
'.wm', '.mpc',
'.wav', '.ogg',
'.wma', '.ra',
'.wv' '.tak',
], '.vqf',
picture: [ '.wm',
'.abr', '.wav',
'.bmp', '.wma',
'.emf', '.wv'
'.gif', ]
'.j2c', },
'.j2k', picture: {
'.jfif', name: 'Pictures',
'.jif', extensions: [
'.jp2', '.abr',
'.jpc', '.bmp',
'.jpe', '.emf',
'.jpeg', '.gif',
'.jpf', '.j2c',
'.jpg', '.j2k',
'.jpk', '.jfif',
'.jpx', '.jif',
'.pcx', '.jp2',
'.pct', '.jpc',
'.pic', '.jpe',
'.pict', '.jpeg',
'.png', '.jpf',
'.pns', '.jpg',
'.psd', '.jpk',
'.psdx', '.jpx',
'.raw', '.pcx',
'.svg', '.pct',
'.svgz', '.pic',
'.tga', '.pict',
'.tif', '.png',
'.tiff', '.pns',
'.wbm', '.psd',
'.wbmp', '.psdx',
'.webp', '.raw',
'.wmf', '.svg',
'.xif' '.svgz',
], '.tga',
document: [ '.tif',
'.csv', '.tiff',
'.doc', '.wbm',
'.docm', '.wbmp',
'.docx', '.webp',
'.dot', '.wmf',
'.dotm', '.xif'
'.dotx', ]
'.key', },
'.mpp', document: {
'.numbers', name: 'Documents',
'.odp', extensions: [
'.ods', '.csv',
'.odt', '.doc',
'.pages', '.docm',
'.pdf', '.docx',
'.pot', '.dot',
'.potm', '.dotm',
'.potx', '.dotx',
'.pps', '.key',
'.ppsm', '.mpp',
'.ppsx', '.numbers',
'.ppt', '.odp',
'.pptm', '.ods',
'.pptx', '.odt',
'.rtf', '.pages',
'.txt', '.pdf',
'.vsd', '.pot',
'.vsdx', '.potm',
'.wk1', '.potx',
'.wk2', '.pps',
'.wk3', '.ppsm',
'.wk4', '.ppsx',
'.wks', '.ppt',
'.wpd', '.pptm',
'.wps', '.pptx',
'.xla', '.rtf',
'.xlam', '.txt',
'.xll', '.vsd',
'.xlm', '.vsdx',
'.xls', '.wk1',
'.xlsb', '.wk2',
'.xlsm', '.wk3',
'.xlsx', '.wk4',
'.xlt', '.wks',
'.xltx', '.wpd',
'.xlw', '.wps',
'.xps' '.xla',
], '.xlam',
application: [ '.xll',
'.apk', '.xlm',
'.bat', '.xls',
'.com', '.xlsb',
'.deb', '.xlsm',
'.dll', '.xlsx',
'.dmg', '.xlt',
'.exe', '.xltx',
'.ipa', '.xlw',
'.jar', '.xps'
'.msi', ]
'.rpm', },
'.sh' application: {
], name: 'Applications',
archive: [ extensions: [
'.001', '.apk',
'.7z', '.bat',
'.ace', '.com',
'.arj', '.deb',
'.bz2', '.dll',
'.cab', '.dmg',
'.cbr', '.exe',
'.cbz', '.ipa',
'.gz', '.jar',
'.img', '.msi',
'.iso', '.rpm',
'.lzh', '.sh'
'.qcow2', ]
'.r', },
'.rar', archive: {
'.sef', name: 'Archives',
'.tar', extensions: [
'.taz', '.001',
'.tbz', '.7z',
'.tbz2', '.ace',
'.uue', '.arj',
'.vdi', '.bz2',
'.vhd', '.cab',
'.vmdk', '.cbr',
'.wim', '.cbz',
'.xar', '.gz',
'.xz', '.img',
'.z', '.iso',
'.zip' '.lzh',
] '.qcow2',
'.r',
'.rar',
'.sef',
'.tar',
'.taz',
'.tbz',
'.tbz2',
'.uue',
'.vdi',
'.vhd',
'.vmdk',
'.wim',
'.xar',
'.xz',
'.z',
'.zip'
]
}
}); });
}()); }());

View File

@ -194,6 +194,7 @@
currentTab: 'overview', currentTab: 'overview',
isEnableSpeedChart: ariaNgSettingService.getDownloadTaskRefreshInterval() > 0, isEnableSpeedChart: ariaNgSettingService.getDownloadTaskRefreshInterval() > 0,
showChooseFilesToolbar: false, showChooseFilesToolbar: false,
fileExtensions: [],
collapsedDirs: {}, collapsedDirs: {},
btPeers: [], btPeers: [],
healthPercent: 0, healthPercent: 0,
@ -342,7 +343,7 @@
} }
var files = $scope.task.files; var files = $scope.task.files;
var extensions = ariaNgFileTypes[type]; var extensions = ariaNgFileTypes[type].extensions;
var fileIndexes = []; var fileIndexes = [];
var isAllSelected = true; var isAllSelected = true;
@ -395,6 +396,143 @@
} }
}; };
$scope.showCustomChooseFileModal = function () {
if (!$scope.task || !$scope.task.files) {
return;
}
var files = $scope.task.files;
var extensionsMap = {};
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();
}
var extensionInfo = extensionsMap[extension];
if (!extensionInfo) {
var extensionName = extension;
if (extensionName.length > 0 && extensionName.charAt(0) === '.') {
extensionName = extensionName.substring(1);
}
extensionInfo = {
extension: extensionName,
classified: false,
selected: false,
selectedCount: 0,
unSelectedCount: 0
};
extensionsMap[extension] = extensionInfo;
}
if (file.selected) {
extensionInfo.selected = true;
extensionInfo.selectedCount++;
} else {
extensionInfo.unSelectedCount++;
}
}
var allClassifiedExtensions = {};
for (var type in ariaNgFileTypes) {
if (!ariaNgFileTypes.hasOwnProperty(type)) {
continue;
}
var extensionTypeName = ariaNgFileTypes[type].name;
var allExtensions = ariaNgFileTypes[type].extensions;
var extensions = [];
for (var i = 0; i < allExtensions.length; i++) {
var extension = allExtensions[i];
var extensionInfo = extensionsMap[extension];
if (extensionInfo) {
extensionInfo.classified = true;
extensions.push(extensionInfo);
}
}
if (extensions.length > 0) {
allClassifiedExtensions[type] = {
name: extensionTypeName,
extensions: extensions
};
}
}
var unClassifiedExtensions = [];
for (var extension in extensionsMap) {
if (!extensionsMap.hasOwnProperty(extension)) {
continue;
}
var extensionInfo = extensionsMap[extension];
if (!extensionInfo.classified) {
unClassifiedExtensions.push(extensionInfo);
}
}
if (unClassifiedExtensions.length > 0) {
allClassifiedExtensions.other = {
name: 'Other',
extensions: unClassifiedExtensions
};
}
$scope.context.fileExtensions = allClassifiedExtensions;
angular.element('#custom-choose-file-modal').modal();
};
$scope.setSelectedExtension = function (selectedExtension, selected) {
if (!$scope.task || !$scope.task.files) {
return;
}
var files = $scope.task.files;
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();
}
if (extension !== '.' + selectedExtension) {
continue;
}
file.selected = selected;
}
updateAllDirNodesSelectedStatus();
};
$('#custom-choose-file-modal').on('hide.bs.modal', function (e) {
$scope.context.fileExtensions = null;
});
$scope.setSelectedFile = function (updateNodeSelectedStatus) { $scope.setSelectedFile = function (updateNodeSelectedStatus) {
if (updateNodeSelectedStatus) { if (updateNodeSelectedStatus) {
updateAllDirNodesSelectedStatus(); updateAllDirNodesSelectedStatus();

View File

@ -235,6 +235,10 @@
<i class="fa fa-file-archive-o"></i> <i class="fa fa-file-archive-o"></i>
<span translate>Archives</span> <span translate>Archives</span>
</button> </button>
<button class="btn btn-xs btn-default" ng-click="showCustomChooseFileModal()">
<i class="fa fa-filter"></i>
<span translate>Custom</span>
</button>
<button class="btn btn-xs btn-success" ng-click="saveChoosedFiles()" ng-disabled="!isAnyFileSelected()" 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> <button class="btn btn-xs btn-default" ng-click="cancelChooseFiles()" translate>Cancel</button>
</div> </div>
@ -369,4 +373,32 @@
</li> </li>
</ul> </ul>
</div> </div>
<div id="custom-choose-file-modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" translate>Custom Choose File</h4>
</div>
<div class="modal-body no-padding">
<div class="settings-table striped hoverable">
<div class="row" ng-repeat="(extensionTypeName, extensionTypeInfo) in context.fileExtensions">
<div class="setting-key setting-key-without-desc col-sm-4" ng-bind="extensionTypeInfo.name | translate"></div>
<div class="setting-value col-sm-8">
<div class="checkbox checkbox-primary checkbox-inline" ng-repeat="info in extensionTypeInfo.extensions">
<input id="{{info.extension}}" type="checkbox" ng-model="info.selected"
ng-indeterminate="info.selectedCount > 0 && info.unSelectedCount > 0"
ng-change="setSelectedExtension(info.extension, info.selected)">
<label for="{{info.extension}}" ng-bind="info.extension"></label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" translate>Close</button>
</div>
</div>
</div>
</div>
</section> </section>