file upload drop zones

This commit is contained in:
2025-07-29 21:17:39 +02:00
parent 45368dcc9a
commit b1409b44d1
5 changed files with 162 additions and 66 deletions

View File

@@ -1,21 +1,86 @@
import type { UploadFile } from '#shared/types';
import { toast } from 'vue-sonner';
export const useUploadStore = defineStore<
'warren-upload',
{
startIndex: number;
files: UploadFile[];
destination: { warrenId: string; path: string } | null;
progress: {
export const useUploadStore = defineStore('warren-upload', {
state: () => ({
dialogOpen: false as boolean,
startIndex: 0 as number,
files: [] as UploadFile[],
destination: null as { warrenId: string; path: string } | null,
progress: null as {
loadedBytes: number;
totalBytes: number;
} | null;
}
>('warren-upload', {
state: () => ({
startIndex: 0,
files: [],
destination: null,
progress: null,
} | null,
presentPaths: new Set() as Set<string>,
}),
actions: {
addFiles(
warrenId: string,
destination: string,
files: File[]
): boolean {
if (this.destination == null) {
this.destination = {
warrenId: warrenId,
path: destination,
};
} else if (
this.destination.warrenId != warrenId ||
this.destination.path !== destination
) {
toast.warning('Upload', {
description:
'The unfinished items belong to a different directory. Remove them before attempting to upload to a different directory.',
});
return false;
}
let added = 0;
for (const file of files) {
if (this.presentPaths.has(file.name)) {
continue;
}
this.files.push({ status: 'not_uploaded', data: file });
this.presentPaths.add(file.name);
added++;
}
return added > 0;
},
removeFile(index: number) {
if (this.files.length <= index) {
return;
}
if (this.files.length <= 1) {
this.clearFiles();
return;
}
const [file] = this.files.splice(index, 1);
this.presentPaths.delete(file.data.name);
},
clearCompletedFiles() {
this.files = this.files.filter((f) => {
if (f.status === 'completed') {
this.presentPaths.delete(f.data.name);
return false;
}
return true;
});
if (this.files.length < 1) {
this.clearFiles();
}
},
clearFiles() {
this.files = [];
this.destination = null;
this.progress = null;
this.presentPaths.clear();
},
},
});