Skip to content

Commit

Permalink
chore(Gravatar): autogenerated circles for users instead of images
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisVorop committed Aug 11, 2023
1 parent 49bb4dd commit fedfb5c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 11 deletions.
44 changes: 33 additions & 11 deletions src/components/Gravatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import md5Hash from 'md5';
import styled from 'styled-components';

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

interface GravatarProps {
email: string;
Expand Down Expand Up @@ -30,6 +31,19 @@ const StyledImage = styled.img<{ visible: boolean }>`
`}
`;

const Circle = styled.div<{ size: number; str: string }>`
border-radius: 100%;
${({ size, str }) => {
return {
width: `${size}px`,
height: `${size}px`,
background: `linear-gradient(90deg,${stringToColor(str.toLowerCase())},${stringToColor(
str.toUpperCase(),
)})`,
};
}};
`;

export const Gravatar = ({
size = 50,
rating = 'g',
Expand All @@ -43,6 +57,7 @@ export const Gravatar = ({
const [modernBrowser, setModernBrowser] = useState(true);
const [mounted, setMounted] = useState(false);
const [visible, setVisible] = useState(false);
const [isError, setIsError] = useState(false);
const imgRef = useRef<HTMLImageElement>(null);

useLayoutEffect(() => {
Expand All @@ -69,6 +84,7 @@ export const Gravatar = ({
const onLoadError: React.ReactEventHandler<HTMLImageElement> = useCallback(({ currentTarget }) => {
currentTarget.onerror = null;
currentTarget.src = '/anonymous.png';
setIsError(true);
}, []);

let hash;
Expand All @@ -93,17 +109,23 @@ export const Gravatar = ({
}, [imgRef, mounted, modernBrowser, src, retinaSrc]);

return (
<StyledImage
visible={visible}
ref={imgRef}
alt={`Gravatar for ${formattedEmail}`}
src="/anonymous.png"
height={size}
width={size}
className={className}
onClick={onClick}
onError={onLoadError}
/>
<>
{!isError ? (
<StyledImage
visible={visible}
ref={imgRef}
alt={`Gravatar for ${formattedEmail}`}
src="/anonymous.png"
height={size}
width={size}
className={className}
onClick={onClick}
onError={onLoadError}
/>
) : (
<Circle size={size} str={email} />
)}
</>
);
};

Expand Down
14 changes: 14 additions & 0 deletions src/utils/stringToColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable no-bitwise */

export const stringToColor = (str: string) => {
let hash = 0;
str.split('').forEach((char) => {
hash = char.charCodeAt(0) + ((hash << 5) - hash);
});
let color = '#';
for (let i = 0; i < 3; i++) {
const value = (hash >> (i * 8)) & 0xff;
color += value.toString(16).padStart(2, '0');
}
return color;
};

0 comments on commit fedfb5c

Please sign in to comment.