refactor(code): Cleaned-up the code base
This commit is contained in:
139
static/js/upload/api.js
Normal file
139
static/js/upload/api.js
Normal file
@@ -0,0 +1,139 @@
|
||||
async function createBox() {
|
||||
const response = await fetch("/box", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
retention_key: el.expiry?.value || defaultRetention,
|
||||
password: el.password?.value || "",
|
||||
allow_zip: isOneTimeDownloadSelected() || !el.allowZip || el.allowZip.checked,
|
||||
files: files.map((item) => ({ name: item.displayName, size: item.file.size })),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await readJSON(response);
|
||||
if (!response.ok) throw new Error(result.error || "Could not create upload box");
|
||||
return result;
|
||||
}
|
||||
|
||||
async function readJSON(response) {
|
||||
try {
|
||||
return await response.json();
|
||||
} catch (_) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function markFileStatus(item, status) {
|
||||
if (!item.boxID || !item.boxFile) return;
|
||||
try {
|
||||
await fetch(`/box/${item.boxID}/files/${item.boxFile.id}/status`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ status }),
|
||||
});
|
||||
} catch (_) {
|
||||
// Best effort only. The upload endpoint also marks hard failures.
|
||||
}
|
||||
}
|
||||
|
||||
function setFileFailed(item, message) {
|
||||
item.failed = true;
|
||||
item.uploaded = false;
|
||||
item.error = message || "Failed to upload";
|
||||
item.loaded = item.file.size;
|
||||
item.row?.classList.remove("is-working", "is-uploaded");
|
||||
item.row?.classList.add("is-failed");
|
||||
if (item.row) item.row.title = item.error;
|
||||
setRowProgress(item, 100);
|
||||
updateOverallProgress();
|
||||
}
|
||||
|
||||
function markCompletedImpact(item) {
|
||||
const key = item.boxFile?.id || item.displayName;
|
||||
if (completedImpactKeys.has(key)) return;
|
||||
completedImpactKeys.add(key);
|
||||
flashProgressBar(item.row?.querySelector(".upload-progress-bar"));
|
||||
}
|
||||
|
||||
function uploadFile(item, onComplete) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const formData = new FormData();
|
||||
formData.append("file", item.file, item.displayName);
|
||||
|
||||
xhr.open("POST", item.boxFile.upload_path);
|
||||
|
||||
xhr.upload.addEventListener("loadstart", () => {
|
||||
item.loaded = 0;
|
||||
item.failed = false;
|
||||
item.uploaded = false;
|
||||
item.row?.classList.remove("is-failed", "is-uploaded");
|
||||
item.row?.classList.add("is-working");
|
||||
setRowProgress(item, 2);
|
||||
updateOverallProgress();
|
||||
});
|
||||
|
||||
xhr.upload.addEventListener("progress", (event) => {
|
||||
if (!event.lengthComputable) return;
|
||||
item.loaded = Math.min(event.loaded, item.file.size);
|
||||
const percent = (event.loaded / event.total) * 100;
|
||||
setRowProgress(item, percent >= 100 ? 99 : percent);
|
||||
updateOverallProgress();
|
||||
});
|
||||
|
||||
xhr.addEventListener("load", async () => {
|
||||
if (xhr.status < 200 || xhr.status >= 300) {
|
||||
let message = "Upload failed";
|
||||
try {
|
||||
message = JSON.parse(xhr.responseText).error || message;
|
||||
} catch (_) {}
|
||||
setFileFailed(item, message);
|
||||
await markFileStatus(item, "failed");
|
||||
reject(new Error(message));
|
||||
return;
|
||||
}
|
||||
|
||||
item.uploaded = true;
|
||||
item.failed = false;
|
||||
item.loaded = item.file.size;
|
||||
item.row?.classList.remove("is-working", "is-failed");
|
||||
item.row?.classList.add("is-uploaded");
|
||||
if (item.row) item.row.title = "Uploaded";
|
||||
setRowProgress(item, 100);
|
||||
markCompletedImpact(item);
|
||||
|
||||
try {
|
||||
const result = JSON.parse(xhr.responseText);
|
||||
if (result.file) {
|
||||
item.boxFile = result.file;
|
||||
const icon = item.row?.querySelector(".upload-file-icon");
|
||||
if (icon && result.file.thumbnail_path) {
|
||||
item.row.classList.add("has-thumbnail");
|
||||
icon.src = result.file.thumbnail_path;
|
||||
} else if (icon && result.file.icon_path && !item.previewURL) {
|
||||
icon.src = result.file.icon_path;
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
updateOverallProgress();
|
||||
onComplete();
|
||||
resolve();
|
||||
});
|
||||
|
||||
xhr.addEventListener("error", async () => {
|
||||
setFileFailed(item, "Network error while uploading");
|
||||
await markFileStatus(item, "failed");
|
||||
reject(new Error("Network error while uploading"));
|
||||
});
|
||||
|
||||
xhr.addEventListener("abort", async () => {
|
||||
setFileFailed(item, "Upload cancelled");
|
||||
await markFileStatus(item, "failed");
|
||||
reject(new Error("Upload cancelled"));
|
||||
});
|
||||
|
||||
markFileStatus(item, "uploading");
|
||||
xhr.send(formData);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user