UserPicture.jsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import React from 'react';
  2. import md5 from 'md5';
  3. import PropTypes from 'prop-types';
  4. import { userPageRoot } from '@commons/util/path-utils';
  5. import { UncontrolledTooltip } from 'reactstrap';
  6. const DEFAULT_IMAGE = '/images/icons/user.svg';
  7. // TODO UserComponent?
  8. export default class UserPicture extends React.Component {
  9. getUserPicture(user) {
  10. // gravatar
  11. if (user.isGravatarEnabled === true) {
  12. return this.generateGravatarSrc(user);
  13. }
  14. // uploaded image
  15. if (user.image != null) {
  16. return user.image;
  17. }
  18. if (user.imageAttachment != null) {
  19. return user.imageAttachment.filePathProxied;
  20. }
  21. return DEFAULT_IMAGE;
  22. }
  23. generateGravatarSrc(user) {
  24. const email = user.email || '';
  25. const hash = md5(email.trim().toLowerCase());
  26. return `https://gravatar.com/avatar/${hash}`;
  27. }
  28. getClassName() {
  29. const className = ['rounded-circle', 'picture'];
  30. // size
  31. if (this.props.size) {
  32. className.push(`picture-${this.props.size}`);
  33. }
  34. return className.join(' ');
  35. }
  36. renderForNull() {
  37. return (
  38. <img
  39. src={DEFAULT_IMAGE}
  40. alt="someone"
  41. className={this.getClassName()}
  42. />
  43. );
  44. }
  45. RootElmWithoutLink = (props) => {
  46. return <span {...props}>{props.children}</span>;
  47. }
  48. RootElmWithLink = (props) => {
  49. const { user } = this.props;
  50. const href = userPageRoot(user);
  51. return <a href={href} {...props}>{props.children}</a>;
  52. }
  53. withTooltip = (RootElm) => {
  54. const { user } = this.props;
  55. const id = `user-picture-${Math.random().toString(32).substring(2)}`;
  56. return props => (
  57. <>
  58. <RootElm id={id}>{props.children}</RootElm>
  59. <UncontrolledTooltip placement="bottom" target={id} delay={0} fade={false}>
  60. @{user.username}<br />
  61. {user.name}
  62. </UncontrolledTooltip>
  63. </>
  64. );
  65. }
  66. render() {
  67. const user = this.props.user;
  68. if (user == null) {
  69. return this.renderForNull();
  70. }
  71. const { noLink, noTooltip } = this.props;
  72. // determine RootElm
  73. let RootElm = noLink ? this.RootElmWithoutLink : this.RootElmWithLink;
  74. if (!noTooltip) {
  75. RootElm = this.withTooltip(RootElm);
  76. }
  77. return (
  78. <RootElm>
  79. <img
  80. src={this.getUserPicture(user)}
  81. alt={user.username}
  82. className={this.getClassName()}
  83. />
  84. </RootElm>
  85. );
  86. }
  87. }
  88. UserPicture.propTypes = {
  89. user: PropTypes.object,
  90. size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
  91. noLink: PropTypes.bool,
  92. noTooltip: PropTypes.bool,
  93. };
  94. UserPicture.defaultProps = {
  95. size: null,
  96. noLink: false,
  97. noTooltip: false,
  98. };