Kumi
6da2f19f42
library - Implemented the media deletion functionality, allowing users to delete media entries directly from the category view. This enhances the manageability of content within the platform, providing a more intuitive and streamlined experience for users managing their media. - Transitioned from FontAwesome to Phosphor Icons, opting for a lighter and more flexible icon library that better aligns with the design ethos of the application. This change not only introduces a fresh aesthetic but also contributes to slightly improved page load times due to the decreased footprint of the icon library. - Updated various UI elements across the platform to maintain a consistent look and feel, including adjustments in the user area CSS to ensure visual compatibility with the new icon set. - Broadened the scope of `.gitignore` to cover all JavaScript files within the static/js directory, eliminating potential version control clutter caused by dynamically generated or dependency-included JS files. These changes collectively aim to refine user interaction and ensure a more cohesive visual presentation throughout the application.
152 lines
4.6 KiB
JavaScript
152 lines
4.6 KiB
JavaScript
import "../scss/frontend.scss";
|
|
import "../css/userarea.css";
|
|
import "@phosphor-icons/web/light";
|
|
|
|
import { getCategoryMedia, 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 = ""; // TODO: Add a loading spinner or something here
|
|
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.textContent = "Converting...";
|
|
|
|
let thumbnailCheck = setInterval(() => {
|
|
getCategoryMedia(response.category, response.id).then((media) => {
|
|
if (media.obj.resolutions.length > 0) {
|
|
clearInterval(thumbnailCheck);
|
|
thumbnail.src = media.obj.resolutions[0].file;
|
|
|
|
progressBar.classList.add("bg-success");
|
|
progressBar.textContent = "Done!";
|
|
}
|
|
});
|
|
}, 2000);
|
|
} else {
|
|
progressBar.classList.add("bg-danger");
|
|
progressBar.textContent = "Error!";
|
|
}
|
|
};
|
|
xhr.send(formData);
|
|
}
|