parcel/templates/index.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 %}