diff --git a/frontend/src/stores/upload.ts b/frontend/src/stores/upload.ts index 52ae0466..d929a9e5 100644 --- a/frontend/src/stores/upload.ts +++ b/frontend/src/stores/upload.ts @@ -17,9 +17,9 @@ export const useUploadStore = defineStore("upload", { // convert to a function state: (): { id: number; - sizes: any[]; - progress: any[]; - queue: any[]; + sizes: number[]; + progress: Progress[]; + queue: UploadItem[]; uploads: Uploads; error: Error | null; } => ({ @@ -39,7 +39,8 @@ export const useUploadStore = defineStore("upload", { const totalSize = state.sizes.reduce((a, b) => a + b, 0); - const sum: number = state.progress.reduce((acc, val) => acc + val); + // TODO: this looks ugly but it works with ts now + const sum = state.progress.reduce((acc, val) => +acc + +val) as number; return Math.ceil((sum / totalSize) * 100); }, filesInUploadCount: (state) => { @@ -58,7 +59,7 @@ export const useUploadStore = defineStore("upload", { const isDir = upload.file.isDir; const progress = isDir ? 100 - : Math.ceil((state.progress[id] / size) * 100); + : Math.ceil(((state.progress[id] as number) / size) * 100); files.push({ id, @@ -74,9 +75,7 @@ export const useUploadStore = defineStore("upload", { }, actions: { // no context as first argument, use `this` instead - setProgress(obj: { id: number; loaded: boolean }) { - // Vue.set(this.progress, id, loaded); - const { id, loaded } = obj; + setProgress({ id, loaded }: { id: number; loaded: Progress }) { this.progress[id] = loaded; }, setError(error: Error) { @@ -95,11 +94,9 @@ export const useUploadStore = defineStore("upload", { moveJob() { const item = this.queue[0]; this.queue.shift(); - // Vue.set(this.uploads, item.id, item); this.uploads[item.id] = item; }, removeJob(id: number) { - // Vue.delete(this.uploads, id); delete this.uploads[id]; }, upload(item: UploadItem) { @@ -147,7 +144,7 @@ export const useUploadStore = defineStore("upload", { await api.post(item.path).catch(this.setError); } else { const onUpload = throttle( - (event) => + (event: ProgressEvent) => this.setProgress({ id: item.id, loaded: event.loaded, @@ -157,7 +154,7 @@ export const useUploadStore = defineStore("upload", { ); await api - .post(item.path, item.file, item.overwrite, onUpload) + .post(item.path, item.file.file as File, item.overwrite, onUpload) .catch(this.setError); } diff --git a/frontend/src/types/file.d.ts b/frontend/src/types/file.d.ts index fd950460..6e7868d9 100644 --- a/frontend/src/types/file.d.ts +++ b/frontend/src/types/file.d.ts @@ -9,7 +9,6 @@ interface ResourceBase { isSymlink: boolean; type: ResourceType; url: string; - fullPath?: string; } interface Resource extends ResourceBase { diff --git a/frontend/src/types/upload.d.ts b/frontend/src/types/upload.d.ts index b72ec624..d528ba22 100644 --- a/frontend/src/types/upload.d.ts +++ b/frontend/src/types/upload.d.ts @@ -1,19 +1,31 @@ interface Uploads { - [key: string]: Upload; + [key: number]: Upload; } interface Upload { id: number; - file: Resource; - type: string; + file: UploadEntry; + type?: ResourceType; } interface UploadItem { id: number; url?: string; path: string; - file: Resource; + file: UploadEntry; dir?: boolean; overwrite?: boolean; type?: ResourceType; } + +interface UploadEntry { + fullPath: string; + isDir: boolean; + name: string; + size: number; + file?: File; +} + +type UploadList = UploadEntry[]; + +type Progress = number | boolean; diff --git a/frontend/src/utils/upload.ts b/frontend/src/utils/upload.ts index a222e071..2436d5cc 100644 --- a/frontend/src/utils/upload.ts +++ b/frontend/src/utils/upload.ts @@ -2,7 +2,7 @@ import { useUploadStore } from "@/stores/upload"; import url from "@/utils/url"; export function checkConflict( - files: ResourceItem[], + files: UploadList, dest: ResourceItem[] ): boolean { if (typeof dest === "undefined" || dest === null) { @@ -11,7 +11,7 @@ export function checkConflict( const folder_upload = files[0].fullPath !== undefined; - const names: string[] = []; + const names = new Set(); for (let i = 0; i < files.length; i++) { const file = files[i]; let name = file.name; @@ -23,39 +23,48 @@ export function checkConflict( } } - names.push(name); + names.add(name); } - return dest.some((d) => names.includes(d.name)); + return dest.some((d) => names.has(d.name)); } -export function scanFiles(dt: { [key: string]: any; item: ResourceItem }) { +export function scanFiles(dt: DataTransfer) { return new Promise((resolve) => { let reading = 0; - const contents: any[] = []; + const contents: UploadList = []; - if (dt.items !== undefined) { - for (const item of dt.items) { + if (dt.items) { + // ts didnt like the for of loop even tho + // it is the official example on MDN + // for (const item of dt.items) { + for (let i = 0; i < dt.items.length; i++) { + const item = dt.items[i]; if ( item.kind === "file" && typeof item.webkitGetAsEntry === "function" ) { const entry = item.webkitGetAsEntry(); - readEntry(entry); + entry && readEntry(entry); } } } else { resolve(dt.files); } - function readEntry(entry: any, directory = "") { + function readEntry(entry: FileSystemEntry, directory = ""): void { if (entry.isFile) { reading++; - entry.file((file: Resource) => { + (entry as FileSystemFileEntry).file((file) => { reading--; - file.fullPath = `${directory}${file.name}`; - contents.push(file); + contents.push({ + file, + name: file.name, + size: file.size, + isDir: false, + fullPath: `${directory}${file.name}`, + }); if (reading === 0) { resolve(contents); @@ -71,14 +80,20 @@ export function scanFiles(dt: { [key: string]: any; item: ResourceItem }) { contents.push(dir); - readReaderContent(entry.createReader(), `${directory}${entry.name}`); + readReaderContent( + (entry as FileSystemDirectoryEntry).createReader(), + `${directory}${entry.name}` + ); } } - function readReaderContent(reader: any, directory: string) { + function readReaderContent( + reader: FileSystemDirectoryReader, + directory: string + ): void { reading++; - reader.readEntries(function (entries: any[]) { + reader.readEntries((entries) => { reading--; if (entries.length > 0) { for (const entry of entries) { @@ -106,16 +121,15 @@ function detectType(mimetype: string): ResourceType { } export function handleFiles( - files: Resource[], + files: UploadList, base: string, overwrite = false ) { const uploadStore = useUploadStore(); - for (let i = 0; i < files.length; i++) { + for (const file of files) { const id = uploadStore.id; let path = base; - const file = files[i]; if (file.fullPath !== undefined) { path += url.encodePath(file.fullPath); @@ -127,12 +141,14 @@ export function handleFiles( path += "/"; } + console.log("File", file); + const item: UploadItem = { id, path, file, overwrite, - ...(!file.isDir && { type: detectType(file.type) }), + ...(!file.isDir && { type: detectType((file.file as File).type) }), }; uploadStore.upload(item);