feat(setting): 由于 gif 使用 canvas 裁剪后无法保留动图格式,对 gif 格式的头像文件跳过裁剪处理。

没有添加确认的步骤。个人感觉从用户体验上来说,直接设置成功会更好一些。

issue #7
pull/13/head
shikelong 4 years ago
parent 4eeedd338f
commit abb3d939e9

@ -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<AvatarPickerProps> = React.memo((props) => {
const fileRef = useRef<HTMLInputElement>(null);
const [cropUrl, setCropUrl] = useState<string>(props.imageUrl || ''); // 裁剪后并使用的url
const [avatarUrl, setAvatarUrl] = useState<string>(props.imageUrl || ''); // 裁剪后并使用的url/或者未经裁剪的 gif url
const updateAvatar = (imageBlobUrl: string) => {
setAvatarUrl(imageBlobUrl);
if (typeof props.onChange === 'function') {
props.onChange(imageBlobUrl);
}
};
const handleSelectFile = (e: React.ChangeEvent<HTMLInputElement>) => {
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<AvatarPickerProps> = 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<AvatarPickerProps> = 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<AvatarPickerProps> = React.memo((props) => {
<Avatar
size={64}
icon={<Icon className="anticon" icon="mdi:account" />}
src={cropUrl}
src={avatarUrl}
/>
)}
</div>

@ -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';
};
Loading…
Cancel
Save