// @ts-check import * as base64 from "../common/vendor/base64-js.js"; import { SUPPORTED_FILE_TYPES } from "./constants.js"; import crel from "../common/crel.js"; import routeFile from "./routeFile.js"; const accept = SUPPORTED_FILE_TYPES .flatMap((t) => [t.mimeType, ...t.extensions]) .join(","); const inputEl = /** @type {HTMLInputElement} */ ( crel("input", { type: "file", id: "file-input", accept, }) ); const inputContainerEl = crel("p", {}, inputEl); const supportedFileTypeNameString = (() => { switch (SUPPORTED_FILE_TYPES.length) { case 0: return "no"; case 2: return `${SUPPORTED_FILE_TYPES[0].name} and ${ SUPPORTED_FILE_TYPES[1].name }`; default: return SUPPORTED_FILE_TYPES .map((t, index, array) => ( (array.length > 1 && (index === array.length - 1)) ? `and ${t.name}` : t.name )) .join(", "); } })(); const labelParagraphEl = crel( "p", {}, crel( "label", { "for": "file-input" }, `Upload something! Supports ${supportedFileTypeNameString} files, with more on the way.`, ), ); const disclaimerParagraphEl = crel( "p", {}, crel("small", {}, "Your files do not leave your computer."), ); const main = () => { const appEl = document.getElementById("app"); if (!appEl) throw new Error("HTML is not set up correctly"); inputEl.addEventListener("change", async () => { const file = inputEl.files?.[0]; if (!file) return; // TODO: Prevent large files. const route = await routeFile(file); if (!route) { console.warn( "Uploaded a file that was accepted but not routed. This may indicate a bug.", ); // TODO: Show something better than this. alert("Unsupported file type."); return; } const fileData = new Uint8Array(await file.arrayBuffer()); window.sessionStorage.setItem("fileData", base64.fromByteArray(fileData)); location.href = route; }); appEl.append(labelParagraphEl, inputContainerEl, disclaimerParagraphEl); }; main();