Merge pull request #13 from shikelong/master

解决了 issue #7,头像裁剪的时候跳过 gif 格式  / 另外修复了存在多个 Modal 时候的堆叠问题
pull/14/head
moonrailgun 4 years ago committed by GitHub
commit 6370737e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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/file-helper';
interface AvatarPickerProps {
className?: string;
@ -16,35 +17,45 @@ 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 reader = new FileReader();
reader.addEventListener('load', () => {
if (reader.result) {
const key = openModal(
<ModalAvatarCropper
imageUrl={reader.result.toString()}
onConfirm={(croppedImageBlobUrl) => {
closeModal(key);
setCropUrl(croppedImageBlobUrl);
const pickedFile = e.target.files[0];
if (typeof props.onChange === 'function') {
props.onChange(croppedImageBlobUrl);
}
}}
/>,
{
maskClosable: false,
closable: true,
}
);
} else {
showToasts(t('文件读取失败'), 'error');
}
});
reader.readAsDataURL(e.target.files[0]);
if (isGIF(pickedFile)) {
updateAvatar(URL.createObjectURL(pickedFile));
} else {
const reader = new FileReader();
reader.addEventListener('load', () => {
if (reader.result) {
const key = openModal(
<ModalAvatarCropper
imageUrl={reader.result.toString()}
onConfirm={(croppedImageBlobUrl) => {
closeModal(key);
updateAvatar(croppedImageBlobUrl);
}}
/>,
{
maskClosable: false,
closable: true,
}
);
} else {
showToasts(t('文件读取失败'), 'error');
}
});
reader.readAsDataURL(pickedFile);
}
// 清理选中状态
e.target.files = null;
@ -71,7 +82,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>

@ -88,7 +88,7 @@ export const Modal: React.FC<ModalProps> = React.memo((props) => {
<ModalContext.Provider value={{ closeModal }}>
{/* Inner */}
<div
className="modal-inner bg-content-light dark:bg-content-dark rounded overflow-auto relative"
className="modal-inner bg-content-light dark:bg-content-dark rounded overflow-auto relative z-10"
style={{ maxHeight: '80vh', maxWidth: '80vw' }}
onClick={stopPropagation}
>

@ -114,3 +114,12 @@ export async function openFile(
fileEl.click();
});
}
/**
* 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