import { isBase64DataUrl, loadImage } from '@ringcentral-integration/utils'; import clsx from 'clsx'; import type { FunctionComponent } from 'react'; import React, { useEffect, useRef, useState } from 'react'; import { v4 as uuidV4 } from 'uuid'; import SpinnerIcon from '../../assets/images/Spinner.svg'; import styles from './styles.scss'; export interface CallAvatarProps { isOnConferenceCall?: boolean; avatarUrl?: string; extraNum?: number; spinnerMode?: boolean; className?: string; onClick?: (...args: any[]) => any; } const initialSize = 38; const margin = 4; const avatarCircleRadius = 15; const extraNumCircleRadius = 8.5; const extraNumCircleBorder = 1; const circleBorder = 1; const $snow = '#fff'; const $blueLight = '#cee7f2'; const $blue = '#066FAC'; const $dark = '#e2e2e2'; const $transparency = '0.8'; const defaultAvatarStyle = { opacity: +$transparency }; const portraitChar = '\ue904'; // HACK:  is the font code for the portrait icon const iconFont = 'dynamics_icon'; // Hard coding this for firefox to load iconfont const avatarStyle = { stroke: $dark, strokeWidth: `${circleBorder}px` }; const spinnerScaleSize = 1.5; const spinnerSize = 12; const spinnerTranslateTo = (initialSize - spinnerSize * spinnerScaleSize) / 2; const aspectRatio = 'xMidYMid meet'; const xmlns = 'http://www.w3.org/2000/svg'; export const CallAvatar: FunctionComponent = ({ extraNum = 0, isOnConferenceCall, spinnerMode: showingSpinner, avatarUrl: avatarUrlProp, className, onClick, }) => { const [avatarUrl, setAvatarUrl] = useState(null); const svgCls = clsx( styles.callAvatar, onClick ? styles.autoPointerEvents : styles.disabledPointerEvents, className, ); const { current: hash } = useRef(uuidV4()); const textId = `text-${hash}`; const clipId = `circleClip-${hash}`; // spinner sizing const spinnerId = `spinner-${hash}`; const isOnConferenceCallWithExtraNum = isOnConferenceCall && extraNum > 0; const translateValue = spinnerTranslateTo - (isOnConferenceCallWithExtraNum ? margin : 0); const spinnerTransform = `translate(${translateValue}, ${spinnerTranslateTo}) scale(${spinnerScaleSize}, ${spinnerScaleSize})`; useEffect(() => { const loadImg = async () => { if (!avatarUrlProp) return; if (isBase64DataUrl(avatarUrlProp)) { setAvatarUrl(avatarUrlProp); return; } try { await loadImage(avatarUrlProp); setAvatarUrl(avatarUrlProp); } catch (error) { setAvatarUrl(null); } }; loadImg(); }, [avatarUrlProp]); if (isOnConferenceCallWithExtraNum) { return ( {portraitChar} {showingSpinner && ( )} {avatarUrl && ( )} {!avatarUrl && !showingSpinner && ( )} {`+${extraNum}`} ); } return ( {portraitChar} {showingSpinner && ( )} {showingSpinner && ( )} {avatarUrl && ( )} {!avatarUrl && !showingSpinner && ( )} ); }; export default CallAvatar;