| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 | 
							- // @flow
 - 
 - import React, { PureComponent } from 'react';
 - 
 - import { IconShareDesktop } from '../../icons';
 - import { getParticipantById } from '../../participants';
 - import { connect } from '../../redux';
 - 
 - import { getAvatarColor, getInitials } from '../functions';
 - 
 - import { StatelessAvatar } from '.';
 - 
 - export type Props = {
 - 
 -     /**
 -      * The string we base the initials on (this is generated from a list of precendences).
 -      */
 -     _initialsBase: ?string,
 - 
 -     /**
 -      * An URL that we validated that it can be loaded.
 -      */
 -     _loadableAvatarUrl: ?string,
 - 
 -     /**
 -      * A prop to maintain compatibility with web.
 -      */
 -     className?: string,
 - 
 -     /**
 -      * A string to override the initials to generate a color of. This is handy if you don't want to make
 -      * the background color match the string that the initials are generated from.
 -      */
 -     colorBase?: string,
 - 
 -     /**
 -      * Display name of the entity to render an avatar for (if any). This is handy when we need
 -      * an avatar for a non-participasnt entity (e.g. a recent list item).
 -      */
 -     displayName?: string,
 - 
 -     /**
 -      * ID of the element, if any.
 -      */
 -     id?: string,
 - 
 -     /**
 -      * The ID of the participant to render an avatar for (if it's a participant avatar).
 -      */
 -     participantId?: string,
 - 
 -     /**
 -      * The size of the avatar.
 -      */
 -     size: number,
 - 
 -     /**
 -      * One of the expected status strings (e.g. 'available') to render a badge on the avatar, if necessary.
 -      */
 -     status?: ?string,
 - 
 -     /**
 -      * URL of the avatar, if any.
 -      */
 -     url: ?string,
 - }
 - 
 - type State = {
 -     avatarFailed: boolean
 - }
 - 
 - export const DEFAULT_SIZE = 65;
 - 
 - /**
 -  * Implements a class to render avatars in the app.
 -  */
 - class Avatar<P: Props> extends PureComponent<P, State> {
 -     /**
 -      * Instantiates a new {@code Component}.
 -      *
 -      * @inheritdoc
 -      */
 -     constructor(props: P) {
 -         super(props);
 - 
 -         this.state = {
 -             avatarFailed: false
 -         };
 - 
 -         this._onAvatarLoadError = this._onAvatarLoadError.bind(this);
 -     }
 - 
 -     /**
 -      * Implements {@code Component#componentDidUpdate}.
 -      *
 -      * @inheritdoc
 -      */
 -     componentDidUpdate(prevProps: P) {
 -         if (prevProps.url !== this.props.url) {
 - 
 -             // URI changed, so we need to try to fetch it again.
 -             // Eslint doesn't like this statement, but based on the React doc, it's safe if it's
 -             // wrapped in a condition: https://reactjs.org/docs/react-component.html#componentdidupdate
 - 
 -             // eslint-disable-next-line react/no-did-update-set-state
 -             this.setState({
 -                 avatarFailed: false
 -             });
 -         }
 -     }
 - 
 -     /**
 -      * Implements {@code Componenr#render}.
 -      *
 -      * @inheritdoc
 -      */
 -     render() {
 -         const {
 -             _initialsBase,
 -             _loadableAvatarUrl,
 -             className,
 -             colorBase,
 -             id,
 -             size,
 -             status,
 -             url
 -         } = this.props;
 -         const { avatarFailed } = this.state;
 - 
 -         const avatarProps = {
 -             className,
 -             color: undefined,
 -             id,
 -             initials: undefined,
 -             onAvatarLoadError: undefined,
 -             size,
 -             status,
 -             url: undefined
 -         };
 - 
 -         // _loadableAvatarUrl is validated that it can be loaded, but uri (if present) is not, so
 -         // we still need to do a check for that. And an explicitly provided URI is higher priority than
 -         // an avatar URL anyhow.
 -         const effectiveURL = (!avatarFailed && url) || _loadableAvatarUrl;
 - 
 -         if (effectiveURL) {
 -             avatarProps.onAvatarLoadError = this._onAvatarLoadError;
 -             avatarProps.url = effectiveURL;
 -         }
 - 
 -         const initials = getInitials(_initialsBase);
 - 
 -         if (initials) {
 -             avatarProps.color = getAvatarColor(colorBase || _initialsBase);
 -             avatarProps.initials = initials;
 -         }
 - 
 -         return (
 -             <StatelessAvatar
 -                 { ...avatarProps } />
 -         );
 -     }
 - 
 -     _onAvatarLoadError: () => void;
 - 
 -     /**
 -      * Callback to handle the error while loading of the avatar URI.
 -      *
 -      * @returns {void}
 -      */
 -     _onAvatarLoadError() {
 -         this.setState({
 -             avatarFailed: true
 -         });
 -     }
 - }
 - 
 - /**
 -  * Maps part of the Redux state to the props of this component.
 -  *
 -  * @param {Object} state - The Redux state.
 -  * @param {Props} ownProps - The own props of the component.
 -  * @returns {Props}
 -  */
 - export function _mapStateToProps(state: Object, ownProps: Props) {
 -     const { colorBase, displayName, participantId } = ownProps;
 -     const _participant: ?Object = participantId && getParticipantById(state, participantId);
 -     const _initialsBase = _participant?.name ?? displayName;
 -     const screenShares = state['features/video-layout'].screenShares || [];
 - 
 -     let _loadableAvatarUrl = _participant?.loadableAvatarUrl;
 - 
 -     if (participantId && screenShares.includes(participantId)) {
 -         _loadableAvatarUrl = IconShareDesktop;
 -     }
 - 
 -     return {
 -         _initialsBase,
 -         _loadableAvatarUrl,
 -         colorBase: !colorBase && _participant ? _participant.id : colorBase
 -     };
 - }
 - 
 - export default connect(_mapStateToProps)(Avatar);
 
 
  |