123 lines
3.5 KiB
HTML
123 lines
3.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Home{% endblock %}
|
|
|
|
{% block content %}
|
|
<div
|
|
hx-get="/uploads"
|
|
hx-target="this"
|
|
hx-trigger="load"
|
|
hx-swap="beforeend"
|
|
class="container mx-auto flex flex-col gap-4">
|
|
|
|
<div class="panel thin gap-2">
|
|
<h1 class="heading">New Upload</h1>
|
|
<form id="upload-form" class="form">
|
|
<input type="file" class="field" name="file">
|
|
<progress id="progress" value="0" max="100" class="hidden"></progress>
|
|
<div class="buttons end mt-4">
|
|
<button type="submit" class="button" disabled>
|
|
{% include "icons/lucide/upload.svg" %}
|
|
Upload file
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.querySelectorAll(".clipboard-copy").forEach(element => {
|
|
element.addEventListener("click", () => {
|
|
const text = element.previousElementSibling.href;
|
|
const blob = new Blob([text], { type: "text/plain" });
|
|
const data = [new ClipboardItem({ ["text/plain"]: blob })];
|
|
navigator.clipboard.write(data);
|
|
|
|
document.querySelectorAll(".clipboard-copy").forEach(element => {
|
|
element.classList.remove("copied");
|
|
});
|
|
|
|
element.classList.add("copied");
|
|
});
|
|
});
|
|
|
|
function setErrorMessage(message) {
|
|
const existing = document.querySelector("#error");
|
|
if (existing) {
|
|
existing.innerHtml = message;
|
|
return;
|
|
}
|
|
|
|
const element = document.createElement("DIV");
|
|
element.classNames.add("text-danger");
|
|
element.innerHtml = message;
|
|
|
|
const form = document.querySelector("#upload-form");
|
|
form.parent.insertBefore(element, form);
|
|
|
|
document.querySelector("button[type='submit']").disabled = false;
|
|
document.querySelector("progress").classList.add("hidden");
|
|
}
|
|
|
|
const form = document.querySelector("#upload-form");
|
|
const input = document.querySelector("input[type='file']");
|
|
const progress = document.querySelector("progress");
|
|
const submit = document.querySelector("button[type='submit']");
|
|
|
|
input.addEventListener("change", (event) => {
|
|
submit.disabled = event.target.files.length === 0;
|
|
});
|
|
|
|
form.addEventListener("submit", (event) => {
|
|
event.preventDefault();
|
|
|
|
submit.disabled = true;
|
|
progress.classList.remove("hidden");
|
|
|
|
var total_size = 0;
|
|
const form_data = new FormData();
|
|
for (let field of event.target.elements) {
|
|
if (field.tagName !== "INPUT") {
|
|
continue;
|
|
}
|
|
|
|
if (field.type === "file") {
|
|
total_size += field.files[0].size;
|
|
form_data.append(field.name, field.files[0]);
|
|
} else {
|
|
form_data.append(field.name, field.value);
|
|
}
|
|
}
|
|
|
|
const request = new XMLHttpRequest();
|
|
|
|
request.addEventListener("load", (event) => {
|
|
htmx.trigger("#upload-refresh", "refresh-event", {});
|
|
|
|
input.value = null;
|
|
progress.classList.add("hidden");
|
|
submit.disabled = true;
|
|
});
|
|
|
|
request.addEventListener("error", (event) => {
|
|
setErrorMessage("Encountered and error uploading file");
|
|
});
|
|
|
|
request.addEventListener("abort", (event) => {
|
|
setErrorMessage("Upload was aborted");
|
|
});
|
|
|
|
request.upload.addEventListener("progress", (event) => {
|
|
const amount = Math.round(event.loaded / total_size * 100.0);
|
|
progress.value = amount;
|
|
});
|
|
|
|
request.open("POST", "/uploads");
|
|
request.send(form_data);
|
|
});
|
|
</script>
|
|
{% endblock %}
|