refactored uploadFiles()

This commit is contained in:
2025-08-30 00:45:12 +02:00
parent 9d1d2b3299
commit f2f6f0f24c

View File

@@ -188,6 +188,17 @@
return link; return link;
} }
function finishUpload(success) {
UI.overallProgressContainer.style.display = "none";
UI.overallProgress.value = 0;
UI.overallStatus.textContent = "";
UI.currentFileName.textContent = "";
fetchFiles();
if (success) {
showSuccess("Upload successful");
}
}
function getUIElements() { function getUIElements() {
UI.currentFileName = document.getElementById("currentFileName"); UI.currentFileName = document.getElementById("currentFileName");
UI.dropzone = document.getElementById("dropzone"); UI.dropzone = document.getElementById("dropzone");
@@ -219,6 +230,13 @@
return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s"; return (bytesPerSec / (1024 * 1024)).toFixed(2) + " MB/s";
} }
function initUIProgress() {
UI.overallProgressContainer.style.display = "block";
UI.overallProgress.value = 0;
UI.overallStatus.textContent = "";
UI.currentFileName.textContent = "";
}
function renderFileList(files) { function renderFileList(files) {
if (!UI.fileList) return; if (!UI.fileList) return;
@@ -324,43 +342,23 @@
const files = Array.from(fileListLike); const files = Array.from(fileListLike);
if (files.length === 0) return; if (files.length === 0) return;
for (const f of files) { if (!validateFiles(files)) return;
if (sanitizeFilename(f.name) == ".upload") {
showError("Invalid filename: .upload");
return;
}
if (sanitizeFilename(f.name) in Files) {
showError("File already exists: " + f.name);
return;
}
}
let noErrorOccurred = true; initUIProgress();
UI.overallProgressContainer.style.display = "block";
UI.overallProgress.value = 0;
UI.overallStatus.textContent = "";
UI.currentFileName.textContent = "";
const totalSize = files.reduce((sum, f) => sum + f.size, 0); const totalSize = files.reduce((sum, f) => sum + f.size, 0);
let uploadedBytes = 0; let uploadedBytes = 0;
const t0 = Date.now(); let currentIndex = 0;
let idx = 0; const startTime = Date.now();
let allSuccessful = true;
const uploadNext = () => { function uploadNext() {
if (idx >= files.length) { if (currentIndex >= files.length) {
UI.overallProgressContainer.style.display = "none"; finishUpload(allSuccessful);
UI.overallProgress.value = 0;
UI.overallStatus.textContent = "";
UI.currentFileName.textContent = "";
fetchFiles();
if (noErrorOccurred) {
showSuccess("Upload successful");
}
return; return;
} }
const file = files[idx]; const file = files[currentIndex];
UI.currentFileName.textContent = file.name; UI.currentFileName.textContent = file.name;
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
@@ -368,60 +366,76 @@
form.append("uploadfile", file); form.append("uploadfile", file);
xhr.upload.addEventListener("progress", (e) => { xhr.upload.addEventListener("progress", (e) => {
if (!e.lengthComputable) return; if (e.lengthComputable) {
updateProgressUI(uploadedBytes + e.loaded, totalSize, startTime);
const totalUploaded = uploadedBytes + e.loaded; }
const percent = (totalUploaded / totalSize) * 100;
UI.overallProgress.value = percent;
const elapsed = (Date.now() - t0) / 1000;
const speed = totalUploaded / elapsed;
const speedStr = humanReadableSpeed(speed);
const remainingBytes = totalSize - totalUploaded;
const etaSec = speed > 0 ? remainingBytes / speed : Infinity;
const min = Math.floor(etaSec / 60);
const sec = Math.floor(etaSec % 60);
UI.overallStatus.textContent =
`${percent.toFixed(1)}% (${(totalSize / 1024 / 1024).toFixed(
1
)} MB total) — ` +
`Speed: ${speedStr}, Est. time left: ${
isFinite(etaSec) ? `${min}m ${sec}s` : "calculating…"
}`;
}); });
xhr.addEventListener("load", () => { xhr.addEventListener("load", () => {
if (xhr.status === 200) { if (xhr.status === 200) {
uploadedBytes += file.size; uploadedBytes += file.size;
} else if (xhr.status === 409) {
showError("File already exists: " + file.name);
allSuccessful = false;
} else { } else {
if (xhr.status === 409) { showError("Upload failed: " + file.name);
showError("File already exists: " + file.name); allSuccessful = false;
noErrorOccurred = false;
} else {
showError("Upload failed: " + file.name);
noErrorOccurred = false;
}
} }
idx++; currentIndex++;
uploadNext(); uploadNext();
}); });
xhr.addEventListener("error", () => { xhr.addEventListener("error", () => {
showError("Network or server error during upload."); showError("Network or server error during upload.");
noErrorOccurred = false; allSuccessful = false;
idx++; currentIndex++;
uploadNext(); uploadNext();
}); });
xhr.open("POST", AppConfig.Endpoints.Upload); xhr.open("POST", AppConfig.Endpoints.Upload);
xhr.send(form); xhr.send(form);
}; }
fetchFiles(); fetchFiles();
uploadNext(); uploadNext();
} }
function updateProgressUI(totalUploaded, totalSize, startTime) {
const percent = (totalUploaded / totalSize) * 100;
UI.overallProgress.value = percent;
const elapsed = (Date.now() - startTime) / 1000;
const speed = totalUploaded / elapsed;
const speedStr = humanReadableSpeed(speed);
const remainingBytes = totalSize - totalUploaded;
const etaSec = speed > 0 ? remainingBytes / speed : Infinity;
const min = Math.floor(etaSec / 60);
const sec = Math.floor(etaSec % 60);
UI.overallStatus.textContent =
`${percent.toFixed(1)}% (${(totalSize / 1024 / 1024).toFixed(
1
)} MB total) — ` +
`Speed: ${speedStr}, Est. time left: ${
isFinite(etaSec) ? `${min}m ${sec}s` : "calculating…"
}`;
}
function validateFiles(files) {
for (const f of files) {
const safeName = sanitizeFilename(f.name);
if (safeName === ".upload") {
showError("Invalid filename: .upload");
return false;
}
if (safeName in Files) {
showError("File already exists: " + f.name);
return false;
}
}
return true;
}
document.addEventListener("DOMContentLoaded", initApp); document.addEventListener("DOMContentLoaded", initApp);
})(); })();