quackscape/assets/js/userarea.js
Kumi 6dc56e02bd
feat(userarea.js): enhance file upload feedback
Enhanced the file upload feedback mechanism in `userarea.js` by
introducing a clearer, success indication and preparing for future
implementations where upload completion will trigger additional checks
against the API for resolution availability. This change brings a more
intuitive user experience during file uploads and lays groundwork for
next steps in upload handling, ensuring users are better informed of the
upload status in real-time.

- Imported `getElementById` for future feature expansion.
- Added a TODO comment as a placeholder for upcoming API check
functionality.
2024-03-16 21:57:25 +01:00

144 lines
4.2 KiB
JavaScript

import "../scss/frontend.scss";
import "../css/userarea.css";
import { getCookie, getElementById } from "./api";
import { Tab } from "bootstrap";
import DataTable from "datatables.net-dt";
let mediaTable = new DataTable("#mediaTable");
let scenesTable = new DataTable("#scenesTable");
let permissionsTable = new DataTable("#permissionsTable");
/* Uploads */
document.querySelectorAll(".drop-zone__input").forEach((inputElement) => {
const dropZoneElement = inputElement.closest(".drop-zone");
dropZoneElement.addEventListener("click", (e) => {
inputElement.click();
});
dropZoneElement.addEventListener("dragover", (e) => {
e.preventDefault();
dropZoneElement.classList.add("drop-zone--over");
});
["dragleave", "dragend", "drop"].forEach((type) => {
dropZoneElement.addEventListener(type, (e) => {
dropZoneElement.classList.remove("drop-zone--over");
});
});
dropZoneElement.addEventListener("drop", (e) => {
e.preventDefault();
if (e.dataTransfer.files.length) {
inputElement.files = e.dataTransfer.files;
handleFiles(inputElement.files);
}
});
inputElement.addEventListener("change", (e) => {
if (inputElement.files.length) {
handleFiles(inputElement.files);
}
});
});
function handleFiles(files) {
const uploadStatus = document.getElementById("uploadStatus");
Array.from(files).forEach((file) => {
const fileRow = document.createElement("div");
fileRow.classList.add(
"row",
"align-items-center",
"mb-2",
"file-upload-wrapper"
);
const thumbnailCol = document.createElement("div");
thumbnailCol.classList.add("col-2");
const thumbnail = document.createElement("img");
thumbnail.classList.add("img-fluid", "thumbnail");
thumbnail.src = ""; // Placeholder until upload completes
thumbnailCol.appendChild(thumbnail);
const fileNameCol = document.createElement("div");
fileNameCol.classList.add("col-7");
const fileName = document.createElement("span");
fileName.classList.add("file-name");
fileName.textContent = file.name;
fileNameCol.appendChild(fileName);
const progressCol = document.createElement("div");
progressCol.classList.add("col-3");
const progressBar = document.createElement("div");
progressBar.classList.add("progress");
const progressBarInner = document.createElement("div");
progressBarInner.classList.add("progress-bar");
progressBarInner.setAttribute("role", "progressbar");
progressBarInner.setAttribute("aria-valuemin", "0");
progressBarInner.setAttribute("aria-valuemax", "100");
progressBarInner.style.width = "0%";
progressBar.appendChild(progressBarInner);
progressCol.appendChild(progressBar);
fileRow.appendChild(thumbnailCol);
fileRow.appendChild(fileNameCol);
fileRow.appendChild(progressCol);
uploadStatus.prepend(fileRow);
uploadFile(file, progressBarInner, thumbnail);
});
}
function uploadFile(file, progressBar, thumbnail) {
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append("file", file);
formData.append("csrfmiddlewaretoken", getCookie("csrftoken"));
if (file.type.startsWith("image")) {
formData.append("media_type", "image");
} else if (file.type.startsWith("video")) {
formData.append("media_type", "video");
} else {
formData.append("media_type", "other");
}
formData.append("title", file.name);
xhr.upload.addEventListener("progress", (e) => {
if (e.lengthComputable) {
if (e.loaded == e.total) {
progressBar.style.width = "100%";
progressBar.textContent = "Processing...";
} else {
const percentComplete = (e.loaded / e.total) * 100;
progressBar.style.width = `${percentComplete}%`;
progressBar.textContent = `${Math.round(percentComplete)}%`;
}
}
});
xhr.open("POST", document.location.href, true);
xhr.onload = () => {
if (xhr.status === 201) {
const response = JSON.parse(xhr.responseText);
progressBar.classList.add("bg-success");
progressBar.textContent = "Success!";
// TODO: Check API until the first resolution is available
} else {
progressBar.classList.add("bg-danger");
progressBar.textContent = "Error!";
}
};
xhr.send(formData);
}