file upload drop zones
This commit is contained in:
@@ -15,6 +15,7 @@ import byteSize from 'byte-size';
|
||||
import { uploadToWarren } from '~/lib/api/warrens';
|
||||
import { toast } from 'vue-sonner';
|
||||
import UploadListEntry from './UploadListEntry.vue';
|
||||
import { useDropZone } from '@vueuse/core';
|
||||
|
||||
const warrenStore = useWarrenStore();
|
||||
const uploadStore = useUploadStore();
|
||||
@@ -32,7 +33,26 @@ const fileInputElement = ref<HTMLInputElement>(
|
||||
);
|
||||
|
||||
const uploading = ref(false);
|
||||
const presentPaths = new Set<string>();
|
||||
const dropZoneRef = ref<HTMLElement>();
|
||||
|
||||
const dropZone = useDropZone(dropZoneRef, {
|
||||
onDrop,
|
||||
multiple: true,
|
||||
});
|
||||
|
||||
function onDrop(files: File[] | null, event: DragEvent) {
|
||||
event.preventDefault();
|
||||
|
||||
if (warrenStore.current == null || files == null || files.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
uploadStore.addFiles(
|
||||
warrenStore.current.warrenId,
|
||||
warrenStore.current.path,
|
||||
files
|
||||
);
|
||||
}
|
||||
|
||||
function onFilesChanged(event: Event) {
|
||||
if (warrenStore.current == null) {
|
||||
@@ -52,58 +72,21 @@ function onFilesChanged(event: Event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (uploadStore.destination == null) {
|
||||
uploadStore.destination = warrenStore.current;
|
||||
} else if (!currentAndUploadRouteMatch.value) {
|
||||
toast.warning('Upload', {
|
||||
description:
|
||||
'The unfinished items belong to a different directory. Remove them before attempting to upload to a different directory.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
for (const file of target.files) {
|
||||
if (presentPaths.has(file.name)) {
|
||||
continue;
|
||||
}
|
||||
uploadStore.files.push({
|
||||
status: 'not_uploaded',
|
||||
data: file,
|
||||
});
|
||||
presentPaths.add(file.name);
|
||||
}
|
||||
uploadStore.addFiles(
|
||||
warrenStore.current.warrenId,
|
||||
warrenStore.current.path,
|
||||
[...target.files]
|
||||
);
|
||||
|
||||
fileInputElement.value.value = '';
|
||||
}
|
||||
|
||||
function removeFile(index: number) {
|
||||
if (uploadStore.files.length <= index) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [file] = uploadStore.files.splice(index, 1);
|
||||
presentPaths.delete(file.data.name);
|
||||
|
||||
if (uploadStore.files.length < 1) {
|
||||
uploadStore.destination = null;
|
||||
uploadStore.progress = null;
|
||||
}
|
||||
uploadStore.removeFile(index);
|
||||
}
|
||||
|
||||
function clearCompletedFiles() {
|
||||
uploadStore.files = uploadStore.files.filter((f) => {
|
||||
if (f.status === 'completed') {
|
||||
presentPaths.delete(f.data.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (uploadStore.files.length < 1) {
|
||||
uploadStore.destination = null;
|
||||
uploadStore.progress = null;
|
||||
}
|
||||
uploadStore.clearCompletedFiles();
|
||||
}
|
||||
|
||||
function updateFileListStatus(loadedBytes: number, ended: boolean = false) {
|
||||
@@ -190,7 +173,7 @@ async function submit() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog>
|
||||
<Dialog v-model:open="uploadStore.dialogOpen">
|
||||
<DialogTrigger as-child>
|
||||
<slot />
|
||||
</DialogTrigger>
|
||||
@@ -220,6 +203,7 @@ async function submit() {
|
||||
/>
|
||||
|
||||
<div
|
||||
ref="dropZoneRef"
|
||||
class="flex min-h-[280px] w-full items-center justify-center overflow-hidden rounded-xl border sm:aspect-video sm:min-h-[unset]"
|
||||
>
|
||||
<ScrollArea
|
||||
|
||||
Reference in New Issue
Block a user