diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte
index 777abb48..71a5c93b 100644
--- a/frontend/src/routes/+page.svelte
+++ b/frontend/src/routes/+page.svelte
@@ -25,6 +25,7 @@ let isDragging = $state(false);
let windowDragging = $state(false);
let dragCounter = 0;
let isUploading = $state(false);
+let uploadProgress = $state(0);
let uploadMessages = $state<{ text: string; isError: boolean; link?: string }[]>([]);
let fileInput: HTMLInputElement;
@@ -85,19 +86,26 @@ async function uploadFiles(files: File[]) {
}
isUploading = true;
+ uploadProgress = 0;
try {
const formData = new FormData();
for (const file of valid) {
formData.append('files', file);
}
- const res = await fetch('/api/documents/quick-upload', {
- method: 'POST',
- body: formData
+ const { ok, body } = await new Promise<{ ok: boolean; body: string }>((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', '/api/documents/quick-upload');
+ xhr.upload.addEventListener('progress', (e) => {
+ if (e.lengthComputable) uploadProgress = Math.round((e.loaded / e.total) * 100);
+ });
+ xhr.addEventListener('load', () => resolve({ ok: xhr.status < 300, body: xhr.responseText }));
+ xhr.addEventListener('error', () => reject(new Error('Network error')));
+ xhr.send(formData);
});
- if (res.ok) {
- const result = await res.json();
+ if (ok) {
+ const result = JSON.parse(body);
if (result.created?.length > 0) {
messages.push({ text: m.upload_success({ count: result.created.length }), isError: false });
}
@@ -122,6 +130,7 @@ async function uploadFiles(files: File[]) {
}
} finally {
isUploading = false;
+ uploadProgress = 0;
uploadMessages = messages;
}
}
@@ -372,10 +381,20 @@ $effect(() => {