diff --git a/src/components/Circle.tsx b/src/components/Circle.tsx new file mode 100644 index 00000000..401f4924 --- /dev/null +++ b/src/components/Circle.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; + +import { stringToColor, isColorDark } from '../utils/stringToColor'; + +export 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; +`; diff --git a/src/components/Gravatar.tsx b/src/components/Gravatar.tsx index 814f0d06..a6aa37cb 100644 --- a/src/components/Gravatar.tsx +++ b/src/components/Gravatar.tsx @@ -1,9 +1,12 @@ -import React, { FC, useCallback, useEffect, useRef } from 'react'; +import React, { FC, useState } from 'react'; import md5Hash from 'md5'; import styled from 'styled-components'; import { isRetina } from '../utils/isRetina'; -import { useMounted } from '../hooks'; +import { preloadImage } from '../utils/preloadImage'; +import { getInitials } from '../utils/getInitials'; + +import { Circle } from './Circle'; interface GravatarProps extends React.HTMLAttributes { email?: string | null; @@ -13,8 +16,8 @@ interface GravatarProps extends React.HTMLAttributes { def?: string; className?: string; domain?: string; + name?: string | null; - onLoadError?: () => void; onClick?: () => void; } @@ -30,13 +33,11 @@ export const Gravatar: FC = ({ domain = process.env.NEXT_PUBLIC_GRAVATAR_HOST || 'www.gravatar.com', email, md5, - onLoadError, + name, ...props }) => { - const mounted = useMounted(); - const imgRef = useRef(null); - - const base = `//${domain}/avatar/`; + const [isError, setIsError] = useState(false); + const [isLoad, setIsLoad] = useState(false); const query = new URLSearchParams({ s: String(size), @@ -52,14 +53,6 @@ export const Gravatar: FC = ({ const formattedEmail = email?.trim().toLowerCase() || ''; - const onError: React.ReactEventHandler = useCallback( - ({ currentTarget }) => { - currentTarget.onerror = null; - onLoadError?.(); - }, - [onLoadError], - ); - let hash; if (md5) { hash = md5; @@ -71,14 +64,20 @@ export const Gravatar: FC = ({ return