// @ts-check import { SUPPORTED_FILE_TYPES } from "./constants.js"; import crel from "../common/crel.js"; import * as base64url from "../common/base64url.js"; import { routeFile } from "./fileRouter.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 = 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."), ); /** * @param {Blob} blob * @returns {Promise} */ const formatBytes = async (blob) => { const arrayBuffer = await blob.arrayBuffer(); const bytes = new Uint8Array(arrayBuffer); return base64url.stringify(bytes); }; 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; } location.href = route + "#" + JSON.stringify({ name: file.name, bytes: await formatBytes(file), }); }); appEl.append(labelParagraphEl, inputContainerEl, disclaimerParagraphEl); }; main();