import { Box, Button, Center, FormControl, FormErrorMessage, Image, Input, Spinner, useToast, } from '@metafam/ds'; import { Maybe, Optional } from '@metafam/utils'; import { forwardRef, useCallback, useState } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import PlayerProfileIcon from '#assets/player-profile-icon.svg'; import { FileReaderData, useImageReader } from '#lib/hooks/useImageReader'; import { optimizedImage } from '#utils/imageHelpers'; export type EditAvatarImageProps = { initialURL?: Maybe; onFilePicked: ({ file, dataURL }: FileReaderData) => void; }; export const EditAvatarImage = forwardRef< HTMLImageElement, EditAvatarImageProps >(({ initialURL, onFilePicked }, ref) => { const toast = useToast(); const readFile = useImageReader(); const [active, setActive] = useState(false); const [loading, setLoading] = useState(true); const [url, setURL] = useState>( optimizedImage('profileImageURL', initialURL), ); const { control, formState: { errors }, } = useFormContext(); const onFileChange = useCallback( async ({ target: input }: { target: HTMLInputElement }) => { const file = input.files?.[0]; if (!file) return; if (file.size === 0) { toast({ title: 'Empty Image Error', description: 'The selected image has a size of 0. Is it a symbolic link?', status: 'error', isClosable: true, duration: 10000, }); } else { setLoading(true); try { const dataURL = await readFile(file); setURL(dataURL); onFilePicked({ file, dataURL }); } finally { setLoading(false); } } }, [onFilePicked, readFile, toast], ); return (
{ setLoading(false); }} display={loading ? 'none' : 'inherit'} src={url} borderRadius="full" objectFit="cover" h="full" w="full" border="2px solid" borderColor={active && url ? 'blue.400' : 'transparent'} />
{loading && (url == null ? ( ) : ( ))}
( <> )} />
{errors.profileImageURL?.message?.toString()}
); });