formats.exposed/public/index/index.js

94 lines
2.2 KiB
JavaScript
Raw Normal View History

// @ts-check
import { SUPPORTED_FILE_TYPES } from "./constants.js";
import crel from "../common/crel.js";
2023-08-01 14:20:57 +00:00
import * as base64url from "../common/base64url.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);
2023-08-11 19:58:53 +00:00
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."),
);
/**
* @param {Blob} blob
* @returns {Promise<string>}
*/
const formatBytes = async (blob) => {
const arrayBuffer = await blob.arrayBuffer();
const bytes = new Uint8Array(arrayBuffer);
2023-08-01 14:20:57 +00:00
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();