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.
This commit is contained in:
Kumi 2024-03-16 21:44:22 +01:00
parent 53d90cb070
commit f5723de9fd
Signed by: kumi
GPG key ID: ECBCC9082395383F

View file

@ -1,132 +1,142 @@
import '../scss/frontend.scss';
import '../css/userarea.css';
import "../scss/frontend.scss";
import "../css/userarea.css";
import { getCookie } from './api';
import { getCookie } from "./api";
import { Tab } from 'bootstrap';
import DataTable from 'datatables.net-dt';
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');
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');
document.querySelectorAll(".drop-zone__input").forEach((inputElement) => {
const dropZoneElement = inputElement.closest(".drop-zone");
dropZoneElement.addEventListener('click', e => {
inputElement.click();
});
dropZoneElement.addEventListener("click", (e) => {
inputElement.click();
});
dropZoneElement.addEventListener('dragover', e => {
e.preventDefault();
dropZoneElement.classList.add('drop-zone--over');
});
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');
});
["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);
}
});
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);
}
});
inputElement.addEventListener("change", (e) => {
if (inputElement.files.length) {
handleFiles(inputElement.files);
}
});
});
function handleFiles(files) {
const uploadStatus = document.getElementById('uploadStatus');
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');
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 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 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);
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);
fileRow.appendChild(thumbnailCol);
fileRow.appendChild(fileNameCol);
fileRow.appendChild(progressCol);
uploadStatus.prepend(fileRow);
uploadStatus.prepend(fileRow);
uploadFile(file, progressBarInner, thumbnail);
});
uploadFile(file, progressBarInner, thumbnail);
});
}
function uploadFile(file, progressBar, thumbnail) {
const xhr = new XMLHttpRequest();
const formData = new FormData();
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('file', file);
formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
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');
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)}%`;
}
}
});
formData.append('title', file.name);
xhr.open("POST", document.location.href, true);
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
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);
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);
}