gravatar.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {Component} from 'react';
  2. import styled from '@emotion/styled';
  3. import * as qs from 'query-string';
  4. import ConfigStore from 'sentry/stores/configStore';
  5. import {callIfFunction} from 'sentry/utils/callIfFunction';
  6. import {imageStyle, ImageStyleProps} from './styles';
  7. type Props = {
  8. remoteSize: number;
  9. gravatarId?: string;
  10. onError?: () => void;
  11. onLoad?: () => void;
  12. placeholder?: string;
  13. } & ImageStyleProps;
  14. type State = {
  15. MD5?: any;
  16. };
  17. class Gravatar extends Component<Props, State> {
  18. state: State = {
  19. MD5: undefined,
  20. };
  21. componentDidMount() {
  22. this._isMounted = true;
  23. import('crypto-js/md5')
  24. .then(mod => mod.default)
  25. .then(MD5 => {
  26. if (!this._isMounted) {
  27. return;
  28. }
  29. this.setState({MD5});
  30. });
  31. }
  32. componentWillUnmount() {
  33. // Need to track mounted state because `React.isMounted()` is deprecated and because of
  34. // dynamic imports
  35. this._isMounted = false;
  36. }
  37. private _isMounted: boolean = false;
  38. buildGravatarUrl = () => {
  39. const {gravatarId, remoteSize, placeholder} = this.props;
  40. let url = ConfigStore.getConfig().gravatarBaseUrl + '/avatar/';
  41. const md5 = callIfFunction(this.state.MD5, gravatarId);
  42. if (md5) {
  43. url += md5;
  44. }
  45. const query = {
  46. s: remoteSize || undefined,
  47. // If gravatar is not found we need the request to return an error,
  48. // otherwise error handler will not trigger and avatar will not have a display a LetterAvatar backup.
  49. d: placeholder || '404',
  50. };
  51. url += '?' + qs.stringify(query);
  52. return url;
  53. };
  54. render() {
  55. if (!this.state.MD5) {
  56. return null;
  57. }
  58. const {round, onError, onLoad, suggested, grayscale} = this.props;
  59. return (
  60. <Image
  61. round={round}
  62. src={this.buildGravatarUrl()}
  63. onLoad={onLoad}
  64. onError={onError}
  65. suggested={suggested}
  66. grayscale={grayscale}
  67. />
  68. );
  69. }
  70. }
  71. export default Gravatar;
  72. const Image = styled('img')<ImageStyleProps>`
  73. ${imageStyle};
  74. `;