summaryrefslogtreecommitdiff
path: root/public/static/scripts/upload.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/static/scripts/upload.js')
-rw-r--r--public/static/scripts/upload.js224
1 files changed, 224 insertions, 0 deletions
diff --git a/public/static/scripts/upload.js b/public/static/scripts/upload.js
new file mode 100644
index 0000000..f180d9a
--- /dev/null
+++ b/public/static/scripts/upload.js
@@ -0,0 +1,224 @@
+function createUploadedFileItem(data) {
+ const base = document.createElement("div");
+ base.classList.add("box", "item", "column", "gap-4", "pad-4");
+
+ const previewContainer = document.createElement("div");
+ previewContainer.classList.add("column", "align-center", "justify-center", "grow");
+ base.appendChild(previewContainer);
+
+ const preview = document.createElement("img");
+ preview.alt = "No thumbnail.";
+ previewContainer.appendChild(preview);
+
+ const header = document.createElement("h2");
+ base.appendChild(header);
+
+ const description = document.createElement("div");
+ base.appendChild(description);
+
+ const buttons = document.createElement("div");
+ buttons.classList.add("row", "gap-8");
+ base.appendChild(buttons);
+
+ if (data) {
+ if (data.mime.startsWith("audio/")) {
+ preview.src = "/static/img/icons/file_audio.png";
+ } else if (data.mime.startsWith("text/")) {
+ preview.src = "/static/img/icons/file_text.png";
+ } else if (data.mime == "application/x-shockwave-flash") {
+ preview.src = "/static/img/icons/file_flash.png";
+ } else if (!data.mime.startsWith("image/") && !data.mime.startsWith("video/")) {
+ preview.src = "/static/img/icons/file.png";
+ } else {
+ preview.src = `${thumbnailPathPrefix}/${data.id}.webp`;
+ }
+
+ header.textContent = `${data.id}.${data.extension}`;
+
+ const mime = document.createElement("p");
+ description.appendChild(mime);
+ mime.textContent = data.mime;
+
+ const size = document.createElement("p");
+ description.appendChild(size);
+ size.textContent = (data.size / 1024 / 1024).toFixed(2) + " MB";
+
+ if (data.id && data.extension) {
+ const url = `${window.location.href}${data.id}.${data.extension}`;
+ const link = document.createElement("a");
+ link.href = url;
+ const btn = document.createElement("button");
+ btn.textContent = "Open";
+ link.appendChild(btn);
+ buttons.appendChild(link);
+
+ const copyBtn = document.createElement("button");
+ copyBtn.addEventListener("click", () => {
+ navigator.clipboard.writeText(url);
+ });
+ const copyImg = document.createElement("img");
+ copyImg.src = "/static/img/icons/paste_plain.png";
+ copyBtn.appendChild(copyImg);
+ buttons.appendChild(copyBtn);
+ }
+
+ if (data.urls && data.urls.deletion_url) {
+ const btn = document.createElement("button");
+ btn.addEventListener("click", () => {
+ deleteUploadedFile(data.urls.deletion_url, data.id);
+ });
+
+ const img = document.createElement("img");
+ img.src = "/static/img/icons/cross.png";
+ btn.appendChild(img);
+
+ buttons.appendChild(btn);
+ }
+ }
+
+ return {
+ "base": base,
+ "preview": preview,
+ "header": header,
+ "description": description,
+ "buttons": buttons
+ };
+}
+
+function getUploadedFiles() {
+ const files = JSON.parse(localStorage.getItem("uploaded_files") ?? "[]");
+ return files;
+}
+
+function saveUploadedFile(data) {
+ const files = getUploadedFiles();
+ files.unshift(data);
+ localStorage.setItem("uploaded_files", JSON.stringify(files));
+}
+
+function displayUploadedFile(data) {
+ const items = document.getElementById("uploaded-files");
+ if (items) {
+ items.prepend(createUploadedFileItem(data).base);
+ }
+}
+
+function displayUploadedFiles() {
+ const files = getUploadedFiles();
+ for (const file of files) {
+ displayUploadedFile(file);
+ }
+}
+
+function deleteUploadedFile(url, id) {
+ if (confirm("Do you want to delete file locally?")) {
+ let files = getUploadedFiles();
+ files = files.filter((x) => x.id !== id);
+ localStorage.setItem("uploaded_files", JSON.stringify(files));
+ }
+
+ if (url && confirm(`Are you sure you want to delete file ID ${id} from the servers?`)) {
+ fetch(url, {
+ 'headers': {
+ 'Accept': 'application/json'
+ },
+ 'method': 'DELETE'
+ }).then((r) => r.json())
+ .then((json) => {
+ if (json.status_code != 200) {
+ alert(`${json.message} (${json.status_code})`);
+ }
+ })
+ .catch((err) => {
+ alert('Failed to delete the file. Look into the console!');
+ console.error(err);
+ });
+ }
+}
+
+function uploadData(data) {
+ const status = document.createElement("p");
+
+ const bar = document.createElement("progress");
+ bar.max = 100;
+
+ const item = createUploadedFileItem(null);
+ item.description.appendChild(bar);
+ item.description.appendChild(status);
+
+ // setting item name
+ if (data.get("file") != null) {
+ let name = data.get("file").name;
+ if (name.length > 10) {
+ name = name.substring(0, 7) + '...';
+ }
+ item.header.textContent = name;
+ item.header.style.fontStyle = "italic";
+ }
+
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', '/upload.php');
+ xhr.setRequestHeader("Accept", "application/json");
+
+ xhr.upload.onprogress = (e) => {
+ if (e.lengthComputable) {
+ const percent = Math.round((e.loaded / e.total) * 100);
+ bar.value = percent;
+ status.textContent = `Uploading file: ${percent}%`;
+ } else {
+ status.textContent = "Uploading...";
+ }
+ };
+
+ xhr.onload = () => {
+ const j = JSON.parse(xhr.responseText);
+
+ if (xhr.status == 201) {
+ status.textContent = "Uploaded!";
+ bar.value = 100;
+
+ const d = j.data;
+ item.base.remove();
+ saveUploadedFile(d);
+ displayUploadedFile(d);
+ } else {
+ status.textContent = `Upload failed: ${j.message} (${xhr.status})`;
+ item.buttons.remove();
+ }
+ };
+
+ xhr.onerror = () => {
+ status.textContent = "Upload error";
+ item.buttons.remove();
+ };
+
+ xhr.send(data);
+
+ const abortButton = document.createElement("button");
+ abortButton.addEventListener("click", () => {
+ xhr.abort();
+ item.base.remove();
+ alert("File upload has been aborted.");
+ });
+ item.buttons.appendChild(abortButton);
+ const abortButtonImg = document.createElement("img");
+ abortButtonImg.alt = "Abort";
+ abortButtonImg.src = "/static/img/icons/cross.png";
+ abortButton.appendChild(abortButtonImg);
+
+ const items = document.getElementById("uploaded-files");
+ if (items) {
+ items.prepend(item.base);
+ }
+}
+
+window.addEventListener("load", () => {
+ const itemsElement = document.getElementById("uploaded-files");
+ if (!itemsElement) return;
+
+ const files = getUploadedFiles();
+ files.forEach((x) => {
+ const item = createUploadedFileItem(x);
+ itemsElement.appendChild(item.base);
+ });
+}); \ No newline at end of file