Sfoglia il codice sorgente

fix(settings): Always show mic audio levels

j8
Vlad Piersec 5 anni fa
parent
commit
99e7d636b7

+ 46
- 50
react/features/settings/components/web/audio/AudioSettingsContent.js Vedi File

@@ -4,7 +4,8 @@ import React, { Component } from 'react';
4 4
 
5 5
 import { translate } from '../../../../base/i18n';
6 6
 import { IconMicrophoneEmpty, IconVolumeEmpty } from '../../../../base/icons';
7
-import { createLocalAudioTrack } from '../../../functions';
7
+import { equals } from '../../../../base/redux';
8
+import { createLocalAudioTracks } from '../../../functions';
8 9
 
9 10
 import AudioSettingsHeader from './AudioSettingsHeader';
10 11
 import MicrophoneEntry from './MicrophoneEntry';
@@ -53,10 +54,10 @@ export type Props = {
53 54
 type State = {
54 55
 
55 56
    /**
56
-    * An object containing the jitsiTrack and the error (if the case)
57
-    * for the microphone that is in use.
57
+    * An list of objects, each containing the microphone label, audio track, device id
58
+    * and track error if the case.
58 59
     */
59
-    currentMicData: Object
60
+    audioTracks: Object[]
60 61
 }
61 62
 
62 63
 /**
@@ -81,10 +82,14 @@ class AudioSettingsContent extends Component<Props, State> {
81 82
         this._onSpeakerEntryClick = this._onSpeakerEntryClick.bind(this);
82 83
 
83 84
         this.state = {
84
-            currentMicData: {
85
-                error: false,
86
-                jitsiTrack: null
87
-            }
85
+            audioTracks: props.microphoneDevices.map(({ deviceId, label }) => {
86
+                return {
87
+                    deviceId,
88
+                    hasError: false,
89
+                    jitsiTrack: null,
90
+                    label
91
+                };
92
+            })
88 93
         };
89 94
     }
90 95
 
@@ -115,20 +120,13 @@ class AudioSettingsContent extends Component<Props, State> {
115 120
     /**
116 121
      * Renders a single microphone entry.
117 122
      *
118
-     * @param {Object} data - An object with the deviceId and label of the microphone.
123
+     * @param {Object} data - An object with the deviceId, jitsiTrack & label of the microphone.
119 124
      * @param {number} index - The index of the element, used for creating a key.
120 125
      * @returns {React$Node}
121 126
      */
122 127
     _renderMicrophoneEntry(data, index) {
123
-        const { deviceId, label } = data;
124
-        const key = `me-${index}`;
128
+        const { deviceId, label, jitsiTrack, hasError } = data;
125 129
         const isSelected = deviceId === this.props.currentMicDeviceId;
126
-        let jitsiTrack = null;
127
-        let hasError = false;
128
-
129
-        if (isSelected) {
130
-            ({ jitsiTrack, hasError } = this.state.currentMicData);
131
-        }
132 130
 
133 131
         return (
134 132
             <MicrophoneEntry
@@ -136,7 +134,7 @@ class AudioSettingsContent extends Component<Props, State> {
136 134
                 hasError = { hasError }
137 135
                 isSelected = { isSelected }
138 136
                 jitsiTrack = { jitsiTrack }
139
-                key = { key }
137
+                key = { `me-${index}` }
140 138
                 onClick = { this._onMicrophoneEntryClick }>
141 139
                 {label}
142 140
             </MicrophoneEntry>
@@ -166,50 +164,36 @@ class AudioSettingsContent extends Component<Props, State> {
166 164
     }
167 165
 
168 166
     /**
169
-     * Disposes the audio track for a given micData object.
170
-     *
171
-     * @param {Object} micData - The object holding the track.
172
-     * @returns {Promise<void>}
173
-     */
174
-    _disposeTrack(micData) {
175
-        const { jitsiTrack } = micData;
176
-
177
-        return jitsiTrack ? jitsiTrack.dispose() : Promise.resolve();
178
-    }
179
-
180
-    /**
181
-     * Updates the current microphone data.
182
-     * Disposes previously created track and creates a new one.
167
+     * Creates and updates the audio tracks.
183 168
      *
184 169
      * @returns {void}
185 170
      */
186
-    async _updateCurrentMicData() {
187
-        await this._disposeTrack(this.state.currentMicData);
171
+    async _setTracks() {
172
+        this._disposeTracks(this.state.audioTracks);
188 173
 
189
-        const currentMicData = await createLocalAudioTrack(
190
-            this.props.currentMicDeviceId,
174
+        const audioTracks = await createLocalAudioTracks(
175
+            this.props.microphoneDevices
191 176
         );
192 177
 
193
-        // In case the component gets unmounted before the track is created
194
-        // avoid a leak by not setting the state
195 178
         if (this._componentWasUnmounted) {
196
-            this._disposeTrack(currentMicData);
179
+            this._disposeTracks(audioTracks);
197 180
         } else {
198 181
             this.setState({
199
-                currentMicData
182
+                audioTracks
200 183
             });
201 184
         }
202 185
     }
203 186
 
204 187
     /**
205
-     * Implements React's {@link Component#componentDidUpdate}.
188
+     * Disposes the audio tracks.
206 189
      *
207
-     * @inheritdoc
190
+     * @param {Object} audioTracks - The object holding the audio tracks.
191
+     * @returns {void}
208 192
      */
209
-    componentDidUpdate(prevProps) {
210
-        if (prevProps.currentMicDeviceId !== this.props.currentMicDeviceId) {
211
-            this._updateCurrentMicData();
212
-        }
193
+    _disposeTracks(audioTracks) {
194
+        audioTracks.forEach(({ jitsiTrack }) => {
195
+            jitsiTrack && jitsiTrack.dispose();
196
+        });
213 197
     }
214 198
 
215 199
     /**
@@ -218,7 +202,7 @@ class AudioSettingsContent extends Component<Props, State> {
218 202
      * @inheritdoc
219 203
      */
220 204
     componentDidMount() {
221
-        this._updateCurrentMicData();
205
+        this._setTracks();
222 206
     }
223 207
 
224 208
     /**
@@ -228,16 +212,28 @@ class AudioSettingsContent extends Component<Props, State> {
228 212
      */
229 213
     componentWillUnmount() {
230 214
         this._componentWasUnmounted = true;
231
-        this._disposeTrack(this.state.currentMicData);
215
+        this._disposeTracks(this.state.audioTracks);
216
+    }
217
+
218
+    /**
219
+     * Implements React's {@link Component#componentDidUpdate}.
220
+     *
221
+     * @inheritdoc
222
+     */
223
+    componentDidUpdate(prevProps) {
224
+        if (!equals(this.props.microphoneDevices, prevProps.microphoneDevices)) {
225
+            this._setTracks();
226
+        }
232 227
     }
233 228
 
229
+
234 230
     /**
235 231
      * Implements React's {@link Component#render}.
236 232
      *
237 233
      * @inheritdoc
238 234
      */
239 235
     render() {
240
-        const { microphoneDevices, outputDevices, t } = this.props;
236
+        const { outputDevices, t } = this.props;
241 237
 
242 238
         return (
243 239
             <div>
@@ -245,7 +241,7 @@ class AudioSettingsContent extends Component<Props, State> {
245 241
                     <AudioSettingsHeader
246 242
                         IconComponent = { IconMicrophoneEmpty }
247 243
                         text = { t('settings.microphones') } />
248
-                    {microphoneDevices.map((data, i) =>
244
+                    {this.state.audioTracks.map((data, i) =>
249 245
                         this._renderMicrophoneEntry(data, i),
250 246
                     )}
251 247
                     <AudioSettingsHeader

+ 28
- 19
react/features/settings/functions.js Vedi File

@@ -176,27 +176,36 @@ export function createLocalVideoTracks(ids: string[]) {
176 176
 
177 177
 
178 178
 /**
179
- * Returns a promise which resolves with an object containing the corresponding
180
- * the audio jitsiTrack/error.
181
- *
182
- * @param {string} deviceId - The deviceId for the current microphone.
179
+ * Returns a promise which resolves with a list of objects containing
180
+ * the audio track and the corresponding audio device information.
183 181
  *
184
- * @returns {Promise<Object>}
182
+ * @param {Object[]} devices - A list of microphone devices.
183
+ * @returns {Promise<{
184
+ *   deviceId: string,
185
+ *   hasError: boolean,
186
+ *   jitsiTrack: Object,
187
+ *   label: string
188
+ * }[]>}
185 189
  */
186
-export function createLocalAudioTrack(deviceId: string) {
187
-    return createLocalTrack('audio', deviceId)
188
-                   .then(jitsiTrack => {
189
-                       return {
190
-                           hasError: false,
191
-                           jitsiTrack
192
-                       };
193
-                   })
194
-                   .catch(() => {
195
-                       return {
196
-                           hasError: true,
197
-                           jitsiTrack: null
198
-                       };
199
-                   });
190
+export function createLocalAudioTracks(devices: Object[]) {
191
+    return Promise.all(
192
+        devices.map(async ({ deviceId, label }) => {
193
+            let jitsiTrack = null;
194
+            let hasError = false;
195
+
196
+            try {
197
+                jitsiTrack = await createLocalTrack('audio', deviceId);
198
+            } catch (err) {
199
+                hasError = true;
200
+            }
201
+
202
+            return {
203
+                deviceId,
204
+                hasError,
205
+                jitsiTrack,
206
+                label
207
+            };
208
+        }));
200 209
 }
201 210
 
202 211
 /**

Loading…
Annulla
Salva