file upload drop zones
This commit is contained in:
@@ -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();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user