import classNames from 'classnames/bind' ; import React , { useContext , useEffect , useState } from 'react' ; import { FormattedMessage , useIntl } from 'react-intl' ; import { useHistory } from 'react-router-dom' ; import ChimeSdkWrapper from '../chime/ChimeSdkWrapper' ; import routes from '../constants/routes.json' ; import getChimeContext from '../context/getChimeContext' ; import getUIStateContext from '../context/getUIStateContext' ; import ClassMode from '../enums/ClassMode' ; import ViewMode from '../enums/ViewMode' ; import styles from './Controls.css' ; import Tooltip from './Tooltip' ; import MessageTopic from '../enums/MessageTopic' ; const cx = classNames . bind ( styles ) ; enum VideoStatus { Disabled , Loading , Enabled } type Props = { viewMode : ViewMode ; onClickShareButton : ( ) => void ; } ; export default function Controls ( props ) { const { viewMode , onClickShareButton } = props ; const chime = useContext ( getChimeContext ( ) ) ; const [ state ] = useContext ( getUIStateContext ( ) ) ; const history = useHistory ( ) ; const [ muted , setMuted ] = useState ( false ) ; const [ focus , setFocus ] = useState ( false ) ; const [ videoStatus , setVideoStatus ] = useState ( VideoStatus . Disabled ) ; const intl = useIntl ( ) ; useEffect ( ( ) => { const callback = ( localMuted ) => { setMuted ( localMuted ) ; } ; chime ?. audioVideo ?. realtimeSubscribeToMuteAndUnmuteLocalAudio ( callback ) ; return ( ) => { if ( chime && chime ?. audioVideo ) { chime ?. audioVideo ?. realtimeUnsubscribeToMuteAndUnmuteLocalAudio ( callback ) ; } } ; } , [ ] ) ; return ( < div className = { cx ( 'controls' , { roomMode : viewMode === ViewMode . Room , screenShareMode : viewMode === ViewMode . ScreenShare , videoEnabled : videoStatus === VideoStatus . Enabled , audioMuted : muted } ) } > < div className = { cx ( 'micMuted' ) } > < FormattedMessage id = "Controls.micMutedInScreenViewMode" / > < /div> { state . classMode === ClassMode . Teacher && viewMode === ViewMode . Room && ( < Tooltip tooltip = { focus ? intl . formatMessage ( { id : 'Controls.turnOffFocusTooltip' } ) : intl . formatMessage ( { id : 'Controls.turnOnFocusTooltip' } ) } > < button type = "button" className = { cx ( 'focusButton' , { enabled : focus } ) } onClick = { ( ) => { const newFocusState = ! focus ; chime ?. sendMessage ( MessageTopic . Focus , { focus : newFocusState } ) ; chime ?. sendMessage ( MessageTopic . Chat , newFocusState ? intl . formatMessage ( { id : 'Controls.focusOnMessage' } ) : intl . formatMessage ( { id : 'Controls.focusOffMessage' } ) ) ; setFocus ( newFocusState ) ; } } > { focus ? ( < i className = "fas fa-street-view" / > ) : ( < i className = "fas fa-street-view" / > ) } < /button> < /Tooltip>)} < Tooltip tooltip = { muted ? intl . formatMessage ( { id : 'Controls.unmuteTooltip' } ) : intl . formatMessage ( { id : 'Controls.muteTooltip' } ) } > < button type = "button" className = { cx ( 'muteButton' , { enabled : ! muted } ) } onClick = { async ( ) => { if ( muted ) { chime ?. audioVideo ?. realtimeUnmuteLocalAudio ( ) ; } else { chime ?. audioVideo ?. realtimeMuteLocalAudio ( ) ; } await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ; } } > { muted ? ( < i className = "fas fa-microphone-slash" / > ) : ( < i className = "fas fa-microphone" / > ) } < /button> < /Tooltip> < Tooltip tooltip = { videoStatus === VideoStatus . Disabled ? intl . formatMessage ( { id : 'Controls.turnOnVideoTooltip' } ) : intl . formatMessage ( { id : 'Controls.turnOffVideoTooltip' } ) } > < button type = "button" className = { cx ( 'videoButton' , { enabled : videoStatus === VideoStatus . Enabled } ) } onClick = { async ( ) => { await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ; if ( videoStatus === VideoStatus . Disabled ) { setVideoStatus ( VideoStatus . Loading ) ; try { if ( ! chime ?. currentVideoInputDevice ) { throw new Error ( 'currentVideoInputDevice does not exist' ) ; } await chime ?. chooseVideoInputDevice ( chime ?. currentVideoInputDevice ) ; chime ?. audioVideo ?. startLocalVideoTile ( ) ; setVideoStatus ( VideoStatus . Enabled ) ; } catch ( error ) { console . error ( error ) ; setVideoStatus ( VideoStatus . Disabled ) ; } } else if ( videoStatus === VideoStatus . Enabled ) { setVideoStatus ( VideoStatus . Loading ) ; chime ?. audioVideo ?. stopLocalVideoTile ( ) ; setVideoStatus ( VideoStatus . Disabled ) ; } } } > { videoStatus === VideoStatus . Enabled ? ( < i className = "fas fa-video" / > ) : ( < i className = "fas fa-video-slash" / > ) } < /button> < /Tooltip> { state . classMode === ClassMode . Teacher && viewMode !== ViewMode . ScreenShare && ( < Tooltip tooltip = { intl . formatMessage ( { id : 'Controls.shareScreenTooltip' } ) } > < button type = "button" className = { cx ( 'shareButton' ) } onClick = { ( ) => { onClickShareButton ( ) ; } } > < i className = "fas fa-desktop" / > < /button> < /Tooltip>)} { viewMode !== ViewMode . ScreenShare && ( < Tooltip tooltip = { state . classMode === ClassMode . Teacher ? intl . formatMessage ( { id : 'Controls.endClassroomTooltip' } ) : intl . formatMessage ( { id : 'Controls.leaveClassroomTooltip' } ) } > < button type = "button" className = { cx ( 'endButton' ) } onClick = { ( ) => { chime ?. leaveRoom ( state . classMode === ClassMode . Teacher ) ; history . push ( routes . HOME ) ; } } > < i className = "fas fa-times" / > < /button> < /Tooltip>)} < /div>); }