1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import {useCallback, useEffect, useRef, useState} from 'react';
- import styled from '@emotion/styled';
- import * as qs from 'query-string';
- import ConfigStore from 'sentry/stores/configStore';
- import {imageStyle, ImageStyleProps} from './styles';
- type Props = {
- remoteSize: number;
- gravatarId?: string;
- onError?: () => void;
- onLoad?: () => void;
- placeholder?: string;
- } & ImageStyleProps;
- type HasherHelper = typeof import('crypto-js/md5');
- function Gravatar({
- remoteSize,
- gravatarId,
- placeholder,
- round,
- onError,
- onLoad,
- suggested,
- }: Props) {
- const isMounted = useRef(false);
- const [MD5, setMD5] = useState<HasherHelper>();
- const loadMd5Helper = useCallback(async () => {
- const mod = await import('crypto-js/md5');
- if (isMounted.current) {
- // XXX: Use function invocation of `useState`s setter since the mod.default
- // is a function itself.
- setMD5(() => mod.default);
- }
- }, []);
- useEffect(() => {
- isMounted.current = true;
- loadMd5Helper();
- return () => {
- isMounted.current = false;
- };
- }, [loadMd5Helper]);
- if (MD5 === undefined) {
- return null;
- }
- const query = qs.stringify({
- s: remoteSize,
- // If gravatar is not found we need the request to return an error,
- // otherwise error handler will not trigger and avatar will not have a display a LetterAvatar backup.
- d: placeholder ?? '404',
- });
- const gravatarBaseUrl = ConfigStore.get('gravatarBaseUrl');
- const md5 = MD5(gravatarId ?? '');
- const url = `${gravatarBaseUrl}/avatar/${md5}?${query}`;
- return (
- <Image
- round={round}
- src={url}
- onLoad={onLoad}
- onError={onError}
- suggested={suggested}
- />
- );
- }
- export default Gravatar;
- const Image = styled('img')<ImageStyleProps>`
- ${imageStyle};
- `;
|