visibly Improve user feedback during file uploads by explicitly handling HTTP 201 responses as successful uploads. Upon a successful upload, the progress bar now turns green (`bg-success`) and displays a "Success!" message, providing a clearer and more immediate visual cue to the user that their file has been successfully uploaded. This change addresses usability issues by making the upload progress and outcome more discernible to users.
133 lines
4.4 KiB
JavaScript
133 lines
4.4 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) {
|
|
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);
|
|
}
|