2017-06-04 10:40:14 +08:00
import React , { Component } from 'react' ;
2017-10-23 20:41:09 +08:00
import _ from 'lodash' ;
2017-06-04 10:40:14 +08:00
import PropTypes from 'prop-types' ;
2017-10-12 22:49:50 +08:00
import cx from 'classnames' ;
2018-12-04 05:24:18 +08:00
import logger from '/imports/startup/client/logger' ;
2018-01-08 14:17:18 +08:00
import { styles } from '../audio-modal/styles' ;
2019-02-06 19:48:01 +08:00
import browser from 'browser-detect' ;
2016-12-09 02:17:17 +08:00
const propTypes = {
kind : PropTypes . oneOf ( [ 'audioinput' , 'audiooutput' , 'videoinput' ] ) ,
onChange : PropTypes . func . isRequired ,
2017-02-16 02:49:40 +08:00
value : PropTypes . string ,
2017-10-23 20:41:09 +08:00
className : PropTypes . string ,
2016-12-09 02:17:17 +08:00
} ;
const defaultProps = {
kind : 'audioinput' ,
2017-02-16 02:49:40 +08:00
value : undefined ,
2017-10-23 20:41:09 +08:00
className : null ,
2016-12-09 02:17:17 +08:00
} ;
class DeviceSelector extends Component {
constructor ( props ) {
super ( props ) ;
this . handleSelectChange = this . handleSelectChange . bind ( this ) ;
this . state = {
2017-02-16 02:49:40 +08:00
value : props . value ,
2016-12-09 02:17:17 +08:00
devices : [ ] ,
options : [ ] ,
} ;
}
componentDidMount ( ) {
2017-10-23 20:41:09 +08:00
const handleEnumerateDevicesSuccess = ( deviceInfos ) => {
const devices = deviceInfos . filter ( d => d . kind === this . props . kind ) ;
2019-02-02 03:12:06 +08:00
logger . info ( { logCode : 'audiodeviceselector_component_enumeratedevices_success' } , ` Success on enumerateDevices() for ${ this . props . kind } : ${ JSON . stringify ( devices ) } ` ) ;
2017-10-23 20:41:09 +08:00
this . setState ( {
devices ,
options : devices . map ( ( d , i ) => ( {
label : d . label || ` ${ this . props . kind } - ${ i } ` ,
value : d . deviceId ,
2017-11-01 01:34:06 +08:00
key : _ . uniqueId ( 'device-option-' ) ,
2017-10-23 20:41:09 +08:00
} ) ) ,
} ) ;
} ;
2016-12-09 02:17:17 +08:00
2017-10-23 20:41:09 +08:00
navigator . mediaDevices
. enumerateDevices ( )
2018-12-04 05:24:18 +08:00
. then ( handleEnumerateDevicesSuccess )
. catch ( ( err ) => {
2019-02-02 03:12:06 +08:00
logger . error ( { logCode : 'audiodeviceselector_component_enumeratedevices_error' } , ` Error on enumerateDevices(): ${ JSON . stringify ( err ) } ` ) ;
2018-12-04 05:24:18 +08:00
} ) ;
2016-12-09 02:17:17 +08:00
}
handleSelectChange ( event ) {
2018-12-04 05:24:18 +08:00
const { value } = event . target ;
2016-12-09 02:17:17 +08:00
const { onChange } = this . props ;
this . setState ( { value } , ( ) => {
const selectedDevice = this . state . devices . find ( d => d . deviceId === value ) ;
onChange ( selectedDevice . deviceId , selectedDevice , event ) ;
} ) ;
}
render ( ) {
2018-12-04 05:24:18 +08:00
const {
kind , className , ... props
} = this . props ;
2019-02-06 19:48:01 +08:00
2016-12-09 02:17:17 +08:00
const { options , value } = this . state ;
return (
< select
{ ... props }
value = { value }
2016-12-20 01:11:43 +08:00
onChange = { this . handleSelectChange }
2017-06-03 03:25:02 +08:00
disabled = { ! options . length }
2017-10-12 22:49:50 +08:00
className = { cx ( styles . select , className ) }
2017-06-03 03:25:02 +08:00
>
2016-12-20 01:11:43 +08:00
{
options . length ?
2017-10-23 20:41:09 +08:00
options . map ( option => (
2016-12-20 01:11:43 +08:00
< option
2017-11-01 01:34:06 +08:00
key = { option . key }
2017-06-03 03:25:02 +08:00
value = { option . value }
>
2016-12-20 01:11:43 +08:00
{ option . label }
< / option >
) ) :
2019-02-06 19:48:01 +08:00
(
( kind == 'audiooutput' && browser ( ) . name == 'safari' ) ?
< option value = "not-found" > Default < / option >
:
< option value = "not-found" > { ` no ${ kind } found ` } < / option >
)
2016-12-20 01:11:43 +08:00
}
2016-12-09 02:17:17 +08:00
< / select >
) ;
}
2017-06-03 03:25:02 +08:00
}
2016-12-09 02:17:17 +08:00
DeviceSelector . propTypes = propTypes ;
DeviceSelector . defaultProps = defaultProps ;
export default DeviceSelector ;