Fixing Issues with file upload and adding more Helper classes!
This commit is contained in:
@@ -1,237 +1,235 @@
|
|||||||
export class FileChunk {
|
export class FileChunk {
|
||||||
public stepSize:number = 1024 * 1024 * 3;
|
public stepSize: number = 1024 * 1024 * 3;
|
||||||
public rawFile:any = null;
|
public rawFile: any = null;
|
||||||
public uploadProgress:number = null;
|
public uploadProgress: number = null;
|
||||||
public uploading:boolean = null;
|
public uploading: boolean = null;
|
||||||
public uploadComplete:boolean = null;
|
public uploadComplete: boolean = null;
|
||||||
public byteStepSize:number = null;
|
public byteStepSize: number = null;
|
||||||
public totalSize:number = null;
|
public totalSize: number = null;
|
||||||
public startByte:number = null;
|
public startByte: number = null;
|
||||||
public endByte:number = null;
|
public endByte: number = null;
|
||||||
public currentChunk:number = 0;
|
public currentChunk: number = 0;
|
||||||
public totalChunks:number = null;
|
public totalChunks: number = null;
|
||||||
public uniqueIdentifier:string = null;
|
public uniqueIdentifier: string = null;
|
||||||
public totalSent:number = null;
|
public totalSent: number = null;
|
||||||
public extraData:any = {};
|
public extraData: any = {};
|
||||||
constructor(rawFile:any, options:any = {}) {
|
|
||||||
|
constructor(rawFile: any, options: any = {}) {
|
||||||
if (typeof options !== 'undefined'){
|
this.setByteStepSize(this.stepSize);
|
||||||
if (typeof options.byteStepSize !== 'undefined'){
|
if (typeof options !== 'undefined') {
|
||||||
this.setByteStepSize(options.byteStepSize);
|
if (typeof options.byteStepSize !== 'undefined') {
|
||||||
}
|
this.setByteStepSize(options.byteStepSize);
|
||||||
}
|
}
|
||||||
this.setRawFile(rawFile)
|
}
|
||||||
|
this.setRawFile(rawFile);
|
||||||
this.setRawFile(rawFile);
|
|
||||||
this.setUploadProgress(0);
|
this.setRawFile(rawFile);
|
||||||
this.setUploading(false);
|
this.setUploadProgress(0);
|
||||||
this.setUploadComplete(false);
|
this.setUploading(false);
|
||||||
this.setTotalSize(this.getRawFile().size);
|
this.setUploadComplete(false);
|
||||||
this.setStartByte(0);
|
this.setTotalSize(this.getRawFile().size);
|
||||||
this.setEndByte(this.getByteStepSize());
|
this.setStartByte(0);
|
||||||
this.setCurrentChunk(0);
|
this.setEndByte(this.getByteStepSize());
|
||||||
if (!this.getBrowserSliceMethod()){
|
this.setCurrentChunk(0);
|
||||||
this.setTotalChunks(1);
|
if (!this.getBrowserSliceMethod()) {
|
||||||
}
|
this.setTotalChunks(1);
|
||||||
else{
|
} else {
|
||||||
this.setTotalChunks(Math.ceil(this.totalSize / this.byteStepSize));
|
this.setTotalChunks(Math.ceil(this.totalSize / this.byteStepSize));
|
||||||
}
|
}
|
||||||
this.setUniqueIdenfier(this.generateUniqueIdentifier());
|
this.setUniqueIdenfier(this.generateUniqueIdentifier());
|
||||||
this.setTotalSent(0);
|
this.setTotalSent(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setExtraData(index:any, value:any){
|
public setExtraData(index: any, value: any) {
|
||||||
this.extraData[index] = value;
|
this.extraData[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getExtraData(index:any){
|
public getExtraData(index: any) {
|
||||||
return this.extraData[index];
|
return this.extraData[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
//getters and setters
|
//getters and setters
|
||||||
public setProgress(v:any){
|
public setProgress(v: any) {
|
||||||
this.uploadProgress = v;
|
this.uploadProgress = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProgress(){
|
public getProgress() {
|
||||||
return this.uploadProgress;
|
return this.uploadProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setUploading(v:boolean){
|
public setUploading(v: boolean) {
|
||||||
this.uploading = v;
|
this.uploading = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUploading(){
|
public getUploading() {
|
||||||
return this.uploading;
|
return this.uploading;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUploadComplete(){
|
public getUploadComplete() {
|
||||||
return this.uploadComplete;
|
return this.uploadComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setUploadComplete(v:boolean){
|
public setUploadComplete(v: boolean) {
|
||||||
this.uploadComplete = v;
|
this.uploadComplete = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setUploadProgress(v:number){
|
public setUploadProgress(v: number) {
|
||||||
this.uploadProgress = v;
|
this.uploadProgress = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUploadProgress(){
|
public getUploadProgress() {
|
||||||
return this.uploadProgress;
|
return this.uploadProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getStartByte(){
|
public getStartByte() {
|
||||||
return this.startByte;
|
return this.startByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setStartByte(v:number){
|
public setStartByte(v: number) {
|
||||||
this.startByte = v;
|
this.startByte = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEndByte(){
|
public getEndByte() {
|
||||||
return this.endByte;
|
return this.endByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setEndByte(v:number){
|
public setEndByte(v: number) {
|
||||||
this.endByte = v;
|
this.endByte = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getByteStepSize(){
|
public getByteStepSize() {
|
||||||
return this.byteStepSize;
|
return this.byteStepSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setByteStepSize(v:number){
|
public setByteStepSize(v: number) {
|
||||||
this.byteStepSize = v;
|
this.byteStepSize = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTotalSize(v:number){
|
public setTotalSize(v: number) {
|
||||||
this.totalSize = v;
|
this.totalSize = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTotalSize(){
|
public getTotalSize() {
|
||||||
return this.totalSize;
|
return this.totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRawFile(){
|
public getRawFile() {
|
||||||
return this.rawFile;
|
return this.rawFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setRawFile(v:File){
|
public setRawFile(v: File) {
|
||||||
this.rawFile = v;
|
this.rawFile = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrentChunk(){
|
public getCurrentChunk() {
|
||||||
return this.currentChunk;
|
return this.currentChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setCurrentChunk(v:number){
|
public setCurrentChunk(v: number) {
|
||||||
this.currentChunk = v;
|
this.currentChunk = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTotalChunks(){
|
public getTotalChunks() {
|
||||||
return this.totalChunks;
|
return this.totalChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTotalChunks(v:number){
|
public setTotalChunks(v: number) {
|
||||||
this.totalChunks = v;
|
this.totalChunks = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setUniqueIdenfier(v:string){
|
public setUniqueIdenfier(v: string) {
|
||||||
this.uniqueIdentifier = v;
|
this.uniqueIdentifier = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUniqueIdenfier(){
|
public getUniqueIdenfier() {
|
||||||
return this.uniqueIdentifier;
|
return this.uniqueIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRawFileExtension(){
|
public getRawFileExtension() {
|
||||||
const extension = this.getRawFileName().split('.');
|
const extension = this.getRawFileName().split('.');
|
||||||
return extension[extension.length - 1];
|
return extension[extension.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRawFileName(){
|
public getRawFileName() {
|
||||||
return this.getRawFile().name;
|
return this.getRawFile().name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getContentType(){
|
public getContentType() {
|
||||||
return this.getRawFile().type;
|
return this.getRawFile().type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTotalSent(){
|
public getTotalSent() {
|
||||||
return this.totalSent;
|
return this.totalSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTotalSent(v:number){
|
public setTotalSent(v: number) {
|
||||||
this.totalSent = v;
|
this.totalSent = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrentRawFileChunk(){
|
public getCurrentRawFileChunk() {
|
||||||
if (!this.getBrowserSliceMethod()){
|
if (!this.getBrowserSliceMethod()) {
|
||||||
return this.getRawFile();
|
return this.getRawFile();
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
return this.getRawFile()[this.getBrowserSliceMethod()](this.getStartByte(), this.getEndByte());
|
return this.getRawFile()[this.getBrowserSliceMethod()](this.getStartByte(), this.getEndByte());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public retrocedeChunk(){
|
public retrocedeChunk() {
|
||||||
if (!this.getBrowserSliceMethod()){
|
if (!this.getBrowserSliceMethod()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setEndByte(this.getStartByte());
|
this.setEndByte(this.getStartByte());
|
||||||
this.setStartByte(this.getStartByte() - this.getByteStepSize());
|
this.setStartByte(this.getStartByte() - this.getByteStepSize());
|
||||||
this.setCurrentChunk(this.getCurrentChunk() - 1);
|
this.setCurrentChunk(this.getCurrentChunk() - 1);
|
||||||
|
|
||||||
if (this.getTotalSent() != 0){
|
if (this.getTotalSent() != 0) {
|
||||||
this.setTotalSent(this.getTotalSent() - this.getByteStepSize());
|
this.setTotalSent(this.getTotalSent() - this.getByteStepSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareNextChunk(){
|
public prepareNextChunk() {
|
||||||
if (!this.getBrowserSliceMethod()){
|
if (!this.getBrowserSliceMethod()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (this.getEndByte() > this.getTotalSize() && this.getCurrentChunk() < this.getTotalChunks()) { // finished
|
||||||
if (this.getEndByte() > this.getTotalSize()){ //finished
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
this.setStartByte(this.getEndByte());
|
||||||
|
this.setEndByte(this.getEndByte() + this.getByteStepSize());
|
||||||
this.setStartByte(this.getEndByte());
|
this.setCurrentChunk(this.getCurrentChunk() + 1);
|
||||||
this.setEndByte(this.getEndByte() + this.getByteStepSize());
|
if (this.getEndByte() > this.getTotalSize() && this.getCurrentChunk() === this.getTotalChunks()) {
|
||||||
this.setCurrentChunk(this.getCurrentChunk() + 1);
|
// something went wrong with the calculations
|
||||||
|
this.setEndByte(this.getTotalSize());
|
||||||
return true;
|
}
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
public getBrowserSliceMethod():string{
|
|
||||||
if (this.rawFile && typeof this.rawFile !== 'undefined'){
|
public getBrowserSliceMethod(): string {
|
||||||
if (this.rawFile.slice && typeof this.rawFile.slice == 'function'){
|
if (this.rawFile && typeof this.rawFile !== 'undefined') {
|
||||||
return 'slice';
|
if (this.rawFile.slice && typeof this.rawFile.slice === 'function') {
|
||||||
}
|
return 'slice';
|
||||||
else if(this.rawFile.mozSlice && typeof this.rawFile.mozSlice == 'function'){
|
}
|
||||||
return 'mozSlice';
|
else if (this.rawFile.mozSlice && typeof this.rawFile.mozSlice === 'function') {
|
||||||
}
|
return 'mozSlice';
|
||||||
else if(this.rawFile.webkitSlice && typeof this.rawFile.webkitSlice == 'function'){
|
}
|
||||||
return 'webkitSlice';
|
else if (this.rawFile.webkitSlice && typeof this.rawFile.webkitSlice === 'function') {
|
||||||
}
|
return 'webkitSlice';
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
return null;
|
else {
|
||||||
}
|
return null;
|
||||||
}//getBrowserSliceMethod() ends here
|
}
|
||||||
|
}//getBrowserSliceMethod() ends here
|
||||||
|
|
||||||
public generateUniqueIdentifier():string{
|
public generateUniqueIdentifier(): string{
|
||||||
var d = new Date().getTime();
|
let d = new Date().getTime();
|
||||||
|
|
||||||
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
|
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
|
||||||
d += performance.now(); //use high-precision timer if available
|
d += performance.now(); // use high-precision timer if available
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||||
var r = (d + Math.random() * 16) % 16 | 0;
|
const r = (d + Math.random() * 16) % 16 | 0;
|
||||||
d = Math.floor(d / 16);
|
d = Math.floor(d / 16);
|
||||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { FileChunk } from './file-chunk.class'
|
|||||||
export class FileItem {
|
export class FileItem {
|
||||||
public file: FileLikeObject;
|
public file: FileLikeObject;
|
||||||
public _file: File;
|
public _file: File;
|
||||||
|
public id: any;
|
||||||
public alias: string;
|
public alias: string;
|
||||||
public url: string = '/';
|
public url: string = '/';
|
||||||
public method: string;
|
public method: string;
|
||||||
@@ -25,6 +26,8 @@ export class FileItem {
|
|||||||
public _currentChunk: number = 0;
|
public _currentChunk: number = 0;
|
||||||
public _totalChunks: number = 0;
|
public _totalChunks: number = 0;
|
||||||
|
|
||||||
|
protected chunkTotalRetries = 10;
|
||||||
|
protected chunkRetries = 0;
|
||||||
protected uploader: FileUploader;
|
protected uploader: FileUploader;
|
||||||
protected some: File;
|
protected some: File;
|
||||||
protected options: FileUploaderOptions;
|
protected options: FileUploaderOptions;
|
||||||
@@ -56,10 +59,18 @@ export class FileItem {
|
|||||||
this._currentChunk = this.fileChunks.currentChunk;
|
this._currentChunk = this.fileChunks.currentChunk;
|
||||||
this._totalChunks = this.fileChunks.totalChunks;
|
this._totalChunks = this.fileChunks.totalChunks;
|
||||||
}
|
}
|
||||||
public getNextChunk():any{
|
public getCurrentChunkFile():any{
|
||||||
this.fileChunks.prepareNextChunk()
|
|
||||||
return this.fileChunks.getCurrentRawFileChunk();
|
return this.fileChunks.getCurrentRawFileChunk();
|
||||||
}
|
}
|
||||||
|
public prepareNextChunk():void{
|
||||||
|
this.fileChunks.prepareNextChunk();
|
||||||
|
}
|
||||||
|
public getCurrentChunk():any{
|
||||||
|
return this.fileChunks.getCurrentChunk()
|
||||||
|
}
|
||||||
|
public getTotalChunks():any{
|
||||||
|
return this.fileChunks.getTotalChunks()
|
||||||
|
}
|
||||||
public setIsUploading(val:boolean){
|
public setIsUploading(val:boolean){
|
||||||
this.isUploading = val;
|
this.isUploading = val;
|
||||||
if(this.fileChunks){
|
if(this.fileChunks){
|
||||||
@@ -73,6 +84,12 @@ export class FileItem {
|
|||||||
public get fileChunks(): FileChunk{
|
public get fileChunks(): FileChunk{
|
||||||
return this._fileChunks;
|
return this._fileChunks;
|
||||||
}
|
}
|
||||||
|
public getId(): any {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
public setId(id: any) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
this.uploader.cancelItem(this);
|
this.uploader.cancelItem(this);
|
||||||
}
|
}
|
||||||
@@ -175,14 +192,24 @@ export class FileItem {
|
|||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public _onCompleteChunk(response: string, status: number, headers: ParsedResponseHeaders): void{
|
public _onCompleteChunk(response: string, status: number, headers: ParsedResponseHeaders): void {
|
||||||
this._onCompleteChunkCallnext();
|
this.chunkRetries = 0;
|
||||||
|
this._onCompleteChunkCallNext();
|
||||||
this.onCompleteChunk(response, status, headers);
|
this.onCompleteChunk(response, status, headers);
|
||||||
}
|
}
|
||||||
public _onCompleteChunkCallnext(): void{
|
public _onCompleteChunkCallNext(): void{
|
||||||
|
//Let's Retry to send this chunk 4 times;
|
||||||
|
}
|
||||||
|
public _onErrorChunk(response: string, status: number, headers: ParsedResponseHeaders): void {
|
||||||
|
if (this.chunkRetries > this.chunkTotalRetries) {
|
||||||
|
this.uploader.onErrorItem(this, response, status, headers);
|
||||||
|
this.uploader.onCompleteItem(this, response, status, headers);
|
||||||
|
} else {
|
||||||
|
this.chunkRetries ++;
|
||||||
|
this.fileChunks.retrocedeChunk();
|
||||||
|
this._onCompleteChunkCallNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _prepareToUploading(): void {
|
public _prepareToUploading(): void {
|
||||||
this.index = this.index || ++this.uploader._nextIndex;
|
this.index = this.index || ++this.uploader._nextIndex;
|
||||||
this.isReady = true;
|
this.isReady = true;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { EventEmitter } from '@angular/core';
|
|||||||
import { FileLikeObject } from './file-like-object.class';
|
import { FileLikeObject } from './file-like-object.class';
|
||||||
import { FileItem } from './file-item.class';
|
import { FileItem } from './file-item.class';
|
||||||
import { FileType } from './file-type.class';
|
import { FileType } from './file-type.class';
|
||||||
import { FileChunk } from './file-chunk.class';
|
|
||||||
function isFile(value: any): boolean {
|
function isFile(value: any): boolean {
|
||||||
return (File && value instanceof File);
|
return (File && value instanceof File);
|
||||||
}
|
}
|
||||||
@@ -80,7 +79,6 @@ export class FileUploader {
|
|||||||
this.setOptions(options);
|
this.setOptions(options);
|
||||||
this.response = new EventEmitter<any>();
|
this.response = new EventEmitter<any>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public setOptions(options: FileUploaderOptions): void {
|
public setOptions(options: FileUploaderOptions): void {
|
||||||
this.options = Object.assign(this.options, options);
|
this.options = Object.assign(this.options, options);
|
||||||
|
|
||||||
@@ -150,6 +148,7 @@ export class FileUploader {
|
|||||||
if (item.isUploading) {
|
if (item.isUploading) {
|
||||||
item.cancel();
|
item.cancel();
|
||||||
}
|
}
|
||||||
|
this.onRemoveItem(item);
|
||||||
this.queue.splice(index, 1);
|
this.queue.splice(index, 1);
|
||||||
this.progress = this._getTotalProgress();
|
this.progress = this._getTotalProgress();
|
||||||
}
|
}
|
||||||
@@ -174,16 +173,16 @@ export class FileUploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cancelItem(value: FileItem): void {
|
public cancelItem(value: FileItem): void {
|
||||||
let index = this.getIndexOfItem(value);
|
const index = this.getIndexOfItem(value);
|
||||||
let item = this.queue[ index ];
|
const item = this.queue[ index ];
|
||||||
let prop = this.options.isHTML5 ? item._xhr : item._form;
|
const prop = this.options.isHTML5 ? item._xhr : item._form;
|
||||||
if (item && item.isUploading) {
|
if (item && item.isUploading) {
|
||||||
prop.abort();
|
prop.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public uploadAll(): void {
|
public uploadAll(): void {
|
||||||
let items = this.getNotUploadedItems().filter((item: FileItem) => !item.isUploading);
|
const items = this.getNotUploadedItems().filter((item: FileItem) => !item.isUploading);
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -192,7 +191,7 @@ export class FileUploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cancelAll(): void {
|
public cancelAll(): void {
|
||||||
let items = this.getNotUploadedItems();
|
const items = this.getNotUploadedItems();
|
||||||
items.map((item: FileItem) => item.cancel());
|
items.map((item: FileItem) => item.cancel());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +206,24 @@ export class FileUploader {
|
|||||||
public getIndexOfItem(value: any): number {
|
public getIndexOfItem(value: any): number {
|
||||||
return typeof value === 'number' ? value : this.queue.indexOf(value);
|
return typeof value === 'number' ? value : this.queue.indexOf(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getIsErrorItems(): any[] {
|
||||||
|
return this.queue.filter((item: FileItem) => item.isError);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIsCancelItems(): any[] {
|
||||||
|
return this.queue.filter((item: FileItem) => item.isCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIsSuccessItems(): any[] {
|
||||||
|
return this.queue.filter((item: FileItem) => item.isSuccess );
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAllItems(): any[] {
|
||||||
|
return this.queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public getNotUploadedItems(): any[] {
|
public getNotUploadedItems(): any[] {
|
||||||
return this.queue.filter((item: FileItem) => !item.isUploaded);
|
return this.queue.filter((item: FileItem) => !item.isUploaded);
|
||||||
}
|
}
|
||||||
@@ -261,9 +277,15 @@ export class FileUploader {
|
|||||||
public onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
public onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
||||||
return { item, response, status, headers };
|
return { item, response, status, headers };
|
||||||
}
|
}
|
||||||
|
public onRemoveItem(item: FileItem ): any {
|
||||||
|
return { item };
|
||||||
|
}
|
||||||
public onCompleteChunk(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
public onCompleteChunk(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
||||||
return { item, response, status, headers };
|
return { item, response, status, headers };
|
||||||
}
|
}
|
||||||
|
public onErrorChunk(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
||||||
|
return { item, response, status, headers };
|
||||||
|
}
|
||||||
public onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
public onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
|
||||||
return { item, response, status, headers };
|
return { item, response, status, headers };
|
||||||
}
|
}
|
||||||
@@ -308,7 +330,6 @@ export class FileUploader {
|
|||||||
this.progress = this._getTotalProgress();
|
this.progress = this._getTotalProgress();
|
||||||
this._render();
|
this._render();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _headersGetter(parsedHeaders: ParsedResponseHeaders): any {
|
protected _headersGetter(parsedHeaders: ParsedResponseHeaders): any {
|
||||||
return (name: any): any => {
|
return (name: any): any => {
|
||||||
if (name) {
|
if (name) {
|
||||||
@@ -321,43 +342,42 @@ export class FileUploader {
|
|||||||
let that = this;
|
let that = this;
|
||||||
xhr.upload.onprogress = (event: any) => {
|
xhr.upload.onprogress = (event: any) => {
|
||||||
let progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
|
let progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
|
||||||
if(that.options.chunkSize > 0){
|
if (that.options.chunkSize > 0) {
|
||||||
progress = Math.round( ((item._currentChunk-1) * 100) / item._totalChunks) + Math.round(progress / item._totalChunks);
|
progress = Math.round( ((item._currentChunk-1) * 100) / item._totalChunks) + Math.round(progress / item._totalChunks);
|
||||||
}
|
}
|
||||||
this._onProgressItem(item, progress);
|
this._onProgressItem(item, progress);
|
||||||
};
|
};
|
||||||
xhr.onload = () => {
|
xhr.onload = () => {
|
||||||
|
const headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
||||||
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
const response = this._transformResponse(xhr.response, headers);
|
||||||
let response = this._transformResponse(xhr.response, headers);
|
const gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
|
||||||
let gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
|
const method = '_on' + gist + 'Item';
|
||||||
let method = '_on' + gist + 'Item';
|
if (this.options.chunkSize > 0) {
|
||||||
|
|
||||||
|
|
||||||
if(this.options.chunkSize > 0){
|
|
||||||
item._chunkUploaders.pop();
|
item._chunkUploaders.pop();
|
||||||
if (item._currentChunk >= item._totalChunks) {
|
if (item._currentChunk >= item._totalChunks) {
|
||||||
(this as any)[ method ](item, response, xhr.status, headers);
|
(this as any)[ method ](item, response, xhr.status, headers);
|
||||||
this._onCompleteItem(item, response, xhr.status, headers);
|
this._onCompleteItem(item, response, xhr.status, headers);
|
||||||
}else{
|
} else {
|
||||||
|
this._onCompleteChunk(item, response, xhr.status, headers);
|
||||||
this._onCompleteChunk(item,response,xhr.status,headers);
|
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
(this as any)[ method ](item, response, xhr.status, headers);
|
(this as any)[ method ](item, response, xhr.status, headers);
|
||||||
this._onCompleteItem(item, response, xhr.status, headers);
|
this._onCompleteItem(item, response, xhr.status, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
xhr.onerror = () => {
|
xhr.onerror = () => {
|
||||||
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
const headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
||||||
let response = this._transformResponse(xhr.response, headers);
|
const response = this._transformResponse(xhr.response, headers);
|
||||||
this._onErrorItem(item, response, xhr.status, headers);
|
if (this.options.chunkSize > 0) {
|
||||||
this._onCompleteItem(item, response, xhr.status, headers);
|
this._onErrorChunk(item, response, xhr.status, headers);
|
||||||
|
} else {
|
||||||
|
this._onErrorItem(item, response, xhr.status, headers);
|
||||||
|
this._onCompleteItem(item, response, xhr.status, headers);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
xhr.onabort = () => {
|
xhr.onabort = () => {
|
||||||
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
const headers = this._parseHeaders(xhr.getAllResponseHeaders());
|
||||||
let response = this._transformResponse(xhr.response, headers);
|
const response = this._transformResponse(xhr.response, headers);
|
||||||
this._onCancelItem(item, response, xhr.status, headers);
|
this._onCancelItem(item, response, xhr.status, headers);
|
||||||
this._onCompleteItem(item, response, xhr.status, headers);
|
this._onCompleteItem(item, response, xhr.status, headers);
|
||||||
};
|
};
|
||||||
@@ -381,22 +401,21 @@ export class FileUploader {
|
|||||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||||
that.response.emit(xhr.responseText)
|
that.response.emit(xhr.responseText)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return xhr;
|
return xhr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _buildMultiPartSendable(item: FileItem,start: number = null, end:number = null): FormData{
|
protected _buildMultiPartSendable(item: FileItem): FormData{
|
||||||
let sendable: FormData;
|
let sendable: FormData;
|
||||||
sendable = new FormData();
|
sendable = new FormData();
|
||||||
this._onBuildItemForm(item, sendable);
|
this._onBuildItemForm(item, sendable);
|
||||||
let file: any = null;
|
let file: any = null;
|
||||||
if(this.options.chunkSize > 0){
|
if(this.options.chunkSize > 0){
|
||||||
|
file = item.getCurrentChunkFile();
|
||||||
file = item.getNextChunk();
|
|
||||||
}else{
|
}else{
|
||||||
file = item._file;
|
file = item._file;
|
||||||
}
|
}
|
||||||
const appendFile = () => sendable.append(item.alias, file, item.file.name);
|
const appendFile = () => sendable.append(item.alias, file, item.file.name);
|
||||||
if (!this.options.parametersBeforeFiles) {
|
if (!this.options.parametersBeforeFiles) {
|
||||||
appendFile();
|
appendFile();
|
||||||
}
|
}
|
||||||
@@ -413,10 +432,10 @@ export class FileUploader {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.options.chunkSize > 0 && this.options.totalChunkParam){
|
if (this.options.chunkSize > 0 && this.options.totalChunkParam){
|
||||||
sendable.append(this.options.totalChunkParam,item._totalChunks.toString() );
|
sendable.append(this.options.totalChunkParam,item.getTotalChunks());
|
||||||
}
|
}
|
||||||
if (this.options.chunkSize > 0 && this.options.currentChunkParam){
|
if (this.options.chunkSize > 0 && this.options.currentChunkParam){
|
||||||
sendable.append(this.options.currentChunkParam,item._currentChunk.toString() );
|
sendable.append(this.options.currentChunkParam,item.getCurrentChunk() +1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.parametersBeforeFiles) {
|
if (this.options.parametersBeforeFiles) {
|
||||||
@@ -434,51 +453,38 @@ export class FileUploader {
|
|||||||
if (typeof item._file.size !== 'number') {
|
if (typeof item._file.size !== 'number') {
|
||||||
throw new TypeError('The file specified is no longer valid');
|
throw new TypeError('The file specified is no longer valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.options.disableMultipart) {
|
if (!this.options.disableMultipart) {
|
||||||
/* CHUNCKED FILE UPLOAD */
|
/* CHUNCKED FILE UPLOAD */
|
||||||
if (this.options.chunkSize > 0){
|
if (this.options.chunkSize > 0) {
|
||||||
let chunkSize = this.options.chunkSize;
|
const chunkMethod = this.options.chunkMethod;
|
||||||
let chunkMethod = this.options.chunkMethod;
|
|
||||||
let NUM_CHUNKS = Math.max(Math.ceil(item._file.size / chunkSize), 1);
|
|
||||||
let CUR_CHUNK = 0;
|
|
||||||
let start = 0;
|
|
||||||
let end = chunkSize;
|
|
||||||
|
|
||||||
item._chunkUploaders = [];
|
item._chunkUploaders = [];
|
||||||
item._currentChunk = 0;
|
item._currentChunk = 0;
|
||||||
item._totalChunks = NUM_CHUNKS;
|
item._onCompleteChunkCallNext = function(): void{
|
||||||
|
|
||||||
item._onCompleteChunkCallnext = function(): void{
|
|
||||||
item._currentChunk ++;
|
item._currentChunk ++;
|
||||||
if(item._currentChunk > 1){
|
if (item._currentChunk > 1) {
|
||||||
item.method = chunkMethod;
|
item.method = chunkMethod;
|
||||||
}
|
}
|
||||||
let sendable = this.uploader._buildMultiPartSendable(item,start,end);
|
const sendable = this.uploader._buildMultiPartSendable(item);
|
||||||
let xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr = this.uploader._xhrAppendEvents(xhr,item);
|
xhr = this.uploader._xhrAppendEvents(xhr, item);
|
||||||
|
item._xhr = xhr;
|
||||||
item._chunkUploaders.push(xhr);
|
item._chunkUploaders.push(xhr);
|
||||||
xhr.send(sendable);
|
xhr.send(sendable);
|
||||||
|
item.prepareNextChunk()
|
||||||
start = end;
|
};
|
||||||
end = start + chunkSize;
|
item.createFileChunk(this.options.chunkSize);
|
||||||
}
|
item.setIsUploading(true);
|
||||||
item.createFileChunk(this.options.chunkSize)
|
item._onCompleteChunkCallNext();
|
||||||
item.setIsUploading(true)
|
|
||||||
item._onCompleteChunkCallnext();
|
|
||||||
this._render();
|
this._render();
|
||||||
return;
|
return;
|
||||||
}else{
|
} else {
|
||||||
sendable = this._buildMultiPartSendable(item);
|
sendable = this._buildMultiPartSendable(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sendable = this.options.formatDataFunction(item);
|
sendable = this.options.formatDataFunction(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append Evenets
|
// Append Evenets
|
||||||
xhr = this._xhrAppendEvents(xhr,item);
|
xhr = this._xhrAppendEvents(xhr, item);
|
||||||
if (this.options.formatDataFunctionIsAsync) {
|
if (this.options.formatDataFunctionIsAsync) {
|
||||||
sendable.then(
|
sendable.then(
|
||||||
(result: any) => xhr.send(JSON.stringify(result))
|
(result: any) => xhr.send(JSON.stringify(result))
|
||||||
@@ -581,14 +587,17 @@ export class FileUploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _onProgressItem(item: FileItem, progress: any): void {
|
protected _onProgressItem(item: FileItem, progress: any): void {
|
||||||
let total = this._getTotalProgress(progress);
|
const total = this._getTotalProgress(progress);
|
||||||
this.progress = total;
|
this.progress = total;
|
||||||
item._onProgress(progress);
|
item._onProgress(progress);
|
||||||
this.onProgressItem(item, progress);
|
this.onProgressItem(item, progress);
|
||||||
this.onProgressAll(total);
|
this.onProgressAll(total);
|
||||||
this._render();
|
this._render();
|
||||||
}
|
}
|
||||||
|
protected _onErrorChunk(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
|
||||||
|
item._onErrorChunk(response, status, headers);
|
||||||
|
this.onErrorChunk(item, response, status, headers)
|
||||||
|
}
|
||||||
protected _onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
|
protected _onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
|
||||||
item._onSuccess(response, status, headers);
|
item._onSuccess(response, status, headers);
|
||||||
this.onSuccessItem(item, response, status, headers);
|
this.onSuccessItem(item, response, status, headers);
|
||||||
|
|||||||
Reference in New Issue
Block a user