All files / app/components AuthorGravatarImage.tsx

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80                                        15x         3x 3x 1x           15x   15x       18x 18x 18x 18x         18x     18x       18x 18x                                         1x      
import React from 'react';
import md5 from 'md5';
import { AuthorPlaceholderImage } from 'app/components/AuthorPlaceholderImage';
import { style } from 'app/styles';
 
export interface AuthorGravatarImageProps {
  width?: number;
  height?: number;
  emails?: string[];
  style?: object | string;
}
 
interface AuthorGravatarImageState {
  emailsIndex: number;
}
 
export class AuthorGravatarImage extends React.Component<
  AuthorGravatarImageProps,
  AuthorGravatarImageState
> {
  readonly state: AuthorGravatarImageState = {
    emailsIndex: 0,
  };
 
  componentDidUpdate(newProps) {
    newProps.emails.forEach((email, index) => {
      if (email !== this.props.emails[index]) {
        this.setState({ emailsIndex: 0 });
      }
    });
  }
 
  constructor(props) {
    super(props);
 
    this.onImageNotFound = this.onImageNotFound.bind(this);
  }
 
  render() {
    const { width = 75, height = 75, emails } = this.props;
    const { emailsIndex } = this.state;
    const notFound = emailsIndex >= emails.length;
    const outerStyle = style(this.props.style, {
      width,
      height,
      display: 'inline-block',
    });
    const gravatarEmail = (emails[emailsIndex] || '')
      .toLocaleLowerCase()
      .replace(/\s/g, '');
    const gravatarUrl = `https://www.gravatar.com/avatar/${md5(
      gravatarEmail
    )}?s=${width}&d=404`;
 
    const imageStyle = style({ width, maxHeight: height });
    return (
      <div style={outerStyle}>
        {notFound ? (
          <AuthorPlaceholderImage
            holderForEmails={emails}
            width={width}
            height={height}
          />
        ) : (
          <img
            data-for={emails[emailsIndex]}
            style={imageStyle}
            src={gravatarUrl}
            onError={this.onImageNotFound}
          />
        )}
      </div>
    );
  }
 
  onImageNotFound() {
    this.setState({ emailsIndex: this.state.emailsIndex + 1 });
  }
}