import React, { type JSX, useCallback, useState } from 'react'; import { isPopulated } from '@growi/core'; import { useTranslation } from 'next-i18next'; import ImageCropModal from '~/client/components/Common/ImageCropModal'; import { apiPost, apiPostForm } from '~/client/util/apiv1-client'; import { apiv3Put } from '~/client/util/apiv3-client'; import { toastError, toastSuccess } from '~/client/util/toastr'; import { useCurrentUser } from '~/states/global'; import { GRAVATAR_DEFAULT, generateGravatarSrc } from '~/utils/gravatar'; const DEFAULT_IMAGE = '/images/icons/user.svg'; const ProfileImageSettings = (): JSX.Element => { const { t } = useTranslation(); const currentUser = useCurrentUser(); const [isGravatarEnabled, setGravatarEnabled] = useState( currentUser?.isGravatarEnabled, ); const [uploadedPictureSrc, setUploadedPictureSrc] = useState(() => { if ( currentUser?.imageAttachment != null && isPopulated(currentUser.imageAttachment) ) { return currentUser.imageAttachment.filePathProxied ?? currentUser.image; } return currentUser?.image; }); const [showImageCropModal, setShowImageCropModal] = useState(false); const [imageCropSrc, setImageCropSrc] = useState( null, ); const selectFileHandler = useCallback( (e: React.ChangeEvent) => { if (e.target.files == null || e.target.files.length === 0) { return; } const reader = new FileReader(); reader.addEventListener('load', () => setImageCropSrc(reader.result)); reader.readAsDataURL(e.target.files[0]); setShowImageCropModal(true); }, [], ); const processImageCompletedHandler = useCallback( async (croppedImage) => { try { const formData = new FormData(); formData.append('file', croppedImage); const response = await apiPostForm( '/attachments.uploadProfileImage', formData, ); toastSuccess( t('toaster.update_successed', { target: t('Current Image'), ns: 'commons', }), ); setUploadedPictureSrc((response as any).attachment.filePathProxied); } catch (err) { toastError(err); } }, [t], ); const deleteImageHandler = useCallback(async () => { try { await apiPost('/attachments.removeProfileImage'); setUploadedPictureSrc(undefined); toastSuccess( t('toaster.update_successed', { target: t('Current Image'), ns: 'commons', }), ); } catch (err) { toastError(err); } }, [t]); const submit = useCallback(async () => { try { const response = await apiv3Put('/personal-setting/image-type', { isGravatarEnabled, }); const { userData } = response.data; setGravatarEnabled(userData.isGravatarEnabled); toastSuccess( t('toaster.update_successed', { target: t('Set Profile Image'), ns: 'commons', }), ); } catch (err) { toastError(err); } }, [isGravatarEnabled, t]); if (currentUser == null) { return <>; } return ( <>
setGravatarEnabled(true)} />
Gravatar
setGravatarEnabled(false)} />
{t('Current Image')}

{t('Current

{uploadedPictureSrc && ( )}
{t('Upload new image')}
setShowImageCropModal(false)} onImageProcessCompleted={processImageCompletedHandler} isCircular showCropOption />
); }; export default ProfileImageSettings;