export class FileSelector { dropZones = []; selectedFile = null; onFileSelected = null; constructor(mimeType) { this.mimeType = mimeType; window.ondrop = (e) => e.preventDefault(); window.ondragover = (e) => { if (![...e.dataTransfer.items].some(it => it.kind === "file")) return; e.preventDefault(); if (!this.dropZones.some(dropZone => dropZone.contains(e.target))) { e.dataTransfer.dropEffect = "none"; } }; } selectFile(file) { this.selectedFile = file; if (this.onFileSelected) this.onFileSelected(file); } addInput(elem) { elem.oninput = () => { setTimeout(() => this.selectFile(elem.files[0]), 200); }; } addDropZone(elem) { this.dropZones.push(elem); elem.ondrop = (e) => { e.preventDefault(); const file = [...e.dataTransfer.files].find(file => file.type.startsWith(this.mimeType)); if (file) { this.selectFile(file); } }; elem.ondragover = (e) => { const items = [...e.dataTransfer.items]; if (!items.some(it => it.kind === "file")) return; e.preventDefault(); if (items.some(it => it.type.startsWith(this.mimeType))) { e.dataTransfer.dropEffect = "copy"; elem.classList.add("dropping"); } else { e.dataTransfer.dropEffect = "copy"; } }; elem.ondragleave = () => elem.classList.remove("dropping"); } }