jiti-meet/react/features/settings/components/web/audio/MicrophoneEntry.js

173 lines
4.0 KiB
JavaScript

// @flow
import React, { Component } from 'react';
import JitsiMeetJS from '../../../../base/lib-jitsi-meet/_';
import AudioSettingsEntry, { type Props as AudioSettingsEntryProps } from './AudioSettingsEntry';
import Meter from './Meter';
const JitsiTrackEvents = JitsiMeetJS.events.track;
type Props = AudioSettingsEntryProps & {
/**
* The deviceId of the microphone.
*/
deviceId: string,
/**
* Flag indicating if there is a problem with the device.
*/
hasError?: boolean,
/**
* The audio track for the current entry.
*/
jitsiTrack: Object,
/**
* Click handler for component.
*/
onClick: Function,
}
type State = {
/**
* The audio level.
*/
level: number,
}
/**
* React {@code Component} representing an entry for the microphone audio settings.
*
* @param {Props} props - The props of the component.
* @returns { ReactElement}
*/
export default class MicrophoneEntry extends Component<Props, State> {
/**
* Initializes a new {@code MicrophoneEntry} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this.state = {
level: -1
};
this._onClick = this._onClick.bind(this);
this._updateLevel = this._updateLevel.bind(this);
}
_onClick: () => void;
/**
* Click handler for the entry.
*
* @returns {void}
*/
_onClick() {
this.props.onClick(this.props.deviceId);
}
_updateLevel: (number) => void;
/**
* Updates the level of the meter.
*
* @param {number} num - The audio level provided by the jitsiTrack.
* @returns {void}
*/
_updateLevel(num) {
this.setState({
level: Math.floor(num / 0.125)
});
}
/**
* Subscribes to audio level changes coming from the jitsiTrack.
*
* @returns {void}
*/
_startListening() {
const { jitsiTrack } = this.props;
jitsiTrack && jitsiTrack.on(
JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
this._updateLevel);
}
/**
* Unsubscribes from changes coming from the jitsiTrack.
*
* @param {Object} jitsiTrack - The jitsiTrack to unsubscribe from.
* @returns {void}
*/
_stopListening(jitsiTrack) {
jitsiTrack && jitsiTrack.off(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, this._updateLevel);
this.setState({
level: -1
});
}
/**
* Implements React's {@link Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate(prevProps: Props) {
if (prevProps.jitsiTrack !== this.props.jitsiTrack) {
this._stopListening(prevProps.jitsiTrack);
this._startListening();
}
}
/**
* Implements React's {@link Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._startListening();
}
/**
* Implements React's {@link Component#componentWillUnmount}.
*
* @inheritdoc
*/
componentWillUnmount() {
this._stopListening(this.props.jitsiTrack);
}
/**
* Implements React's {@link Component#render}.
*
* @inheritdoc
*/
render() {
const { children, hasError, isSelected, jitsiTrack } = this.props;
return (
<div
className = 'audio-preview-microphone'
onClick = { this._onClick }>
<AudioSettingsEntry
hasError = { hasError }
isSelected = { isSelected }>
{children}
</AudioSettingsEntry>
{ Boolean(jitsiTrack) && <Meter
className = 'audio-preview-meter-mic'
isDisabled = { hasError }
level = { this.state.level } />
}
</div>
);
}
}