import { Injectable, ElementRef } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { Subject , of } from 'rxjs'; import { HttpClient, HttpParams } from "@angular/common/http"; declare var require; // avoid missing property error on require @Injectable() export class ResumableFileUploadService { private resumable: any; private dropElement: ElementRef; private fileBrowseElement: ElementRef; private directoryBrowseElement: ElementRef; public files: Array = new Array(); public isUploading = false; public totalProgress = "0"; public isClosed = true; public isMinimized = false; public parentCode: string; public refresh: Subject = new Subject(); constructor(private httpClient: HttpClient,private oauthService: OAuthService) { this.init(); } init = function () { this.ref require.ensure([], require => { let Resumable = require('./resumable.js'); var other = this; this.resumable = new Resumable( { target: '/api/v1/file/chunk', query: function (file, chunk) { var options = {}; if (file.parentCode) options["parentCode"] = file.parentCode; if (chunk.tested) { if (file.file.geoRefJson) options["geoRefJson"] = file.file.geoRefJson; if (file.file.attributes) options["attributes"] = file.file.attributes; } return options; }, headers: function (file) { return { Authorization: "Bearer " + other.oauthService.getAccessToken() } }, generateUniqueIdentifier: function (file, event) { var params = new HttpParams() .set("name", file.fileName || file.name) .set("size", file.size); return other.httpClient.post("/api/v1/file",params).toPromise().then(res => res.code); }, chunkNumberParameterName: 'chunkNumber', chunkSizeParameterName: 'chunkSize', currentChunkSizeParameterName: 'currentChunkSize', totalSizeParameterName: 'size', typeParameterName: 'type', identifierParameterName: 'code', fileNameParameterName: 'name', relativePathParameterName: 'relativePath', totalChunksParameterName: 'totalChunks' } ) as any; var other = this; this.resumable.on('catchAll', function (event) { other.isUploading = other.resumable.isUploading(); other.totalProgress = (other.resumable.progress() * 100).toFixed(0); other.refresh.next({}); }); this.resumable.on('filesAdded', function (files) { files.forEach(function (file) { file.parentCode = other.parentCode; other.files.push(new File(file)); }); other.isClosed = false; other.resumable.upload(); }); this.resumable.on('fileSuccess', function (file) { var index = other.getIndex(file); if (index >= 0) { other.files[index].success = true; } }); this.resumable.on('error', function (message,file) { var index = other.getIndex(file); if (index >= 0) { other.files[index].error = true; other.files[index].errorMessage = message; } }); this.resumable.on('fileProgress', function (file) { var index = other.getIndex(file); if (index >= 0) { other.files[index].progress = (file.progress() * 100) + '%'; } }); if (this.dropElement) this.resumable.assignDrop(this.dropElement); if (this.fileBrowseElement) this.resumable.assignBrowse(this.fileBrowseElement); if (this.directoryBrowseElement) this.resumable.assignBrowse(this.directoryBrowseElement, true); }); } addFiles = (files: any[], event: any, geoRefJson?: string, attributes?: any) => { for (let f of files) { if (geoRefJson) f.geoRefJson = geoRefJson; if (attributes) f.attributes = JSON.stringify(attributes); } this.resumable.addFiles(files, event); } assignDrop = function (element: ElementRef) { if (this.resumable) { this.resumable.assignDrop(element); } this.dropElement = element; } assignFileBrowse = function (element: ElementRef) { if (this.resumable) { this.resumable.assignBrowse(element); } this.fileBrowseElement = element; } assignDirectoryBrowse = function (element: ElementRef) { if (this.resumable) { this.resumable.assignBrowse(element, true); } this.directoryBrowseElement = element; } getIndex = function (file) { for (var i = 0; i < this.files.length; i++) { if (this.files[i].identifier == file.uniqueIdentifier) return i; } return -1; } toggleMinimize = function () { this.isMinimized = !this.isMinimized; }; cancelFile = function (file) { file.file.cancel(); var index = this.files.indexOf(file, 0); if (index > -1) { this.files.splice(index, 1); } }; doClose = function () { this.resumable.cancel(); this.files = new Array(); this.isClosed = true; } close = function () { let close = true; if (this.isUploading) { close = false; } if (close) { this.doClose(); } } } export class File { private file: any; public fileName: string; public progress: string; public identifier: string; public success: boolean; public error: boolean; public errorMessage: string; constructor(file: any) { this.file = file; this.fileName = file.fileName; this.progress = (file.progress() * 100) + '%'; this.identifier = file.uniqueIdentifier; this.success = false; this.error = false; this.errorMessage = ""; } }