diff --git a/web/src/components/AvatarPicker.tsx b/web/src/components/AvatarPicker.tsx index 4f6711f6..61995439 100644 --- a/web/src/components/AvatarPicker.tsx +++ b/web/src/components/AvatarPicker.tsx @@ -4,6 +4,7 @@ import { showToasts, t } from 'tailchat-shared'; import { Avatar } from 'antd'; import { Icon } from '@iconify/react'; import { ModalAvatarCropper } from './modals/AvatarCropper'; +import { isGIF } from '@/utils/filetype-helper'; interface AvatarPickerProps { className?: string; @@ -16,10 +17,25 @@ interface AvatarPickerProps { */ export const AvatarPicker: React.FC = React.memo((props) => { const fileRef = useRef(null); - const [cropUrl, setCropUrl] = useState(props.imageUrl || ''); // 裁剪后并使用的url + const [avatarUrl, setAvatarUrl] = useState(props.imageUrl || ''); // 裁剪后并使用的url/或者未经裁剪的 gif url + + const updateAvatar = (imageBlobUrl: string) => { + setAvatarUrl(imageBlobUrl); + + if (typeof props.onChange === 'function') { + props.onChange(imageBlobUrl); + } + }; const handleSelectFile = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { + const pickedFile = e.target.files[0]; + + if (isGIF(pickedFile)) { + updateAvatar(URL.createObjectURL(pickedFile)); + return; + } + const reader = new FileReader(); reader.addEventListener('load', () => { if (reader.result) { @@ -28,11 +44,7 @@ export const AvatarPicker: React.FC = React.memo((props) => { imageUrl={reader.result.toString()} onConfirm={(croppedImageBlobUrl) => { closeModal(key); - setCropUrl(croppedImageBlobUrl); - - if (typeof props.onChange === 'function') { - props.onChange(croppedImageBlobUrl); - } + updateAvatar(croppedImageBlobUrl); }} />, { @@ -44,7 +56,7 @@ export const AvatarPicker: React.FC = React.memo((props) => { showToasts(t('文件读取失败'), 'error'); } }); - reader.readAsDataURL(e.target.files[0]); + reader.readAsDataURL(pickedFile); // 清理选中状态 e.target.files = null; @@ -71,7 +83,7 @@ export const AvatarPicker: React.FC = React.memo((props) => { } - src={cropUrl} + src={avatarUrl} /> )} diff --git a/web/src/utils/filetype-helper.ts b/web/src/utils/filetype-helper.ts new file mode 100644 index 00000000..b92643fe --- /dev/null +++ b/web/src/utils/filetype-helper.ts @@ -0,0 +1,8 @@ +/** + * Judge GIF File type by mime type + * @param file File object + * @returns if passed file object is a gif image. + */ +export const isGIF = (file: File): boolean => { + return file.type === 'image/gif'; +};