Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

MicrophoneEntry.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // @flow
  2. import React, { Component } from 'react';
  3. import JitsiMeetJS from '../../../../base/lib-jitsi-meet/_';
  4. import AudioSettingsEntry, { type Props as AudioSettingsEntryProps } from './AudioSettingsEntry';
  5. import Meter from './Meter';
  6. const JitsiTrackEvents = JitsiMeetJS.events.track;
  7. type Props = AudioSettingsEntryProps & {
  8. /**
  9. * The deviceId of the microphone.
  10. */
  11. deviceId: string,
  12. /**
  13. * Flag indicating if there is a problem with the device.
  14. */
  15. hasError?: boolean,
  16. /**
  17. * Flag indicating if there is a problem with the device.
  18. */
  19. index?: number,
  20. /**
  21. * The audio track for the current entry.
  22. */
  23. jitsiTrack: Object,
  24. /**
  25. * The length of the microphone list
  26. */
  27. length: number,
  28. /**
  29. * Click handler for component.
  30. */
  31. onClick: Function,
  32. listHeaderId: string
  33. }
  34. type State = {
  35. /**
  36. * The audio level.
  37. */
  38. level: number
  39. }
  40. /**
  41. * React {@code Component} representing an entry for the microphone audio settings.
  42. *
  43. * @param {Props} props - The props of the component.
  44. * @returns { ReactElement}
  45. */
  46. export default class MicrophoneEntry extends Component<Props, State> {
  47. /**
  48. * Initializes a new {@code MicrophoneEntry} instance.
  49. *
  50. * @param {Object} props - The read-only properties with which the new
  51. * instance is to be initialized.
  52. */
  53. constructor(props: Props) {
  54. super(props);
  55. this.state = {
  56. level: -1
  57. };
  58. this._onClick = this._onClick.bind(this);
  59. this._onKeyPress = this._onKeyPress.bind(this);
  60. this._updateLevel = this._updateLevel.bind(this);
  61. }
  62. _onClick: () => void;
  63. /**
  64. * Click handler for the entry.
  65. *
  66. * @returns {void}
  67. */
  68. _onClick() {
  69. this.props.onClick(this.props.deviceId);
  70. }
  71. /**
  72. * Key pressed handler for the entry.
  73. *
  74. * @returns {void}
  75. */
  76. _onKeyPress: (KeyboardEvent) => void;
  77. /**
  78. * Key pressed handler for the entry.
  79. *
  80. * @param {Object} e - The event.
  81. * @private
  82. *
  83. * @returns {void}
  84. */
  85. _onKeyPress(e) {
  86. if (e.key === ' ') {
  87. e.preventDefault();
  88. this.props.onClick(this.props.deviceId);
  89. }
  90. }
  91. _updateLevel: (number) => void;
  92. /**
  93. * Updates the level of the meter.
  94. *
  95. * @param {number} num - The audio level provided by the jitsiTrack.
  96. * @returns {void}
  97. */
  98. _updateLevel(num) {
  99. this.setState({
  100. level: Math.floor(num / 0.125)
  101. });
  102. }
  103. /**
  104. * Subscribes to audio level changes coming from the jitsiTrack.
  105. *
  106. * @returns {void}
  107. */
  108. _startListening() {
  109. const { jitsiTrack } = this.props;
  110. jitsiTrack && jitsiTrack.on(
  111. JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
  112. this._updateLevel);
  113. }
  114. /**
  115. * Unsubscribes from changes coming from the jitsiTrack.
  116. *
  117. * @param {Object} jitsiTrack - The jitsiTrack to unsubscribe from.
  118. * @returns {void}
  119. */
  120. _stopListening(jitsiTrack) {
  121. jitsiTrack && jitsiTrack.off(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, this._updateLevel);
  122. this.setState({
  123. level: -1
  124. });
  125. }
  126. /**
  127. * Implements React's {@link Component#componentDidUpdate}.
  128. *
  129. * @inheritdoc
  130. */
  131. componentDidUpdate(prevProps: Props) {
  132. if (prevProps.jitsiTrack !== this.props.jitsiTrack) {
  133. this._stopListening(prevProps.jitsiTrack);
  134. this._startListening();
  135. }
  136. }
  137. /**
  138. * Implements React's {@link Component#componentDidMount}.
  139. *
  140. * @inheritdoc
  141. */
  142. componentDidMount() {
  143. this._startListening();
  144. }
  145. /**
  146. * Implements React's {@link Component#componentWillUnmount}.
  147. *
  148. * @inheritdoc
  149. */
  150. componentWillUnmount() {
  151. this._stopListening(this.props.jitsiTrack);
  152. }
  153. /**
  154. * Implements React's {@link Component#render}.
  155. *
  156. * @inheritdoc
  157. */
  158. render() {
  159. const { deviceId, children, hasError, index, isSelected, length, jitsiTrack, listHeaderId } = this.props;
  160. const deviceTextId: string = `choose_microphone${deviceId}`;
  161. const labelledby: string = `${listHeaderId} ${deviceTextId} `;
  162. return (
  163. <li
  164. aria-checked = { isSelected }
  165. aria-labelledby = { labelledby }
  166. aria-posinset = { index }
  167. aria-setsize = { length }
  168. className = 'audio-preview-microphone'
  169. onClick = { this._onClick }
  170. onKeyPress = { this._onKeyPress }
  171. role = 'radio'
  172. tabIndex = { 0 }>
  173. <AudioSettingsEntry
  174. hasError = { hasError }
  175. isSelected = { isSelected }
  176. labelId = { deviceTextId }>
  177. {children}
  178. </AudioSettingsEntry>
  179. { Boolean(jitsiTrack) && <Meter
  180. className = 'audio-preview-meter-mic'
  181. isDisabled = { hasError }
  182. level = { this.state.level } />
  183. }
  184. </li>
  185. );
  186. }
  187. }