ddc-image-upload
Version:
Dusdusan Image Upload
261 lines (260 loc) • 19.2 kB
JavaScript
"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;