Skip to content

Commit

Permalink
chore: add raised handling error
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisVorop committed Aug 16, 2023
1 parent cbcc0dd commit 7b29e8c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 56 deletions.
60 changes: 10 additions & 50 deletions src/components/Gravatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ import md5Hash from 'md5';
import styled from 'styled-components';

import { isRetina } from '../utils/isRetina';
import { isColorDark, stringToColor } from '../utils/stringToColor';

interface GravatarProps extends React.HTMLAttributes<HTMLImageElement> {
email?: string | null;
md5?: string;
size: number;
rating?: string;
name?: string | null;
def?: string;
className?: string;
domain?: string;

onLoadError?: () => void;
onClick?: () => void;
}

Expand All @@ -23,48 +22,18 @@ const StyledImage = styled.img`
border-radius: 100%;
`;

const Circle = styled.div<{ size: number; str: string }>`
border-radius: 100%;
${({ size, str }) => {
const mainColor = stringToColor(str);
return {
width: `${size}px`,
height: `${size}px`,
background: `linear-gradient(90deg,${mainColor},${stringToColor(str.toUpperCase())})`,
color: `${isColorDark(mainColor) ? 'white' : 'black'}`,
fontSize: `calc(${size / 2}px - 2px)`,
};
}};
display: flex;
align-items: center;
justify-content: center;
letter-spacing: -1.5px;
font-weight: 600;
user-select: none;
`;

const getInitials = (fullName?: string | null) => {
if (!fullName) return '';
const arr = fullName.split(' ');
return `${arr[0]?.[0] || ''} ${arr[1]?.[0] || ''}`;
};

export const Gravatar: FC<GravatarProps> = ({
size = 50,
rating = 'g',
def = 'retro',
domain = process.env.NEXT_PUBLIC_GRAVATAR_HOST || 'www.gravatar.com',
email,
md5,
name,
onLoadError,
...props
}) => {
const [modernBrowser, setModernBrowser] = useState(true);
const [mounted, setMounted] = useState(false);
const [isError, setIsError] = useState(false);
const imgRef = useRef<HTMLImageElement>(null);

useLayoutEffect(() => {
Expand All @@ -88,10 +57,13 @@ export const Gravatar: FC<GravatarProps> = ({

const formattedEmail = email?.trim().toLowerCase() || '';

const onLoadError: React.ReactEventHandler<HTMLImageElement> = useCallback(({ currentTarget }) => {
currentTarget.onerror = null;
setIsError(true);
}, []);
const onError: React.ReactEventHandler<HTMLImageElement> = useCallback(
({ currentTarget }) => {
currentTarget.onerror = null;
onLoadError?.();
},
[onLoadError],
);

let hash;
if (md5) {
Expand All @@ -113,17 +85,5 @@ export const Gravatar: FC<GravatarProps> = ({
}
}, [imgRef, mounted, modernBrowser, src, retinaSrc]);

const initials = getInitials(name);

return (
<>
{!isError ? (
<StyledImage ref={imgRef} height={size} width={size} onError={onLoadError} {...props} />
) : (
<Circle size={size} str={formattedEmail} {...props}>
{initials}
</Circle>
)}
</>
);
return <StyledImage ref={imgRef} height={size} width={size} onError={onError} {...props} />;
};
60 changes: 54 additions & 6 deletions src/components/UserPic.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import styled from 'styled-components';

import { stringToColor, isColorDark } from '../utils/stringToColor';

import { Gravatar } from './Gravatar';

interface UserPicProps extends React.HTMLAttributes<HTMLImageElement> {
Expand All @@ -18,16 +20,62 @@ const StyledImage = styled.img`
border-radius: 100%;
`;

export const UserPic: React.FC<UserPicProps> = ({ src, email, size = 32, ...props }) => {
const Circle = styled.div<{ size: number; str: string }>`
border-radius: 100%;
${({ size, str }) => {
const mainColor = stringToColor(str);
return {
width: `${size}px`,
height: `${size}px`,
background: `linear-gradient(90deg,${mainColor},${stringToColor(str.toUpperCase())})`,
color: `${isColorDark(mainColor) ? 'white' : 'black'}`,
fontSize: `calc(${size / 2}px - 2px)`,
};
}};
display: flex;
align-items: center;
justify-content: center;
letter-spacing: -1.5px;
font-weight: 600;
user-select: none;
`;

const getInitials = (fullName?: string | null) => {
if (!fullName) return '';
const arr = fullName.split(' ');
return `${arr[0]?.[0] || ''} ${arr[1]?.[0] || ''}`;
};

export const UserPic: React.FC<UserPicProps> = ({ src, name, email, size = 32, ...props }) => {
const [isError, setIsError] = useState(false);
const sizePx = `${size}px`;

const onLoadError: React.ReactEventHandler<HTMLImageElement> = useCallback(({ currentTarget }) => {
currentTarget.onerror = null;
const onLoadError = useCallback(() => {
setIsError(true);
}, []);

const onError: React.ReactEventHandler<HTMLImageElement> = useCallback(
({ currentTarget }) => {
currentTarget.onerror = null;
onLoadError();
},
[onLoadError],
);

if (isError) {
return (
<Circle size={size} str={`${email}`} {...props}>
{getInitials(name)}
</Circle>
);
}

if (src) {
return <StyledImage src={src} height={sizePx} width={sizePx} onError={onLoadError} {...props} />;
return <StyledImage src={src} height={sizePx} width={sizePx} onError={onError} {...props} />;
}

return <Gravatar email={email} size={size} {...props} />;
return <Gravatar onLoadError={onLoadError} email={email} size={size} {...props} />;
};

0 comments on commit 7b29e8c

Please sign in to comment.