import React , { Component } from 'react' ; import classnames from 'classnames' ; import debounce from '@ringcentral-integration/commons/lib/debounce' ; import dynamicsFont from '../../assets/DynamicsFont/DynamicsFont.scss' ; import CallAvatar from '../CallAvatar' ; import i18n from './i18n' ; import styles from './styles.scss' ; const MAXIMUM_AVATARS = 4 ; const WIDTH_PER_AVATAR = parseInt ( styles . conferenceAvatarSize , 0 ) ; const AVATAR_MERGIN_LEFT = parseInt ( styles . avatarMerginLeftSize , 0 ) ; const PEDDING_WIDTH = parseInt ( styles . avatarPaddingSize , 0 ) ; const minWidthCalculator = ( count ) => WIDTH_PER_AVATAR * count + AVATAR_MERGIN_LEFT * ( count - 1 ) + PEDDING_WIDTH * 2 + 1 + 2 ; const KINDS_OF_WIDTH_THAT_NEED_ADAPATER = [ { avartarCount : 0 , width : minWidthCalculator ( 1 ) } , { avartarCount : 1 , width : minWidthCalculator ( 3 ) } , { avartarCount : 2 , width : minWidthCalculator ( MAXIMUM_AVATARS ) } , { avartarCount : 3 , width : minWidthCalculator ( MAXIMUM_AVATARS + 1 ) } , ] ; type ConferenceInfoProps = { currentLocale : string ; partyProfiles ? : { avatarUrl ? : string ; partyName ? : string ; } [ ] ; onClick ? : ( ... args : any [ ] ) => any ; } ; type ConferenceInfoState = { avatarCount : any | number ; } ; class ConferenceInfo extends Component < ConferenceInfoProps , ConferenceInfoState > { constructor ( props ) { super ( props ) ; this . state = { avatarCount : MAXIMUM_AVATARS , } ; this . _container = React . createRef ( ) ; } _computeAvatarCountByWindowWidth ( props ) { const { partyProfiles } = props ; const avatarProfilesCount = ( partyProfiles && partyProfiles . length ) || 0 ; if ( ! this . _mounted ) { if ( avatarProfilesCount >= MAXIMUM_AVATARS ) { return MAXIMUM_AVATARS ; } return avatarProfilesCount ; } const width = this . _container && this . _container . current && this . _container . current . clientWidth ; let avatarCount = avatarProfilesCount ; const firstMatchWidth = KINDS_OF_WIDTH_THAT_NEED_ADAPATER . find ( ( it ) => width < it . width ) ; if ( firstMatchWidth ) { avatarCount = firstMatchWidth . avartarCount ; if ( avatarCount + 1 === avatarProfilesCount ) { avatarCount = avatarProfilesCount ; } } else if ( avatarCount >= MAXIMUM_AVATARS ) { avatarCount = MAXIMUM_AVATARS ; } return avatarCount ; } onWindowResize = debounce ( ( ) => { this . updateAvatarAmounts ( this . props ) ; } , 100 ) ; updateAvatarAmounts ( props ) { if ( ! this . _mounted ) { return ; } const avatarCount = this . _computeAvatarCountByWindowWidth ( props ) ; if ( avatarCount !== this . state . avatarCount ) { this . setState ( { avatarCount , } ) ; } } componentWillReceiveProps ( nextProps ) { this . updateAvatarAmounts ( nextProps ) ; } componentDidMount ( ) { this . _mounted = true ; window . addEventListener ( 'resize' , this . onWindowResize ) ; this . updateAvatarAmounts ( this . props ) ; } componentWillUnmount ( ) { this . _mounted = false ; window . removeEventListener ( 'resize' , this . onWindowResize ) ; } shouldComponentUpdate ( nextProps , nextState ) { const { partyProfiles } = nextProps ; const oldpartyProfiles = this . props . partyProfiles ; let showUpdate = true ; if ( partyProfiles !== oldpartyProfiles ) { if ( Array . isArray ( partyProfiles ) && Array . isArray ( oldpartyProfiles ) && partyProfiles . length === oldpartyProfiles . length ) { showUpdate = false ; for ( let i = 0 ; i < partyProfiles . length ; i += 1 ) { if ( partyProfiles [ i ] . id !== oldpartyProfiles [ i ] . id ) { showUpdate = true ; break ; } } } } else if ( nextState . avatarCount !== this . state . avatarCount ) { showUpdate = true ; } else { showUpdate = false ; } return showUpdate ; } computeDisplayedProfiles ( { profiles , avatarCount } ) { const displayedProfiles = profiles . length >= avatarCount ? profiles . slice ( 0 , avatarCount ) : profiles ; const remains = profiles . length - avatarCount ; return { displayedProfiles , remains , } ; } render ( ) { const { currentLocale , partyProfiles , onClick } = this . props ; const profiles = partyProfiles || [ ] ; const { avatarCount } = this . state ; const { displayedProfiles , remains } = this . computeDisplayedProfiles ( { profiles , avatarCount , } ) ; return ( < div className = { styles . conferenceCallInfoContainer } ref = { this . _container } > { displayedProfiles . length || ( avatarCount === 0 && remains > 0 ) ? ( < div className = { classnames ( styles . avatarContainer , styles . clickable ) } onClick = { ( e ) => { e . preventDefault ( ) ; onClick ( ) ; } } > { displayedProfiles . map ( ( { avatarUrl , partyName } , idx ) => ( < div key = { `${ partyName }_${ idx }` } className = { styles . avatar } > < CallAvatar avatarUrl = { avatarUrl } /> < /div>))} { remains > 0 ? ( < div className = { classnames ( styles . avatar , styles . remains ) } > { `+${ remains }` } < /div>) : null} < /div>) : (<div className={styles.avatarContainer}> < div className = { styles . avatar } style = { { backgroundColor : '#fff' } } > < i className = { classnames ( dynamicsFont . portrait , styles . icon ) } /> < /div> < /div>)} < p className = { styles . info } data - sign = "conferenceCall" > { i18n . getString ( 'conferenceCall' , currentLocale ) } < /p> < /div>); } } ConferenceInfo . defaultProps = { partyProfiles : null , onClick : ( i ) => i , } ; export default ConferenceInfo ;