Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 23x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 234x 280x 280x 17x 17x 280x 2x 2x 2x 2x 280x | import React from "react";
import { promisifyEvent } from "~utils/promise";
export type Props = {
onClickRef?: React.RefObject<() => void>;
onFileUpdate?: (dataBlob: string) => void;
};
const convertFileToDataUrl = (file: File) => {
const reader = new FileReader();
return promisifyEvent<string>((listener, errorListener) => {
const localListener = () => listener(reader.result as string);
const localErrorListener = () =>
errorListener(new Error("Problem converting file to data url"));
reader.addEventListener("load", localListener, false);
reader.addEventListener("error", localErrorListener);
reader.readAsDataURL(file);
return () => {
reader.removeEventListener("load", localListener);
reader.removeEventListener("error", localErrorListener);
};
});
};
export const FileInput: React.FC<Props> = ({ onClickRef, onFileUpdate }) => {
const inputRef = React.useRef<HTMLInputElement>(null);
React.useEffect(() => {
Iif (!onClickRef) {
return;
}
onClickRef.current = () => inputRef.current?.click();
}, [onClickRef]);
const onChange = React.useCallback<
React.ChangeEventHandler<HTMLInputElement>
>(
(event) => {
Eif (event.target.files && event.target.files.length !== 0) {
// oxlint-disable-next-line typescript/no-non-null-assertion
const file = event.target.files[0]!;
void convertFileToDataUrl(file).then((dataUrl) =>
onFileUpdate?.(dataUrl),
);
}
},
[onFileUpdate],
);
return (
<input ref={inputRef} className="hidden" onChange={onChange} type="file" />
);
};
|