64 lines
1.3 KiB
JavaScript
64 lines
1.3 KiB
JavaScript
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");
|
|
}
|
|
}
|