diff --git a/src/components/Gravatar.tsx b/src/components/Gravatar.tsx index 7e123de4..d047b4c4 100644 --- a/src/components/Gravatar.tsx +++ b/src/components/Gravatar.tsx @@ -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; @@ -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', @@ -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(null); useLayoutEffect(() => { @@ -69,6 +84,7 @@ export const Gravatar = ({ const onLoadError: React.ReactEventHandler = useCallback(({ currentTarget }) => { currentTarget.onerror = null; currentTarget.src = '/anonymous.png'; + setIsError(true); }, []); let hash; @@ -93,17 +109,23 @@ export const Gravatar = ({ }, [imgRef, mounted, modernBrowser, src, retinaSrc]); return ( - + <> + {!isError ? ( + + ) : ( + + )} + ); }; diff --git a/src/utils/stringToColor.ts b/src/utils/stringToColor.ts new file mode 100644 index 00000000..3dae0778 --- /dev/null +++ b/src/utils/stringToColor.ts @@ -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; +};