# This is a combination of 3 commits.
# The first commit's message is: feat(uploader): huge uploader update - creted uploader options - added `file type` support - added headers to xhr - rename FileUploaderSettings => FileUploaderOptionsInterface - added public methods set Options - created filter from set options - added demo component # The 2nd commit message will be skipped: # rename FileUploaderSettings => FileUploaderOptionsInterface # The 3rd commit message will be skipped: # added public method setOptions
This commit is contained in:
committed by
Dmitriy Shekhovtsov
parent
ff6825c8cb
commit
d938aa1c39
@@ -32,7 +32,7 @@ export class FileItem {
|
||||
this.options = options;
|
||||
this.file = new FileLikeObject(some);
|
||||
this._file = some;
|
||||
this.url = uploader.url;
|
||||
this.url = uploader.options.url;
|
||||
this._zone = new NgZone({ enableLongStackTrace: false });
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ export class FileItem {
|
||||
public _onComplete(response:any, status:any, headers:any):void {
|
||||
this.onComplete(response, status, headers);
|
||||
|
||||
if (this.uploader.removeAfterUpload) {
|
||||
if (this.uploader.options.removeAfterUpload) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
158
components/file-upload/file-type.ts
Normal file
158
components/file-upload/file-type.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
export class FileType {
|
||||
/* MS office */
|
||||
static mime_doc = [
|
||||
'application/msword',
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'application/vnd.ms-word.document.macroEnabled.12',
|
||||
'application/vnd.ms-word.template.macroEnabled.12'
|
||||
];
|
||||
static mime_xsl = [
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'application/vnd.ms-excel.sheet.macroEnabled.12',
|
||||
'application/vnd.ms-excel.template.macroEnabled.12',
|
||||
'application/vnd.ms-excel.addin.macroEnabled.12',
|
||||
'application/vnd.ms-excel.sheet.binary.macroEnabled.12'
|
||||
];
|
||||
static mime_ppt = [
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.ms-powerpoint',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'application/vnd.ms-powerpoint.addin.macroEnabled.12',
|
||||
'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
|
||||
'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
|
||||
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'
|
||||
];
|
||||
|
||||
/* PSD */
|
||||
static mime_psd = [
|
||||
'image/photoshop',
|
||||
'image/x-photoshop',
|
||||
'image/psd',
|
||||
'application/photoshop',
|
||||
'application/psd',
|
||||
'zz-application/zz-winassoc-psd'
|
||||
];
|
||||
|
||||
/* Compressed files */
|
||||
static mime_compress = [
|
||||
'application/x-gtar',
|
||||
'application/x-gcompress',
|
||||
'application/compress',
|
||||
'application/x-tar',
|
||||
'application/x-rar-compressed',
|
||||
'application/octet-stream'
|
||||
];
|
||||
|
||||
static getMimeClass(file) {
|
||||
let mimeClass = 'application';
|
||||
if (this.mime_psd.indexOf(file.type) !== -1) {
|
||||
mimeClass = 'image';
|
||||
} else if (file.type.match('image.*')) {
|
||||
mimeClass = 'image';
|
||||
} else if (file.type.match('video.*')) {
|
||||
mimeClass = 'video';
|
||||
} else if (file.type.match('audio.*')) {
|
||||
mimeClass = 'audio';
|
||||
} else if (file.type === 'application/pdf') {
|
||||
mimeClass = 'pdf';
|
||||
} else if (this.mime_compress.indexOf(file.type) !== -1) {
|
||||
mimeClass = 'compress';
|
||||
} else if (this.mime_doc.indexOf(file.type) !== -1) {
|
||||
mimeClass = 'doc';
|
||||
} else if (this.mime_xsl.indexOf(file.type) !== -1) {
|
||||
mimeClass = 'xls';
|
||||
} else if (this.mime_ppt.indexOf(file.type) !== -1) {
|
||||
mimeClass = 'ppt';
|
||||
}
|
||||
if (mimeClass === 'application') {
|
||||
mimeClass = this.fileTypeDetection(file.name);
|
||||
}
|
||||
|
||||
|
||||
return mimeClass;
|
||||
}
|
||||
|
||||
|
||||
static fileTypeDetection(inputFilename) {
|
||||
let types = {
|
||||
'jpg': 'image',
|
||||
'jpeg': 'image',
|
||||
'tif': 'image',
|
||||
'psd': 'image',
|
||||
'bmp': 'image',
|
||||
'png': 'image',
|
||||
'nef': 'image',
|
||||
'tiff': 'image',
|
||||
'cr2': 'image',
|
||||
'dwg': 'image',
|
||||
'cdr': 'image',
|
||||
'ai': 'image',
|
||||
'indd': 'image',
|
||||
'pin': 'image',
|
||||
'cdp': 'image',
|
||||
'skp': 'image',
|
||||
'stp': 'image',
|
||||
'3dm': 'image',
|
||||
'mp3': 'audio',
|
||||
'wav': 'audio',
|
||||
'wma': 'audio',
|
||||
'mod': 'audio',
|
||||
'm4a': 'audio',
|
||||
'compress': 'compress',
|
||||
'rar': 'compress',
|
||||
'7z': 'compress',
|
||||
'lz': 'compress',
|
||||
'z01': 'compress',
|
||||
'pdf': 'pdf',
|
||||
'xls': 'xls',
|
||||
'xlsx': 'xls',
|
||||
'ods': 'xls',
|
||||
'mp4': 'video',
|
||||
'avi': 'video',
|
||||
'wmv': 'video',
|
||||
'mpg': 'video',
|
||||
'mts': 'video',
|
||||
'flv': 'video',
|
||||
'3gp': 'video',
|
||||
'vob': 'video',
|
||||
'm4v': 'video',
|
||||
'mpeg': 'video',
|
||||
'm2ts': 'video',
|
||||
'mov': 'video',
|
||||
'doc': 'doc',
|
||||
'docx': 'doc',
|
||||
'eps': 'doc',
|
||||
'rtf': 'doc',
|
||||
'txt': 'doc',
|
||||
'odt': 'doc',
|
||||
'rtf': 'doc',
|
||||
'ppt': 'ppt',
|
||||
'pptx': 'ppt',
|
||||
'pps': 'ppt',
|
||||
'ppsx': 'ppt',
|
||||
'odp': 'ppt'
|
||||
};
|
||||
|
||||
let chunks = inputFilename.split('.');
|
||||
if (chunks.length < 2) {
|
||||
return 'application';
|
||||
}
|
||||
let extension = chunks[chunks.length - 1].toLowerCase();
|
||||
if (types[extension] === undefined) {
|
||||
return 'application';
|
||||
} else {
|
||||
return types[extension];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +1,85 @@
|
||||
import {FileLikeObject} from './file-like-object.class';
|
||||
import {FileItem} from './file-item.class';
|
||||
function isFile(value:any):boolean {
|
||||
import {FileType} from './file-type';
|
||||
function isFile(value: any) {
|
||||
return (File && value instanceof File);
|
||||
}
|
||||
// function isFileLikeObject(value:any) {
|
||||
// return value instanceof FileLikeObject;
|
||||
// }
|
||||
export class FileUploader {
|
||||
public url:string;
|
||||
public authToken:string;
|
||||
public isUploading:boolean = false;
|
||||
public queue:Array<any> = [];
|
||||
public progress:number = 0;
|
||||
public autoUpload:boolean = false;
|
||||
public isHTML5:boolean = true;
|
||||
public removeAfterUpload:boolean = false;
|
||||
public queueLimit:number;
|
||||
public _nextIndex:number = 0;
|
||||
public filters:Array<any> = [];
|
||||
public options:any;
|
||||
private _failFilterIndex:number;
|
||||
export interface Headers {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
public constructor(options:any) {
|
||||
// Object.assign(this, options);
|
||||
this.url = options.url;
|
||||
this.authToken = options.authToken;
|
||||
this.autoUpload = options.autoUpload;
|
||||
this.filters.unshift({name: 'queueLimit', fn: this._queueLimitFilter});
|
||||
this.filters.unshift({name: 'folder', fn: this._folderFilter});
|
||||
export interface FileUploaderOptionsInterface {
|
||||
allowedMimeType?: Array<string>;
|
||||
allowedFileType?: Array<string>;
|
||||
autoUpload?:boolean;
|
||||
isHTML5?:boolean;
|
||||
filters?:Array<any>;
|
||||
headers?: Array<Headers>;
|
||||
maxFileSize?: number;
|
||||
queueLimit?:number;
|
||||
removeAfterUpload?:boolean;
|
||||
url?:string;
|
||||
}
|
||||
|
||||
export class FileUploader {
|
||||
|
||||
public authToken: string;
|
||||
public isUploading: boolean = false;
|
||||
public queue: Array<any> = [];
|
||||
public progress: number = 0;
|
||||
public _nextIndex:number = 0;
|
||||
public options:any;
|
||||
private _failFilterIndex: number;
|
||||
|
||||
public options: FileUploaderOptionsInterface = {
|
||||
autoUpload: false,
|
||||
isHTML5: true,
|
||||
filters: [],
|
||||
removeAfterUpload: false,
|
||||
};
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public addToQueue(files:any[], options:any, filters:any):void {
|
||||
let list:any[] = [];
|
||||
public setOptions(options: any) {
|
||||
this.options = Object.assign(this.options, options);
|
||||
|
||||
this.authToken = options.authToken;
|
||||
this.autoUpload = options.autoUpload;
|
||||
this.options.filters.unshift({name: 'queueLimit', fn: this._queueLimitFilter});
|
||||
|
||||
if (this.options.maxFileSize) {
|
||||
this.options.filters.unshift({name: 'fileSize', fn: this._fileSizeFilter});
|
||||
}
|
||||
|
||||
if (this.options.allowedFileType) {
|
||||
this.options.filters.unshift({name: 'fileType', fn: this._fileTypeFilter});
|
||||
}
|
||||
|
||||
if (this.options.allowedMimeType) {
|
||||
this.options.filters.unshift({name: 'mimeType', fn: this._mimeTypeFilter});
|
||||
}
|
||||
|
||||
// this.options.filters.unshift({name: 'folder', fn: this._folderFilter});
|
||||
}
|
||||
|
||||
|
||||
public addToQueue(files: any[], options?: any, filters?: any) {
|
||||
let list: any[] = [];
|
||||
for (let file of files) {
|
||||
list.push(file);
|
||||
}
|
||||
let arrayOfFilters = this._getFilters(filters);
|
||||
let count = this.queue.length;
|
||||
let addedFileItems:any[] = [];
|
||||
let addedFileItems: any[] = [];
|
||||
list.map((some:any) => {
|
||||
if (!options) {
|
||||
options = this.options;
|
||||
}
|
||||
|
||||
let temp = new FileLikeObject(some);
|
||||
if (this._isValidFile(temp, arrayOfFilters, options)) {
|
||||
let fileItem = new FileItem(this, some, options);
|
||||
@@ -55,7 +96,7 @@ export class FileUploader {
|
||||
this.progress = this._getTotalProgress();
|
||||
}
|
||||
this._render();
|
||||
if (this.autoUpload) {
|
||||
if (this.options.autoUpload) {
|
||||
this.uploadAll();
|
||||
}
|
||||
}
|
||||
@@ -80,7 +121,7 @@ export class FileUploader {
|
||||
public uploadItem(value:FileItem):void {
|
||||
let index = this.getIndexOfItem(value);
|
||||
let item = this.queue[index];
|
||||
let transport = this.isHTML5 ? '_xhrTransport' : '_iframeTransport';
|
||||
let transport = this.options.isHTML5 ? '_xhrTransport' : '_iframeTransport';
|
||||
item._prepareToUploading();
|
||||
if (this.isUploading) {
|
||||
return;
|
||||
@@ -92,7 +133,7 @@ export class FileUploader {
|
||||
public cancelItem(value:any):void {
|
||||
let index = this.getIndexOfItem(value);
|
||||
let item = this.queue[index];
|
||||
let prop = this.isHTML5 ? '_xhr' : '_form';
|
||||
let prop = this.options.isHTML5 ? '_xhr' : '_form';
|
||||
if (item && item.isUploading) {
|
||||
item[prop].abort();
|
||||
}
|
||||
@@ -175,8 +216,19 @@ export class FileUploader {
|
||||
return {item, response, status, headers};
|
||||
}
|
||||
|
||||
public onCancelItem(item:any, response:any, status:any, headers:any):any {
|
||||
return {item, response, status, headers};
|
||||
private _mimeTypeFilter(item: any) {
|
||||
return !(this.options.allowedMimeType && this.options.allowedMimeType.indexOf(item.type) === -1);
|
||||
}
|
||||
|
||||
private _fileSizeFilter(item: any) {
|
||||
return !(this.options.maxFileSize && item.size > this.options.maxFileSize);
|
||||
}
|
||||
|
||||
private _fileTypeFilter(item: any) {
|
||||
return !(this.options.allowedFileType &&
|
||||
this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public onCompleteItem(item:any, response:any, status:any, headers:any):any {
|
||||
@@ -207,7 +259,7 @@ export class FileUploader {
|
||||
}
|
||||
|
||||
protected _headersGetter(parsedHeaders:any):any {
|
||||
return (name:any) => {
|
||||
return (name: any) => {
|
||||
if (name) {
|
||||
return parsedHeaders[name.toLowerCase()] || void 0;
|
||||
}
|
||||
@@ -259,6 +311,11 @@ export class FileUploader {
|
||||
/*item.headers.map((value, name) => {
|
||||
xhr.setRequestHeader(name, value);
|
||||
});*/
|
||||
if (this.options.headers) {
|
||||
for (let header of this.options.headers) {
|
||||
xhr.setRequestHeader(header.name, header.value);
|
||||
}
|
||||
}
|
||||
if (this.authToken) {
|
||||
xhr.setRequestHeader('Authorization', this.authToken);
|
||||
}
|
||||
|
||||
3
demo/components/file-upload/zs-file-demo/demo.html
Normal file
3
demo/components/file-upload/zs-file-demo/demo.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<label class="btn btn-primary">Select File
|
||||
<input type="file" (change)="onChange($event)" [multiple]="multiple" style="display: none;"/>
|
||||
</label>
|
||||
124
demo/components/file-upload/zs-file-demo/demo.ts
Normal file
124
demo/components/file-upload/zs-file-demo/demo.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import {Component, EventEmitter, ElementRef, Renderer, Input} from 'angular2/core';
|
||||
import {FileUploader, FileUploaderOptionsInterface} from '../../../../ng2-file-upload';
|
||||
|
||||
@Component({
|
||||
selector: 'demo-file-upload',
|
||||
providers: [FileUploader],
|
||||
directives: [],
|
||||
pipes: [],
|
||||
host: {
|
||||
'(drop)': 'onDrop($event)',
|
||||
'(dragover)': 'onDragOver($event)',
|
||||
'(dragleave)': 'onDragLeave($event)',
|
||||
'[class.hover]': 'isHover'
|
||||
},
|
||||
template: require('./demo.html'),
|
||||
styles: [':host {border:1px solid black; padding:59px;display: block;}' +
|
||||
'.hover {border: 3px solid green; backgroud: black;}']
|
||||
})
|
||||
export class DemoFileUpload {
|
||||
|
||||
@Input() url: string;
|
||||
@Input() queueLimit: number;
|
||||
@Input() maxFileSize: number;
|
||||
@Input() autoUpload: boolean;
|
||||
@Input() allowedMimeType: Array<string>;
|
||||
@Input() allowedFileType: Array<string>;
|
||||
@Input() headers: Array<any>;
|
||||
|
||||
private inputs = ['allowedMimeType',
|
||||
'allowedFileType',
|
||||
'autoUpload',
|
||||
'isHTML5',
|
||||
'headers',
|
||||
'maxFileSize',
|
||||
'queueLimit',
|
||||
'removeAfterUpload',
|
||||
'url',
|
||||
];
|
||||
|
||||
private uploaderOptions: FileUploaderOptionsInterface = {};
|
||||
|
||||
private isHover: boolean = false;
|
||||
private multiple: boolean = true;
|
||||
|
||||
constructor(private element: ElementRef,
|
||||
private fileUploadService: FileUploader,
|
||||
private renderer: Renderer) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
for (let input of this.inputs) {
|
||||
if (this[input]) {
|
||||
this.uploaderOptions[input] = this[input];
|
||||
}
|
||||
}
|
||||
this.fileUploadService.setOptions(this.uploaderOptions);
|
||||
|
||||
this.multiple = (!this.queueLimit || this.queueLimit > 1);
|
||||
}
|
||||
|
||||
|
||||
onDrop(event: any) {
|
||||
this._preventAndStop(event);
|
||||
this.isHover = false;
|
||||
|
||||
let transfer = this._getTransfer(event);
|
||||
if (!transfer) {
|
||||
return;
|
||||
}
|
||||
this.fileUploadService.addToQueue(transfer.files);
|
||||
}
|
||||
|
||||
onDragOver(event: any) {
|
||||
this._preventAndStop(event);
|
||||
|
||||
if (this.isHover) {
|
||||
return;
|
||||
}
|
||||
|
||||
let transfer = this._getTransfer(event);
|
||||
if (!this._haveFiles(transfer.types)) {
|
||||
return;
|
||||
}
|
||||
this.isHover = true;
|
||||
}
|
||||
|
||||
onDragLeave(event: any): any {
|
||||
this._preventAndStop(event);
|
||||
if (event.currentTarget === (<any>this).element[0]) {
|
||||
return;
|
||||
}
|
||||
this.isHover = false;
|
||||
}
|
||||
|
||||
onChange($event) {
|
||||
this.fileUploadService.addToQueue($event.srcElement.files);
|
||||
}
|
||||
|
||||
|
||||
private _getTransfer(event: any): any {
|
||||
return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer;
|
||||
}
|
||||
|
||||
private _preventAndStop(event: any): any {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
private _haveFiles(types: any): any {
|
||||
if (!types) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (types.indexOf) {
|
||||
return types.indexOf('Files') !== -1;
|
||||
} else if (types.contains) {
|
||||
return types.contains('Files');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user