diff --git a/apps/app-frontend/src/pages/instance/Files.vue b/apps/app-frontend/src/pages/instance/Files.vue index 72d75cfceb..c64adee333 100644 --- a/apps/app-frontend/src/pages/instance/Files.vue +++ b/apps/app-frontend/src/pages/instance/Files.vue @@ -229,7 +229,6 @@ async function handleDownloadFile(path: string, _fileName: string) { const uploadState = ref({ isUploading: false, currentFileName: null, - currentFileProgress: 0, uploadedBytes: 0, totalBytes: 0, completedFiles: 0, @@ -241,8 +240,7 @@ async function handleUploadFiles(files: File[]) { uploadState.value = { isUploading: true, - currentFileName: '', - currentFileProgress: 0, + currentFileName: files[0]?.name ?? null, uploadedBytes: 0, totalBytes: files.reduce((sum, f) => sum + f.size, 0), completedFiles: 0, @@ -258,7 +256,6 @@ async function handleUploadFiles(files: File[]) { await writeFileBytes(targetPath, new Uint8Array(buffer)) uploadState.value.completedFiles++ uploadState.value.uploadedBytes += file.size - uploadState.value.currentFileProgress = 1 } } catch (e) { addNotification({ diff --git a/packages/api-client/src/platform/xhr-upload-client.ts b/packages/api-client/src/platform/xhr-upload-client.ts index d16e765899..60d4e6b8f6 100644 --- a/packages/api-client/src/platform/xhr-upload-client.ts +++ b/packages/api-client/src/platform/xhr-upload-client.ts @@ -96,13 +96,16 @@ export abstract class XHRUploadClient extends AbstractModrinthClient { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() const metadata = context.metadata as UploadMetadata + const fallbackTotal = this.getUploadPayloadSize(metadata) xhr.upload.addEventListener('progress', (e) => { - if (e.lengthComputable) { + const total = e.lengthComputable ? e.total : fallbackTotal + if (total > 0) { + const loaded = Math.min(e.loaded, total) const progress: UploadProgress = { - loaded: e.loaded, - total: e.total, - progress: e.loaded / e.total, + loaded, + total, + progress: loaded / total, } progressCallbacks.forEach((cb) => cb(progress)) } @@ -146,6 +149,18 @@ export abstract class XHRUploadClient extends AbstractModrinthClient { }) } + private getUploadPayloadSize(metadata: UploadMetadata): number { + if ('file' in metadata) { + return metadata.file.size + } + + let total = 0 + metadata.formData.forEach((value) => { + total += value instanceof Blob ? value.size : new Blob([value]).size + }) + return total + } + protected createUploadError(xhr: XMLHttpRequest): ModrinthApiError { let responseData: unknown try { diff --git a/packages/api-client/src/types/upload.ts b/packages/api-client/src/types/upload.ts index 61e50dc94d..467faa9a28 100644 --- a/packages/api-client/src/types/upload.ts +++ b/packages/api-client/src/types/upload.ts @@ -93,7 +93,6 @@ export interface UploadHandle { export interface UploadState { isUploading: boolean currentFileName: string | null - currentFileProgress: number uploadedBytes: number totalBytes: number completedFiles: number diff --git a/packages/ui/src/components/servers/admonitions/UploadAdmonition.vue b/packages/ui/src/components/servers/admonitions/UploadAdmonition.vue index 7c0656d9ef..bd1e14cb74 100644 --- a/packages/ui/src/components/servers/admonitions/UploadAdmonition.vue +++ b/packages/ui/src/components/servers/admonitions/UploadAdmonition.vue @@ -1,18 +1,14 @@