2023-08-01 02:16:15 +00:00
|
|
|
// @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";
|
2023-08-11 19:42:32 +00:00
|
|
|
import routeFile from "./routeFile.js";
|
2023-08-01 02:16:15 +00:00
|
|
|
|
|
|
|
const accept = SUPPORTED_FILE_TYPES
|
|
|
|
.flatMap((t) => [t.mimeType, ...t.extensions])
|
|
|
|
.join(",");
|
|
|
|
const inputEl = /** @type {HTMLInputElement} */ (
|
|
|
|
crel("input", {
|
|
|
|
type: "file",
|
|
|
|
id: "file-input",
|
|
|
|
accept,
|
|
|
|
})
|
|
|
|
);
|
2023-08-02 18:39:57 +00:00
|
|
|
const inputContainerEl = crel("p", {}, inputEl);
|
2023-08-01 02:16:15 +00:00
|
|
|
|
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(", ");
|
|
|
|
}
|
|
|
|
})();
|
2023-08-01 02:16:15 +00:00
|
|
|
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);
|
2023-08-01 02:16:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-08-02 18:39:57 +00:00
|
|
|
appEl.append(labelParagraphEl, inputContainerEl, disclaimerParagraphEl);
|
2023-08-01 02:16:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
main();
|