(function () { const form = document.querySelector("#upload-form"); const dropZone = document.querySelector(".drop-zone"); const fileInput = document.querySelector("#file-input"); const fileSummary = document.querySelector("#file-summary"); const progress = document.querySelector("#upload-progress"); const uploadStatus = document.querySelector("#upload-status"); const result = document.querySelector("#upload-result"); const resultMeta = document.querySelector("#result-meta"); const resultList = document.querySelector("#result-list"); const copyAll = document.querySelector("#copy-all"); const openBox = document.querySelector("#open-box"); if (!form || !dropZone || !fileInput) { return; } let latestLinks = []; ["dragenter", "dragover"].forEach((eventName) => { dropZone.addEventListener(eventName, (event) => { event.preventDefault(); dropZone.classList.add("is-dragging"); }); }); ["dragleave", "drop"].forEach((eventName) => { dropZone.addEventListener(eventName, (event) => { event.preventDefault(); dropZone.classList.remove("is-dragging"); }); }); dropZone.addEventListener("drop", (event) => { if (event.dataTransfer && event.dataTransfer.files.length > 0) { fileInput.files = event.dataTransfer.files; updateSelectedState(event.dataTransfer.files); } }); fileInput.addEventListener("change", () => { updateSelectedState(fileInput.files); }); form.addEventListener("submit", async (event) => { event.preventDefault(); if (!fileInput.files || fileInput.files.length === 0) { updateStatus("Choose at least one file first."); return; } const submit = form.querySelector("button[type='submit']"); const formData = new FormData(form); setLoading(true, submit); try { const response = await fetch(form.action, { method: "POST", body: formData, headers: { Accept: "application/json", }, }); const payload = await response.json(); if (!response.ok) { throw new Error(payload.error || "Upload failed"); } renderResult(payload); form.reset(); updateSelectedState([]); } catch (error) { updateStatus(error.message || "Upload failed"); } finally { setLoading(false, submit); } }); if (copyAll) { copyAll.addEventListener("click", () => { copyText(latestLinks.join("\n"), copyAll, "Copied"); }); } function updateSelectedState(files) { const count = files.length || 0; const title = dropZone.querySelector(".drop-title"); if (title) { title.textContent = count === 0 ? "Drop files to upload" : count === 1 ? "1 file selected" : `${count} files selected`; } if (fileSummary) { fileSummary.textContent = count === 0 ? "Choose one or more files to begin." : `${count} file${count === 1 ? "" : "s"} ready.`; } } function setLoading(isLoading, submit) { if (progress) { progress.hidden = !isLoading; } if (submit) { submit.disabled = isLoading; submit.textContent = isLoading ? "Uploading..." : "Upload files"; } updateStatus(isLoading ? "Transferring files..." : ""); } function updateStatus(message) { if (uploadStatus) { uploadStatus.textContent = message; } } function renderResult(payload) { if (!result || !resultList || !resultMeta || !openBox) { return; } latestLinks = [payload.boxUrl, payload.zipUrl].concat(payload.files.map((file) => file.url)); result.hidden = false; openBox.href = payload.boxUrl; resultMeta.textContent = `${payload.files.length} file${payload.files.length === 1 ? "" : "s"} ยท expires ${formatDate(payload.expiresAt)}`; resultList.replaceChildren(); payload.files.forEach((file) => { const row = document.createElement("div"); row.className = "result-item"; const body = document.createElement("span"); const name = document.createElement("strong"); name.textContent = file.name; const url = document.createElement("code"); url.textContent = file.url; body.append(name, url); const copy = document.createElement("button"); copy.className = "button button-outline"; copy.type = "button"; copy.textContent = "Copy"; copy.addEventListener("click", () => copyText(file.url, copy, "Copied")); row.append(body, copy); resultList.append(row); }); const zip = document.createElement("div"); zip.className = "result-item"; const zipBody = document.createElement("span"); const zipName = document.createElement("strong"); zipName.textContent = "Download all as zip"; const zipUrl = document.createElement("code"); zipUrl.textContent = payload.zipUrl; zipBody.append(zipName, zipUrl); const zipCopy = document.createElement("button"); zipCopy.className = "button button-outline"; zipCopy.type = "button"; zipCopy.textContent = "Copy"; zipCopy.addEventListener("click", () => copyText(payload.zipUrl, zipCopy, "Copied")); zip.append(zipBody, zipCopy); resultList.append(zip); } async function copyText(text, button, copiedLabel) { if (!text) { return; } await navigator.clipboard.writeText(text); const previous = button.textContent; button.textContent = copiedLabel; setTimeout(() => { button.textContent = previous; }, 1400); } function formatDate(value) { const date = new Date(value); if (Number.isNaN(date.getTime())) { return value; } return date.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric", }); } })();