import { Client } from "@atcute/client"; import { remove } from "@mary/exif-rm"; import { createSignal, onCleanup, Show } from "solid-js"; import { agent } from "../../auth/state"; import { Button } from "../button.jsx"; import { TextInput } from "../text-input.jsx"; import { editorInstance } from "./state"; export const FileUpload = (props: { file: File; blobInput: HTMLInputElement; onClose: () => void; }) => { const [uploading, setUploading] = createSignal(false); const [error, setError] = createSignal(""); onCleanup(() => (props.blobInput.value = "")); const formatFileSize = (bytes: number) => { if (bytes === 0) return "0 Bytes"; const k = 1024; const sizes = ["Bytes", "KB", "MB", "GB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + " " + sizes[i]; }; const uploadBlob = async () => { let blob: Blob; const mimetype = (document.getElementById("mimetype") as HTMLInputElement)?.value; (document.getElementById("mimetype") as HTMLInputElement).value = ""; if (mimetype) blob = new Blob([props.file], { type: mimetype }); else blob = props.file; if ((document.getElementById("exif-rm") as HTMLInputElement).checked) { const exifRemoved = remove(new Uint8Array(await blob.arrayBuffer())); if (exifRemoved !== null) blob = new Blob([exifRemoved], { type: blob.type }); } const rpc = new Client({ handler: agent()! }); setUploading(true); const res = await rpc.post("com.atproto.repo.uploadBlob", { input: blob, }); setUploading(false); if (!res.ok) { setError(res.data.error); return; } editorInstance.view.dispatch({ changes: { from: editorInstance.view.state.selection.main.head, insert: JSON.stringify(res.data.blob, null, 2), }, }); props.onClose(); }; return (

Upload blob

{props.file.name} ({formatFileSize(props.file.size)})

Metadata will be pasted after the cursor

Error: {error()}
Uploading
); };