quackscape/assets/js/userarea.js
Kumi f5723de9fd
refactor(userarea.js): senhance file upload
UX

Uniformly changed single quotes to double quotes for consistency
throughout userarea.js. Improved the file upload feature by refining the
visual feedback during file upload processes. This includes more
descriptive progress and success/error messages, ensuring users have
clear, immediate insight into the state of their uploads. Additionally,
refined the data submission structure in `uploadFile`, explicitly
assigning file type and title, optimizing for better server-side
processing. These changes enhance code readability and user experience.
2024-03-16 21:44:22 +01:00

143 lines
4.2 KiB
JavaScript

import "../scss/frontend.scss";
import "../css/userarea.css";
import { getCookie } 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);
const thumbnailUrl = response.thumbnailUrl;
thumbnail.src = thumbnailUrl;
progressBar.classList.add("bg-success");
progressBar.textContent = "Success!";
} else {
progressBar.classList.add("bg-danger");
progressBar.textContent = "Error!";
}
};
xhr.send(formData);
}