pose / web /client /src /components /Dropzone.vue
amitesh11's picture
Upload 3019 files
369fac9 verified
<script setup>
import { ref, watch, computed } from "vue";
// TODO: handle only video file
const dropzoneInput = ref(null);
const uploadedVideoFile = ref(null);
const isUploaded = computed(() => (uploadedVideoFile.value ? true : false));
const isDragOver = ref(false);
// Emit events
const emit = defineEmits(["fileUploaded"]);
watch(
() => uploadedVideoFile.value,
(newData, oldData) => {
if (newData) {
emit("fileUploaded", newData);
}
}
);
// * Handle Drag Events
const removeDragEventDefault = (event) => {
event.preventDefault();
event.stopPropagation();
};
const handleDragOver = (event) => {
removeDragEventDefault(event);
isDragOver.value = true;
};
const handleDragLeave = (event) => {
removeDragEventDefault(event);
isDragOver.value = false;
};
const handleDrop = (event) => {
removeDragEventDefault(event);
isDragOver.value = false;
let videoFile = event.dataTransfer.files[0];
let dataTransfer = new DataTransfer();
dataTransfer.items.add(videoFile);
let filesToBeAdded = dataTransfer.files;
dropzoneInput.value.files = filesToBeAdded;
uploadedVideoFile.value = videoFile;
};
// Handle File Input
const openFileInput = () => {
dropzoneInput.value.click();
};
const handleClickUpload = (event) => {
const target = event.target;
if (target && target.files) {
uploadedVideoFile.value = target.files[0];
}
};
// Other utils func
const byteToMB = (bytes) => {
return Math.round(bytes / 1000000);
};
</script>
<template>
<div
class="dropzone"
:class="{ 'dropzone-dragging': isDragOver }"
id="dropzone"
@drag="removeDragEventDefault"
@dragstart="removeDragEventDefault"
@dragend="removeDragEventDefault"
@dragover="handleDragOver"
@dragenter="handleDragLeave"
@dragleave="removeDragEventDefault"
@drop="handleDrop"
@click.self="openFileInput"
>
<!-- Initial Stage -->
<template v-if="!isUploaded">
<i class="fa-solid fa-cloud-arrow-up dropzone-icon"></i>
Drop files or Click here to select files to upload.
</template>
<!-- Uploaded State -->
<template v-else>
<i class="fa-regular fa-file-video dropzone-icon"></i>
{{ uploadedVideoFile.name }}
({{ byteToMB(uploadedVideoFile.size) }} MB)
</template>
<input
type="file"
name="files"
class="dropzone-input"
ref="dropzoneInput"
@change="handleClickUpload"
/>
</div>
</template>
<style lang="scss" scoped>
.dropzone {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 0.2rem dashed var(--primary-color);
padding: 2rem;
border-radius: 0.25rem;
background-color: #fff;
font-size: 1.25rem;
text-align: center;
transition: 0.25s background-color ease-in-out;
cursor: pointer;
&-dragging,
&:hover {
background-color: lighten(#41b883, 38%);
}
&-icon {
display: block;
font-size: 3rem;
margin: 0 auto 1.5rem;
color: var(--primary-color);
}
&-input {
display: none;
}
}
</style>