Browse Source

Groups devices notifications by type audio/video. (#4238)

* Groups devices notifications by type audio/video.

* Fixes passing correct device array.
master
Дамян Минков 6 years ago
parent
commit
a14fead0f3
No account linked to committer's email address
3 changed files with 76 additions and 49 deletions
  1. 12
    3
      conference.js
  2. 1
    2
      lang/main.json
  3. 63
    44
      react/features/base/devices/middleware.js

+ 12
- 3
conference.js View File

@@ -2402,17 +2402,26 @@ export default {
2402 2402
         // Let's handle unknown/non-preferred devices
2403 2403
         const newAvailDevices
2404 2404
             = APP.store.getState()['features/base/devices'].availableDevices;
2405
+        let newAudioDevices = [];
2406
+        let oldAudioDevices = [];
2405 2407
 
2406 2408
         if (typeof newDevices.audiooutput === 'undefined') {
2407
-            APP.store.dispatch(
2408
-                checkAndNotifyForNewDevice(newAvailDevices.audioOutput, oldDevices.audioOutput));
2409
+            newAudioDevices = newAvailDevices.audioOutput;
2410
+            oldAudioDevices = oldDevices.audioOutput;
2409 2411
         }
2410 2412
 
2411 2413
         if (!requestedInput.audio) {
2414
+            newAudioDevices = newAudioDevices.concat(newAvailDevices.audioInput);
2415
+            oldAudioDevices = oldAudioDevices.concat(oldDevices.audioInput);
2416
+        }
2417
+
2418
+        // check for audio
2419
+        if (newAudioDevices.length > 0) {
2412 2420
             APP.store.dispatch(
2413
-                checkAndNotifyForNewDevice(newAvailDevices.audioInput, oldDevices.audioInput));
2421
+                checkAndNotifyForNewDevice(newAudioDevices, oldAudioDevices));
2414 2422
         }
2415 2423
 
2424
+        // check for video
2416 2425
         if (!requestedInput.video) {
2417 2426
             APP.store.dispatch(
2418 2427
                 checkAndNotifyForNewDevice(newAvailDevices.videoInput, oldDevices.videoInput));

+ 1
- 2
lang/main.json View File

@@ -481,8 +481,7 @@
481 481
         "suboptimalExperienceDescription": "Eer... we are afraid your experience with __appName__ isn't going to be that great here. We are looking for ways to improve this but, until then, please try using one of the <a href='static/recommendedBrowsers.html' target='_blank'>fully supported browsers</a>.",
482 482
         "suboptimalExperienceTitle": "Browser Warning",
483 483
         "newDeviceCameraTitle": "New camera detected",
484
-        "newDeviceMicTitle": "New microphone detected",
485
-        "newDeviceCameraTitle": "New audio output detected",
484
+        "newDeviceAudioTitle": "New audio device detected",
486 485
         "newDeviceAction": "Use"
487 486
     },
488 487
     "passwordSetRemotely": "set by another member",

+ 63
- 44
react/features/base/devices/middleware.js View File

@@ -79,7 +79,9 @@ function _conferenceJoined({ dispatch, getState }, next, action) {
79 79
 
80 80
 /**
81 81
  * Finds a new device by comparing new and old array of devices and dispatches
82
- * notification with the new device.
82
+ * notification with the new device. For new devices with same groupId only one
83
+ * notification will be shown, this is so to avoid showing multiple notifications
84
+ * for audio input and audio output devices.
83 85
  *
84 86
  * @param {Store} store - The redux store in which the specified {@code action}
85 87
  * is being dispatched.
@@ -97,7 +99,25 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
97 99
         nDevice => !oldDevices.find(
98 100
             device => device.deviceId === nDevice.deviceId));
99 101
 
100
-    onlyNewDevices.forEach(newDevice => {
102
+    // we group devices by groupID which normally is the grouping by physical device
103
+    // plugging in headset we provide normally two device, one input and one output
104
+    // and we want to show only one notification for this physical audio device
105
+    const devicesGroupBy = onlyNewDevices.reduce((accumulated, value) => {
106
+        accumulated[value.groupId] = accumulated[value.groupId] || [];
107
+        accumulated[value.groupId].push(value);
108
+
109
+        return accumulated;
110
+    }, {});
111
+
112
+    Object.values(devicesGroupBy).forEach(devicesArray => {
113
+
114
+        if (devicesArray.length < 1) {
115
+            return;
116
+        }
117
+
118
+        // let's get the first device as a reference, we will use it for
119
+        // label and type
120
+        const newDevice = devicesArray[0];
101 121
 
102 122
         // we want to strip any device details that are not very
103 123
         // user friendly, like usb ids put in brackets at the end
@@ -115,12 +135,9 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
115 135
             titleKey = 'notify.newDeviceCameraTitle';
116 136
             break;
117 137
         }
118
-        case 'audioinput': {
119
-            titleKey = 'notify.newDeviceMicTitle';
120
-            break;
121
-        }
138
+        case 'audioinput' :
122 139
         case 'audiooutput': {
123
-            titleKey = 'notify.newDeviceCameraTitle';
140
+            titleKey = 'notify.newDeviceAudioTitle';
124 141
             break;
125 142
         }
126 143
         }
@@ -129,7 +146,7 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
129 146
             description,
130 147
             titleKey,
131 148
             customActionNameKey: 'notify.newDeviceAction',
132
-            customActionHandler: _useDevice.bind(undefined, store, newDevice)
149
+            customActionHandler: _useDevice.bind(undefined, store, devicesArray)
133 150
         }));
134 151
     });
135 152
 }
@@ -139,47 +156,49 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
139 156
  *
140 157
  * @param {Store} store - The redux store in which the specified {@code action}
141 158
  * is being dispatched.
142
- * @param {MediaDeviceInfo} device - The device to save.
159
+ * @param {Array<MediaDeviceInfo|InputDeviceInfo>} devices - The devices to save.
143 160
  * @returns {boolean} - Returns true in order notifications to be dismissed.
144 161
  * @private
145 162
  */
146
-function _useDevice({ dispatch }, device) {
147
-    switch (device.kind) {
148
-    case 'videoinput': {
149
-        dispatch(updateSettings({
150
-            userSelectedCameraDeviceId: device.deviceId,
151
-            userSelectedCameraDeviceLabel: device.label
152
-        }));
163
+function _useDevice({ dispatch }, devices) {
164
+    devices.forEach(device => {
165
+        switch (device.kind) {
166
+        case 'videoinput': {
167
+            dispatch(updateSettings({
168
+                userSelectedCameraDeviceId: device.deviceId,
169
+                userSelectedCameraDeviceLabel: device.label
170
+            }));
153 171
 
154
-        dispatch(setVideoInputDevice(device.deviceId));
155
-        break;
156
-    }
157
-    case 'audioinput': {
158
-        dispatch(updateSettings({
159
-            userSelectedMicDeviceId: device.deviceId,
160
-            userSelectedMicDeviceLabel: device.label
161
-        }));
172
+            dispatch(setVideoInputDevice(device.deviceId));
173
+            break;
174
+        }
175
+        case 'audioinput': {
176
+            dispatch(updateSettings({
177
+                userSelectedMicDeviceId: device.deviceId,
178
+                userSelectedMicDeviceLabel: device.label
179
+            }));
162 180
 
163
-        dispatch(setAudioInputDevice(device.deviceId));
164
-        break;
165
-    }
166
-    case 'audiooutput': {
167
-        setAudioOutputDeviceId(
168
-            device.deviceId,
169
-            dispatch,
170
-            true,
171
-            device.label)
172
-            .then(() => logger.log('changed audio output device'))
173
-            .catch(err => {
174
-                logger.warn(
175
-                    'Failed to change audio output device.',
176
-                    'Default or previously set audio output device will',
177
-                    ' be used instead.',
178
-                    err);
179
-            });
180
-        break;
181
-    }
182
-    }
181
+            dispatch(setAudioInputDevice(device.deviceId));
182
+            break;
183
+        }
184
+        case 'audiooutput': {
185
+            setAudioOutputDeviceId(
186
+                device.deviceId,
187
+                dispatch,
188
+                true,
189
+                device.label)
190
+                .then(() => logger.log('changed audio output device'))
191
+                .catch(err => {
192
+                    logger.warn(
193
+                        'Failed to change audio output device.',
194
+                        'Default or previously set audio output device will',
195
+                        ' be used instead.',
196
+                        err);
197
+                });
198
+            break;
199
+        }
200
+        }
201
+    });
183 202
 
184 203
     return true;
185 204
 }

Loading…
Cancel
Save