121 lines
4.1 KiB
Vue
121 lines
4.1 KiB
Vue
<script setup>
|
|
import Navigation from "../Components/custom/Navigation.vue";
|
|
import SearchForm from "../Components/custom/SearchForm.vue";
|
|
import UserDropdown from "../Components/custom/UserDropdown.vue";
|
|
import FileUploadErrorModal from "../Components/custom/FileUploadErrorModal.vue";
|
|
import { emitter } from "../emitter.js";
|
|
import { ref, onMounted } from "vue";
|
|
import { useForm, usePage } from "@inertiajs/vue3";
|
|
|
|
// get current page for file uploading
|
|
const page = usePage();
|
|
// make refs
|
|
const dragging = ref(false);
|
|
const fileUploadError = ref(false);
|
|
const draggable = ref(false);
|
|
|
|
// add Mitt event listener on component load
|
|
onMounted(() => {
|
|
emitter.on("FILE_UPLOAD_STARTED", uploadFiles);
|
|
// determines whether this page is draggable
|
|
const regex = new RegExp("/files.*", "gi");
|
|
if (regex.test(page.url)) draggable.value = true;
|
|
});
|
|
|
|
// file drop function
|
|
const onDrop = (event) => {
|
|
dragging.value = false;
|
|
// get dragged files
|
|
const files = event.dataTransfer.files;
|
|
// check if files exist, then upload
|
|
// note that folders can be falsy here
|
|
if (files.length) {
|
|
uploadFiles(files);
|
|
}
|
|
};
|
|
|
|
// create form input for file upload
|
|
const fileUpload = useForm({
|
|
files: [],
|
|
paths: [],
|
|
parent_id: null,
|
|
});
|
|
|
|
// upload files function
|
|
const uploadFiles = (files) => {
|
|
// fill out form
|
|
fileUpload.files = files;
|
|
fileUpload.parent_id = page.props.folder.id;
|
|
fileUpload.paths = Array.from(files).map((file) => file.webkitRelativePath);
|
|
|
|
// send form to backend for processing
|
|
fileUpload.post(route("file.upload"), {
|
|
onError: (errors) => {
|
|
if (Object.keys(errors).length > 0) {
|
|
message = errors[Object.keys(errors)[0]];
|
|
fileUploadError.value = message;
|
|
} else {
|
|
message =
|
|
"Errors encountered while uploading file. Please try again.";
|
|
}
|
|
},
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="h-screen w-full bg-zinc-900 text-gray-100 flex gap-4">
|
|
<Navigation />
|
|
<main
|
|
v-if="draggable"
|
|
@drop.prevent="onDrop"
|
|
@dragover.prevent="dragging = true"
|
|
@dragleave.prevent="dragging = false"
|
|
class="flex flex-col flex-1 px-4 overflow-hidden"
|
|
>
|
|
<template v-if="dragging">
|
|
<div
|
|
class="text-lg w-full h-full flex flex-col items-center justify-center border-2 border-dashed border-gray-700"
|
|
>
|
|
<div
|
|
class="w-40 h-40 border-2 rounded-lg border-gray-700 text-gray-300 text-6xl flex items-center justify-center"
|
|
>
|
|
<div class="arrow">+</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<div class="flex items-center justify-between w-full">
|
|
<SearchForm />
|
|
<UserDropdown />
|
|
</div>
|
|
<div class="flex-1 flex flex-col overflow-hidden">
|
|
<div class="h-4 bg-zinc-900" v-if="fileUpload.progress">
|
|
<div
|
|
class="h-full bg-sky-600 transition-all"
|
|
:style="{ width: `${form.progress.percentage}%` }"
|
|
></div>
|
|
</div>
|
|
<slot />
|
|
</div>
|
|
</template>
|
|
</main>
|
|
<main v-else class="flex flex-col flex-1 px-4 overflow-hidden">
|
|
<div class="flex items-center justify-between w-full">
|
|
<SearchForm />
|
|
<UserDropdown />
|
|
</div>
|
|
<div class="flex-1 flex flex-col overflow-hidden">
|
|
<slot />
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<FileUploadErrorModal v-if="fileUploadError" :message="fileUploadError">
|
|
<button
|
|
@click="fileUploadError = false"
|
|
class="border border-sky-600 px-5 py-3 rounded hover:bg-sky-600"
|
|
>
|
|
OK
|
|
</button>
|
|
</FileUploadErrorModal>
|
|
</template>
|