import { UpploadService } from "../service"; import { IHandlersParams, IServiceTemplateParams } from "../helpers/interfaces"; import { safeListen } from "../helpers/elements"; import { translate } from "../helpers/i18n"; import { formatBytes } from "../helpers/utils"; export default class Local extends UpploadService { name = "local"; icon = ``; color = "#34495e"; mimeTypes = ["image/gif", "image/jpeg", "image/jpg", "image/png"]; maxFileSize: number = Infinity; constructor({ mimeTypes, maxFileSize, }: { mimeTypes?: string[]; maxFileSize?: number } = {}) { super(); if (mimeTypes) this.mimeTypes = mimeTypes; if (maxFileSize) this.maxFileSize = maxFileSize; } template = (params: IServiceTemplateParams) => { return `
${params.translate("services.local.drop")}
${params.translate("services.local.or")}
`; }; handlers = (params: IHandlersParams) => { const dropArea = params.uppload.container.querySelector(".drop-area"); if (dropArea) { safeListen(dropArea, "drop", (event) => this.dropHandler(params, event as DragEvent) ); safeListen(dropArea, "dragover", (event) => this.dragHandler(params, event) ); safeListen(dropArea, "dragend", (event) => this.dragStop(params, event)); safeListen(dropArea, "dragexit", (event) => this.dragStop(params, event)); safeListen(dropArea, "dragleave", (event) => this.dragStop(params, event) ); safeListen(dropArea, "click", (event) => this.fileSelect(params, event)); } const input = params.uppload.container.querySelector( ".alternate-input input[type=file]" ) as HTMLInputElement | null; if (input) safeListen(input, "change", (event) => this.getFile(params, event)); const helpButton = params.uppload.container.querySelector(".need-help-link"); if (helpButton) safeListen(helpButton, "click", () => params.showHelp("/services/local")); }; getFile(params: IHandlersParams, event: Event) { event.preventDefault(); const files = (event.target as HTMLInputElement).files; let file: File | null = null; if (files) { if (params.uppload.settings.multiple && files.length > 1) return params.uploadMultiple(Array.from(files)); for (let i = 0; i < files.length; i++) { const item = files[i]; if (this.mimeTypes.indexOf(item.type) !== -1) if (item.size < this.maxFileSize) file = item; else params.handle( new Error( params.translate( "errors.file_too_large", formatBytes(this.maxFileSize) ) ) ); } } if (!file) return; if (file) params.next({ blob: file, size: file.size, type: file.type, lastModified: file.lastModified ? new Date(file.lastModified) : undefined, name: file.name, }); } fileSelect(params: IHandlersParams, event: Event) { const input = params.uppload.container.querySelector( ".alternate-input input[type=file]" ) as HTMLInputElement | null; if (input) input.click(); } private dragStop(params: IHandlersParams, event: Event) { const dropArea = params.uppload.container.querySelector(".drop-area"); if (dropArea) dropArea.classList.remove("drop-area-active"); } dragHandler(params: IHandlersParams, event: Event) { event.preventDefault(); const dropArea = params.uppload.container.querySelector(".drop-area"); if (dropArea) dropArea.classList.add("drop-area-active"); } dropHandler(params: IHandlersParams, event: DragEvent) { event.preventDefault(); this.dragStop(params, event); let file: File | null = null; // getAsFile() returns File | null if (event.dataTransfer && event.dataTransfer.items) { for (let i = 0; i < event.dataTransfer.items.length; i++) { const item = event.dataTransfer.items[i]; if (item.kind === "file" && this.mimeTypes.indexOf(item.type) !== -1) { file = item.getAsFile(); if (!file || file.size > this.maxFileSize) { file = null; params.handle( new Error( params.translate( "errors.file_too_large", formatBytes(this.maxFileSize) ) ) ); } } } } if (!file) return; if (file) params.next({ blob: file, size: file.size, type: file.type, lastModified: file.lastModified ? new Date(file.lastModified) : undefined, name: file.name, }); } }