UNPKG

ddc-image-upload

Version:

Dusdusan Image Upload

261 lines (260 loc) 19.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t; return { next: verb(0), "throw": verb(1), "return": verb(2) }; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var core_1 = require("@angular/core"); var image_service_1 = require("./image.service"); var FileHolder = (function () { function FileHolder(src, file) { this.src = src; this.file = file; this.pending = false; } return FileHolder; }()); exports.FileHolder = FileHolder; var ImageUploadComponent = (function () { function ImageUploadComponent(imageService) { var _this = this; this.imageService = imageService; this.files = []; this.fileCounter = 0; this.fileOver = false; this.showFileTooLargeMessage = false; this.beforeUpload = function (data) { return data; }; this.buttonCaption = 'Select Images'; this.disabled = false; this.cssClass = 'img-ul'; this.clearButtonCaption = 'Clear'; this.dropBoxMessage = 'Drop your images here!'; this.max = 100; this.preview = true; this.withCredentials = false; this.uploadedFiles = []; this.removed = new core_1.EventEmitter(); this.uploadStateChanged = new core_1.EventEmitter(); this.uploadFinished = new core_1.EventEmitter(); this.previewClicked = new core_1.EventEmitter(); this.pendingFilesCounter = 0; this.onFileOver = function (isOver) { return _this.fileOver = isOver; }; this.countRemainingSlots = function () { return _this.max - _this.fileCounter; }; } ImageUploadComponent.prototype.ngOnInit = function () { if (!this.fileTooLargeMessage) { this.fileTooLargeMessage = 'An image was too large and was not uploaded.' + (this.maxFileSize ? (' The maximum file size is ' + this.maxFileSize / 1024) + 'KiB.' : ''); } this.supportedExtensions = this.supportedExtensions ? this.supportedExtensions.map(function (ext) { return 'image/' + ext; }) : ['image/*']; if (this.currentCounter) { this.fileCounter = this.currentCounter; } console.log(this.currentCounter); }; ImageUploadComponent.prototype.deleteAll = function () { var _this = this; this.files.forEach(function (f) { return _this.removed.emit(f); }); this.files = []; this.fileCounter = 0; if (this.inputElement) { this.inputElement.nativeElement.value = ''; } }; ImageUploadComponent.prototype.deleteFile = function (file) { var index = this.files.indexOf(file); this.files.splice(index, 1); this.fileCounter--; if (this.inputElement) { this.inputElement.nativeElement.value = ''; } this.removed.emit(file); }; ImageUploadComponent.prototype.previewFileClicked = function (file) { this.previewClicked.emit(file); }; ImageUploadComponent.prototype.ngOnChanges = function (changes) { if (changes.uploadedFiles && changes.uploadedFiles.currentValue.length > 0) { this.processUploadedFiles(); } }; ImageUploadComponent.prototype.onFileChange = function (files) { if (this.disabled) return; var remainingSlots = this.countRemainingSlots(); var filesToUploadNum = files.length > remainingSlots ? remainingSlots : files.length; if (this.url && filesToUploadNum != 0) { this.uploadStateChanged.emit(true); } this.fileCounter += filesToUploadNum; this.showFileTooLargeMessage = false; this.uploadFiles(files, filesToUploadNum); }; ImageUploadComponent.prototype.onResponse = function (response, fileHolder) { fileHolder.serverResponse = { status: response.status, response: response }; fileHolder.pending = false; this.uploadFinished.emit(fileHolder); if (--this.pendingFilesCounter == 0) { this.uploadStateChanged.emit(false); } }; ImageUploadComponent.prototype.processUploadedFiles = function () { for (var i = 0; i < this.uploadedFiles.length; i++) { var data = this.uploadedFiles[i]; var fileBlob = void 0, file = void 0, fileUrl = void 0; if (data instanceof Object) { fileUrl = data.url; fileBlob = (data.blob) ? data.blob : new Blob([data]); file = new File([fileBlob], data.fileName); } else { fileUrl = data; fileBlob = new Blob([fileUrl]); file = new File([fileBlob], fileUrl); } this.files.push(new FileHolder(fileUrl, file)); } }; ImageUploadComponent.prototype.uploadFiles = function (files, filesToUploadNum) { return __awaiter(this, void 0, void 0, function () { var _this = this; var _loop_1, this_1, i; return __generator(this, function (_a) { switch (_a.label) { case 0: _loop_1 = function (i) { var file, beforeUploadResult, img, reader; return __generator(this, function (_a) { switch (_a.label) { case 0: file = files[i]; if (this_1.maxFileSize && file.size > this_1.maxFileSize) { this_1.fileCounter--; this_1.inputElement.nativeElement.value = ''; this_1.showFileTooLargeMessage = true; this_1.uploadStateChanged.emit(false); return [2 /*return*/, "continue"]; } return [4 /*yield*/, this_1.beforeUpload({ file: file, url: this_1.url, abort: false })]; case 1: beforeUploadResult = _a.sent(); if (beforeUploadResult.abort) { this_1.fileCounter--; this_1.inputElement.nativeElement.value = ''; return [2 /*return*/, "continue"]; } img = document.createElement('img'); img.src = window.URL.createObjectURL(beforeUploadResult.file); reader = new FileReader(); reader.addEventListener('load', function (event) { var fileHolder = new FileHolder(event.target.result, beforeUploadResult.file); _this.uploadSingleFile(fileHolder, beforeUploadResult.url, beforeUploadResult.formData); _this.files.push(fileHolder); }, false); reader.readAsDataURL(beforeUploadResult.file); return [2 /*return*/]; } }); }; this_1 = this; i = 0; _a.label = 1; case 1: if (!(i < filesToUploadNum)) return [3 /*break*/, 4]; return [5 /*yield**/, _loop_1(i)]; case 2: _a.sent(); _a.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); }; ImageUploadComponent.prototype.uploadSingleFile = function (fileHolder, url, customForm) { var _this = this; if (url === void 0) { url = this.url; } if (url) { this.pendingFilesCounter++; fileHolder.pending = true; this.imageService .postImage(url, fileHolder.file, this.headers, this.partName, customForm, this.withCredentials) .subscribe(function (response) { return _this.onResponse(response, fileHolder); }, function (error) { _this.onResponse(error, fileHolder); _this.deleteFile(fileHolder); }); } else { this.uploadFinished.emit(fileHolder); } }; return ImageUploadComponent; }()); ImageUploadComponent.decorators = [ { type: core_1.Component, args: [{ selector: 'image-upload', template: "\n <div\n fileDrop\n [accept]=\"supportedExtensions\"\n (fileOver)=\"onFileOver($event)\"\n (fileDrop)=\"onFileChange($event)\"\n [ngClass]=\"cssClass\"\n [ngClass]=\"{'img-ul-file-is-over': fileOver}\" \n [ngStyle]=\"style?.layout\"\n >\n <div class=\"img-ul-file-upload img-ul-hr-inline-group\"> \n <label *ngIf=\"fileCounter != max\"\n class=\"img-ul-upload img-ul-button\" \n [ngStyle]=\"style?.selectButton\"\n [ngClass]=\"{'img-ul-disabled': disabled}\">\n <span [innerText]=\"buttonCaption\"></span>\n <input\n type=\"file\"\n [disabled]=\"disabled\"\n [accept]=\"supportedExtensions\"\n multiple (change)=\"onFileChange(input.files)\"\n #input>\n </label>\n <button *ngIf=\"fileCounter > 0\"\n [disabled]=\"disabled\"\n class=\"img-ul-clear img-ul-button\" \n (click)=\"deleteAll()\" \n [ngStyle]=\"style?.clearButton\"\n [innerText]=\"clearButtonCaption\">\n </button>\n <div class=\"img-ul-drag-box-msg\" [innerText]=\"dropBoxMessage\"></div>\n </div>\n\n <p class=\"img-ul-file-too-large\" *ngIf=\"showFileTooLargeMessage\" [innerText]=\"fileTooLargeMessage\"></p>\n\n <div *ngIf=\"preview\" class=\"img-ul-container img-ul-hr-inline-group\" [ngStyle]=\"style?.previewPanel\">\n <div\n class=\"img-ul-image\"\n *ngFor=\"let file of files\"\n (click)=\"previewFileClicked(file)\"\n [ngStyle]=\"{'background-image': 'url('+ file.src +')'}\"\n >\n <div *ngIf=\"file.pending\" class=\"img-ul-loading-overlay\">\n <div class=\"img-ul-spinning-circle\"></div>\n </div>\n <div *ngIf=\"!file.pending\" \n [ngClass]=\"{'img-ul-disabled': disabled}\" \n class=\"img-ul-x-mark\" \n (click)=\"deleteFile(file)\">\n <span class=\"img-ul-close\"></span>\n </div>\n </div>\n </div>\n </div>\n ", styles: ["\n .img-ul {\n --active-color: #3C9;\n --common-radius: 3px;\n background-color: #f8f8f8;\n border-radius: var(--common-radius);\n border: #d0d0d0 dashed 1px;\n font-family: sans-serif;\n position: relative;\n color: #9b9b9b;\n }\n\n .img-ul-file-is-over {\n border: var(--active-color) solid;\n }\n\n .img-ul-hr-inline-group:after {\n clear: both;\n content: \"\";\n display: table;\n }\n\n .img-ul-file-upload { \n padding: 16px;\n }\n\n .img-ul-drag-box-msg { \n display: inline-block;\n font-weight: 600;\n margin-left: 12px;\n padding-top: 14px;\n }\n\n label.img-ul-button input[type=file] {\n display: none;\n position: fixed;\n top: -99999px;\n }\n\n .img-ul-clear {\n background-color: #FF0000;\n }\n\n .img-ul-clear:disabled {\n background-color: #FF6464;\n cursor: default;\n }\n\n .img-ul-upload {\n background-color: var(--active-color);\n }\n\n .img-ul-button {\n -moz-box-shadow: 2px 2px 4px 0 rgba(148, 148, 148, 0.6);\n -webkit-box-shadow: 2px 2px 4px 0 rgba(148, 148, 148, 0.6);\n border: none;\n box-shadow: 2px 2px 4px 0 rgba(148, 148, 148, 0.6);\n color: #FFF;\n cursor: pointer;\n display: inline-block;\n float: left;\n font-size: 1.25em;\n font-weight: 500;\n padding: 10px;\n text-transform: uppercase;\n }\n\n .img-ul-button:active span {\n display: block;\n position: relative;\n top: 1px;\n }\n\n .img-ul-container {\n background-color: #fdfdfd;\n padding: 0 10px;\n }\n\n .img-ul-image { \n background: center center no-repeat;\n background-size: contain;\n display: inline-block;\n float: left;\n height: 86px;\n margin: 6px;\n position: relative;\n width: 86px;\n }\n\n .img-ul-x-mark {\n background-color: #000;\n border-radius: 2px;\n color: #FFF;\n cursor: pointer;\n float: right;\n height: 20px;\n margin: 2px;\n opacity: .7;\n text-align: center;\n width: 20px;\n }\n\n .img-ul-close {\n height: 20px;\n opacity: .7;\n padding-right: 3px;\n position: relative;\n width: 20px;\n }\n\n .img-ul-x-mark:hover .img-ul-close {\n opacity: 1;\n }\n\n .img-ul-close:before, .img-ul-close:after {\n background-color: #FFF;\n border-radius: 2px;\n content: '';\n height: 15px;\n position: absolute;\n top: 0;\n width: 2px;\n }\n\n .img-ul-close:before {\n transform: rotate(45deg);\n }\n\n .img-ul-close:after {\n transform: rotate(-45deg);\n }\n\n .img-ul-x-mark.img-ul-disabled {\n display: none;\n }\n\n .img-ul-loading-overlay {\n background-color: #000;\n bottom: 0;\n left: 0;\n opacity: .7;\n position: absolute;\n right: 0;\n top: 0;\n }\n\n .img-ul-spinning-circle {\n height: 30px;\n width: 30px;\n margin: auto;\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n border-radius: 50%;\n border: 3px solid rgba(255, 255, 255, 0);\n border-top: 3px solid #FFF;\n border-right: 3px solid #FFF;\n -webkit-animation: spinner 2s infinite cubic-bezier(0.085, 0.625, 0.855, 0.360);\n animation: spinner 2s infinite cubic-bezier(0.085, 0.625, 0.855, 0.360);\n }\n\n .img-ul-file-too-large {\n color: red;\n padding: 0 15px;\n }\n\n .img-ul-upload.img-ul-disabled {\n background-color: #86E9C9;\n cursor: default;\n }\n\n .img-ul-upload.img-ul-disabled:active span {\n top: 0px;\n }\n\n @-webkit-keyframes spinner {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n }\n\n @keyframes spinner {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n }\n "] },] }, ]; ImageUploadComponent.ctorParameters = function () { return [ { type: image_service_1.ImageService, }, ]; }; ImageUploadComponent.propDecorators = { 'beforeUpload': [{ type: core_1.Input },], 'buttonCaption': [{ type: core_1.Input },], 'disabled': [{ type: core_1.Input },], 'cssClass': [{ type: core_1.Input, args: ['class',] },], 'clearButtonCaption': [{ type: core_1.Input },], 'dropBoxMessage': [{ type: core_1.Input },], 'fileTooLargeMessage': [{ type: core_1.Input },], 'headers': [{ type: core_1.Input },], 'max': [{ type: core_1.Input },], 'maxFileSize': [{ type: core_1.Input },], 'preview': [{ type: core_1.Input },], 'partName': [{ type: core_1.Input },], 'style': [{ type: core_1.Input },], 'supportedExtensions': [{ type: core_1.Input, args: ['extensions',] },], 'url': [{ type: core_1.Input },], 'withCredentials': [{ type: core_1.Input },], 'uploadedFiles': [{ type: core_1.Input },], 'removed': [{ type: core_1.Output },], 'uploadStateChanged': [{ type: core_1.Output },], 'uploadFinished': [{ type: core_1.Output },], 'previewClicked': [{ type: core_1.Output },], 'disableSelect': [{ type: core_1.Input },], 'currentCounter': [{ type: core_1.Input },], 'inputElement': [{ type: core_1.ViewChild, args: ['input',] },], }; exports.ImageUploadComponent = ImageUploadComponent;