Files
warren/frontend/stores/upload.ts
2025-07-29 21:17:39 +02:00

87 lines
2.5 KiB
TypeScript

import type { UploadFile } from '#shared/types';
import { toast } from 'vue-sonner';
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,
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();
},
},
});