Pārlūkot izejas kodu

feat(api): notify api of mic and camera errors (#4289)

- Use actions to notify the rest of the app that
  a mic or camera error has occurred
- Use middleware to respond to those notifications
  of errors by showing in-app notifications and
  notifying the external api
master
virtuacoplenny 6 gadus atpakaļ
vecāks
revīzija
251da1861a
Revīzijas autora e-pasta adrese nav piesaistīta nevienam kontam

+ 10
- 7
conference.js Parādīt failu

@@ -51,6 +51,8 @@ import {
51 51
 import {
52 52
     checkAndNotifyForNewDevice,
53 53
     getAvailableDevices,
54
+    notifyCameraError,
55
+    notifyMicError,
54 56
     setAudioOutputDeviceId,
55 57
     updateDeviceList
56 58
 } from './react/features/base/devices';
@@ -694,13 +696,14 @@ export default {
694 696
                         // If both requests for 'audio' + 'video' and 'audio'
695 697
                         // only failed, we assume that there are some problems
696 698
                         // with user's microphone and show corresponding dialog.
697
-                        APP.UI.showMicErrorNotification(audioOnlyError);
698
-                        APP.UI.showCameraErrorNotification(videoOnlyError);
699
+                        APP.store.dispatch(notifyMicError(audioOnlyError));
700
+                        APP.store.dispatch(notifyCameraError(videoOnlyError));
699 701
                     } else {
700 702
                         // If request for 'audio' + 'video' failed, but request
701 703
                         // for 'audio' only was OK, we assume that we had
702 704
                         // problems with camera and show corresponding dialog.
703
-                        APP.UI.showCameraErrorNotification(audioAndVideoError);
705
+                        APP.store.dispatch(
706
+                            notifyCameraError(audioAndVideoError));
704 707
                     }
705 708
                 }
706 709
 
@@ -839,7 +842,7 @@ export default {
839 842
 
840 843
         if (!this.localAudio && !mute) {
841 844
             const maybeShowErrorDialog = error => {
842
-                showUI && APP.UI.showMicErrorNotification(error);
845
+                showUI && APP.store.dispatch(notifyMicError(error));
843 846
             };
844 847
 
845 848
             createLocalTracksF({ devices: [ 'audio' ] }, false)
@@ -902,7 +905,7 @@ export default {
902 905
 
903 906
         if (!this.localVideo && !mute) {
904 907
             const maybeShowErrorDialog = error => {
905
-                showUI && APP.UI.showCameraErrorNotification(error);
908
+                showUI && APP.store.dispatch(notifyCameraError(error));
906 909
             };
907 910
 
908 911
             // Try to create local video if there wasn't any.
@@ -2109,7 +2112,7 @@ export default {
2109 2112
                     this._updateVideoDeviceId();
2110 2113
                 })
2111 2114
                 .catch(err => {
2112
-                    APP.UI.showCameraErrorNotification(err);
2115
+                    APP.store.dispatch(notifyCameraError(err));
2113 2116
                 });
2114 2117
             }
2115 2118
         );
@@ -2142,7 +2145,7 @@ export default {
2142 2145
                     this._updateAudioDeviceId();
2143 2146
                 })
2144 2147
                 .catch(err => {
2145
-                    APP.UI.showMicErrorNotification(err);
2148
+                    APP.store.dispatch(notifyMicError(err));
2146 2149
                 });
2147 2150
             }
2148 2151
         );

+ 16
- 0
doc/api.md Parādīt failu

@@ -264,6 +264,14 @@ The `event` parameter is a String object with the name of the event.
264 264
 The `listener` parameter is a Function object with one argument that will be notified when the event occurs with data related to the event.
265 265
 
266 266
 The following events are currently supported:
267
+* **cameraError** - event notifications about Jitsi-Meet having failed to access the camera. The listener will receive an object with the following structure:
268
+```javascript
269
+{
270
+    type: string, // A constant representing the overall type of the error.
271
+    message: string // Additional information about the error.
272
+}
273
+```
274
+
267 275
 * **avatarChanged** - event notifications about avatar
268 276
 changes. The listener will receive an object with the following structure:
269 277
 ```javascript
@@ -287,6 +295,14 @@ changes. The listener will receive an object with the following structure:
287 295
 }
288 296
 ```
289 297
 
298
+* **micError** - event notifications about Jitsi-Meet having failed to access the mic. The listener will receive an object with the following structure:
299
+```javascript
300
+{
301
+    type: string, // A constant representing the overall type of the error.
302
+    message: string // Additional information about the error.
303
+}
304
+```
305
+
290 306
 * **screenSharingStatusChanged** - receives event notifications about turning on/off the local user screen sharing. The listener will receive object with the following structure:
291 307
 ```javascript
292 308
 {

+ 32
- 0
modules/API/API.js Parādīt failu

@@ -559,6 +559,38 @@ class API {
559 559
         });
560 560
     }
561 561
 
562
+    /**
563
+     * Notify external application of an unexpected camera-related error having
564
+     * occurred.
565
+     *
566
+     * @param {string} type - The type of the camera error.
567
+     * @param {string} message - Additional information about the error.
568
+     * @returns {void}
569
+     */
570
+    notifyOnCameraError(type: string, message: string) {
571
+        this._sendEvent({
572
+            name: 'camera-error',
573
+            type,
574
+            message
575
+        });
576
+    }
577
+
578
+    /**
579
+     * Notify external application of an unexpected mic-related error having
580
+     * occurred.
581
+     *
582
+     * @param {string} type - The type of the mic error.
583
+     * @param {string} message - Additional information about the error.
584
+     * @returns {void}
585
+     */
586
+    notifyOnMicError(type: string, message: string) {
587
+        this._sendEvent({
588
+            name: 'mic-error',
589
+            type,
590
+            message
591
+        });
592
+    }
593
+
562 594
     /**
563 595
      * Notify external application (if API is enabled) that conference feedback
564 596
      * has been submitted. Intended to be used in conjunction with the

+ 2
- 0
modules/API/external/external_api.js Parādīt failu

@@ -51,6 +51,7 @@ const events = {
51 51
     'avatar-changed': 'avatarChanged',
52 52
     'audio-availability-changed': 'audioAvailabilityChanged',
53 53
     'audio-mute-status-changed': 'audioMuteStatusChanged',
54
+    'camera-error': 'cameraError',
54 55
     'device-list-changed': 'deviceListChanged',
55 56
     'display-name-change': 'displayNameChange',
56 57
     'email-change': 'emailChange',
@@ -58,6 +59,7 @@ const events = {
58 59
     'feedback-prompt-displayed': 'feedbackPromptDisplayed',
59 60
     'filmstrip-display-changed': 'filmstripDisplayChanged',
60 61
     'incoming-message': 'incomingMessage',
62
+    'mic-error': 'micError',
61 63
     'outgoing-message': 'outgoingMessage',
62 64
     'participant-joined': 'participantJoined',
63 65
     'participant-left': 'participantLeft',

+ 1
- 97
modules/UI/UI.js Parādīt failu

@@ -13,16 +13,12 @@ import SharedVideoManager from './shared_video/SharedVideo';
13 13
 import VideoLayout from './videolayout/VideoLayout';
14 14
 import Filmstrip from './videolayout/Filmstrip';
15 15
 
16
-import { JitsiTrackErrors } from '../../react/features/base/lib-jitsi-meet';
17 16
 import { getLocalParticipant } from '../../react/features/base/participants';
18 17
 import { toggleChat } from '../../react/features/chat';
19 18
 import { openDisplayNamePrompt } from '../../react/features/display-name';
20 19
 import { setEtherpadHasInitialzied } from '../../react/features/etherpad';
21 20
 import { setFilmstripVisible } from '../../react/features/filmstrip';
22
-import {
23
-    setNotificationsEnabled,
24
-    showWarningNotification
25
-} from '../../react/features/notifications';
21
+import { setNotificationsEnabled } from '../../react/features/notifications';
26 22
 import {
27 23
     dockToolbox,
28 24
     setToolboxEnabled,
@@ -40,39 +36,6 @@ UI.eventEmitter = eventEmitter;
40 36
 let etherpadManager;
41 37
 let sharedVideoManager;
42 38
 
43
-const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
44
-    microphone: {},
45
-    camera: {}
46
-};
47
-
48
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
49
-    .camera[JitsiTrackErrors.UNSUPPORTED_RESOLUTION]
50
-        = 'dialog.cameraUnsupportedResolutionError';
51
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[JitsiTrackErrors.GENERAL]
52
-    = 'dialog.cameraUnknownError';
53
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[JitsiTrackErrors.PERMISSION_DENIED]
54
-    = 'dialog.cameraPermissionDeniedError';
55
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[JitsiTrackErrors.NOT_FOUND]
56
-    = 'dialog.cameraNotFoundError';
57
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[JitsiTrackErrors.CONSTRAINT_FAILED]
58
-    = 'dialog.cameraConstraintFailedError';
59
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
60
-    .camera[JitsiTrackErrors.NO_DATA_FROM_SOURCE]
61
-        = 'dialog.cameraNotSendingData';
62
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.microphone[JitsiTrackErrors.GENERAL]
63
-    = 'dialog.micUnknownError';
64
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
65
-    .microphone[JitsiTrackErrors.PERMISSION_DENIED]
66
-        = 'dialog.micPermissionDeniedError';
67
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.microphone[JitsiTrackErrors.NOT_FOUND]
68
-    = 'dialog.micNotFoundError';
69
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
70
-    .microphone[JitsiTrackErrors.CONSTRAINT_FAILED]
71
-        = 'dialog.micConstraintFailedError';
72
-JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
73
-    .microphone[JitsiTrackErrors.NO_DATA_FROM_SOURCE]
74
-        = 'dialog.micNotSendingData';
75
-
76 39
 const UIListeners = new Map([
77 40
     [
78 41
         UIEvents.ETHERPAD_CLICKED,
@@ -774,65 +737,6 @@ UI.showExtensionInlineInstallationDialog = function(callback) {
774 737
     });
775 738
 };
776 739
 
777
-/**
778
- * Shows a notifications about the passed in microphone error.
779
- *
780
- * @param {JitsiTrackError} micError - An error object related to using or
781
- * acquiring an audio stream.
782
- * @returns {void}
783
- */
784
-UI.showMicErrorNotification = function(micError) {
785
-    if (!micError) {
786
-        return;
787
-    }
788
-
789
-    const { message, name } = micError;
790
-
791
-    const micJitsiTrackErrorMsg
792
-        = JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.microphone[name];
793
-    const micErrorMsg = micJitsiTrackErrorMsg
794
-        || JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
795
-            .microphone[JitsiTrackErrors.GENERAL];
796
-    const additionalMicErrorMsg = micJitsiTrackErrorMsg ? null : message;
797
-
798
-    APP.store.dispatch(showWarningNotification({
799
-        description: additionalMicErrorMsg,
800
-        descriptionKey: micErrorMsg,
801
-        titleKey: name === JitsiTrackErrors.PERMISSION_DENIED
802
-            ? 'deviceError.microphonePermission'
803
-            : 'deviceError.microphoneError'
804
-    }));
805
-};
806
-
807
-/**
808
- * Shows a notifications about the passed in camera error.
809
- *
810
- * @param {JitsiTrackError} cameraError - An error object related to using or
811
- * acquiring a video stream.
812
- * @returns {void}
813
- */
814
-UI.showCameraErrorNotification = function(cameraError) {
815
-    if (!cameraError) {
816
-        return;
817
-    }
818
-
819
-    const { message, name } = cameraError;
820
-
821
-    const cameraJitsiTrackErrorMsg
822
-        = JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[name];
823
-    const cameraErrorMsg = cameraJitsiTrackErrorMsg
824
-        || JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
825
-            .camera[JitsiTrackErrors.GENERAL];
826
-    const additionalCameraErrorMsg = cameraJitsiTrackErrorMsg ? null : message;
827
-
828
-    APP.store.dispatch(showWarningNotification({
829
-        description: additionalCameraErrorMsg,
830
-        descriptionKey: cameraErrorMsg,
831
-        titleKey: name === JitsiTrackErrors.PERMISSION_DENIED
832
-            ? 'deviceError.cameraPermission' : 'deviceError.cameraError'
833
-    }));
834
-};
835
-
836 740
 /**
837 741
  * Shows error dialog that informs the user that no data is received from the
838 742
  * device.

+ 9
- 5
modules/devices/mediaDeviceHelper.js Parādīt failu

@@ -1,6 +1,10 @@
1 1
 /* global APP, JitsiMeetJS */
2 2
 
3
-import { getAudioOutputDeviceId } from '../../react/features/base/devices';
3
+import {
4
+    getAudioOutputDeviceId,
5
+    notifyCameraError,
6
+    notifyMicError
7
+} from '../../react/features/base/devices';
4 8
 import {
5 9
     getUserSelectedCameraDeviceId,
6 10
     getUserSelectedMicDeviceId,
@@ -176,11 +180,11 @@ export default {
176 180
                 ]))
177 181
                 .then(tracks => {
178 182
                     if (audioTrackError) {
179
-                        APP.UI.showMicErrorNotification(audioTrackError);
183
+                        APP.store.dispatch(notifyMicError(audioTrackError));
180 184
                     }
181 185
 
182 186
                     if (videoTrackError) {
183
-                        APP.UI.showCameraErrorNotification(videoTrackError);
187
+                        APP.store.dispatch(notifyCameraError(videoTrackError));
184 188
                     }
185 189
 
186 190
                     return tracks.filter(t => typeof t !== 'undefined');
@@ -205,7 +209,7 @@ export default {
205 209
                 })
206 210
                 .catch(err => {
207 211
                     audioTrackError = err;
208
-                    showError && APP.UI.showMicErrorNotification(err);
212
+                    showError && APP.store.disptach(notifyMicError(err));
209 213
 
210 214
                     return [];
211 215
                 }));
@@ -223,7 +227,7 @@ export default {
223 227
                 })
224 228
                 .catch(err => {
225 229
                     videoTrackError = err;
226
-                    showError && APP.UI.showCameraErrorNotification(err);
230
+                    showError && APP.store.dispatch(notifyCameraError(err));
227 231
 
228 232
                     return [];
229 233
                 }));

+ 1
- 0
react/features/app/components/App.web.js Parādīt failu

@@ -6,6 +6,7 @@ import React from 'react';
6 6
 import { DialogContainer } from '../../base/dialog';
7 7
 import '../../base/responsive-ui';
8 8
 import '../../chat';
9
+import '../../external-api';
9 10
 import '../../room-lock';
10 11
 import '../../video-layout';
11 12
 

+ 22
- 0
react/features/base/devices/actionTypes.js Parādīt failu

@@ -1,3 +1,25 @@
1
+/**
2
+ * The type of Redux action which signals that an error occurred while obtaining
3
+ * a camera.
4
+ *
5
+ * {
6
+ *     type: NOTIFY_CAMERA_ERROR,
7
+ *     error: Object
8
+ * }
9
+ */
10
+export const NOTIFY_CAMERA_ERROR = 'NOTIFY_CAMERA_ERROR';
11
+
12
+/**
13
+ * The type of Redux action which signals that an error occurred while obtaining
14
+ * a microphone.
15
+ *
16
+ * {
17
+ *     type: NOTIFY_MIC_ERROR,
18
+ *     error: Object
19
+ * }
20
+ */
21
+export const NOTIFY_MIC_ERROR = 'NOTIFY_MIC_ERROR';
22
+
1 23
 /**
2 24
  * The type of Redux action which signals that the currently used audio
3 25
  * input device should be changed.

+ 39
- 0
react/features/base/devices/actions.js Parādīt failu

@@ -7,6 +7,8 @@ import {
7 7
 import {
8 8
     ADD_PENDING_DEVICE_REQUEST,
9 9
     CHECK_AND_NOTIFY_FOR_NEW_DEVICE,
10
+    NOTIFY_CAMERA_ERROR,
11
+    NOTIFY_MIC_ERROR,
10 12
     REMOVE_PENDING_DEVICE_REQUESTS,
11 13
     SET_AUDIO_INPUT_DEVICE,
12 14
     SET_VIDEO_INPUT_DEVICE,
@@ -148,6 +150,43 @@ export function getAvailableDevices() {
148 150
     });
149 151
 }
150 152
 
153
+/**
154
+ * Signals that an error occurred while trying to obtain a track from a camera.
155
+ *
156
+ * @param {Object} error - The device error, as provided by lib-jitsi-meet.
157
+ * @param {string} error.name - The constant for the type of the error.
158
+ * @param {string} error.message - Optional additional information about the
159
+ * error.
160
+ * @returns {{
161
+ *     type: NOTIFY_CAMERA_ERROR,
162
+ *     error: Object
163
+ * }}
164
+ */
165
+export function notifyCameraError(error) {
166
+    return {
167
+        type: NOTIFY_CAMERA_ERROR,
168
+        error
169
+    };
170
+}
171
+
172
+/**
173
+ * Signals that an error occurred while trying to obtain a track from a mic.
174
+ *
175
+ * @param {Object} error - The device error, as provided by lib-jitsi-meet.
176
+ * @param {Object} error.name - The constant for the type of the error.
177
+ * @param {string} error.message - Optional additional information about the
178
+ * error.
179
+ * @returns {{
180
+ *     type: NOTIFY_MIC_ERROR,
181
+ *     error: Object
182
+ * }}
183
+ */
184
+export function notifyMicError(error) {
185
+    return {
186
+        type: NOTIFY_MIC_ERROR,
187
+        error
188
+    };
189
+}
151 190
 
152 191
 /**
153 192
  * Remove all pending device requests.

+ 69
- 1
react/features/base/devices/middleware.js Parādīt failu

@@ -4,6 +4,7 @@ import { CONFERENCE_JOINED } from '../conference';
4 4
 import { processExternalDeviceRequest } from '../../device-selection';
5 5
 import { MiddlewareRegistry } from '../redux';
6 6
 import UIEvents from '../../../../service/UI/UIEvents';
7
+import { JitsiTrackErrors } from '../lib-jitsi-meet';
7 8
 
8 9
 import {
9 10
     removePendingDeviceRequests,
@@ -12,15 +13,35 @@ import {
12 13
 } from './actions';
13 14
 import {
14 15
     CHECK_AND_NOTIFY_FOR_NEW_DEVICE,
16
+    NOTIFY_CAMERA_ERROR,
17
+    NOTIFY_MIC_ERROR,
15 18
     SET_AUDIO_INPUT_DEVICE,
16 19
     SET_VIDEO_INPUT_DEVICE
17 20
 } from './actionTypes';
18
-import { showNotification } from '../../notifications';
21
+import { showNotification, showWarningNotification } from '../../notifications';
19 22
 import { updateSettings } from '../settings';
20 23
 import { setAudioOutputDeviceId } from './functions';
21 24
 
22 25
 const logger = require('jitsi-meet-logger').getLogger(__filename);
23 26
 
27
+const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
28
+    microphone: {
29
+        [JitsiTrackErrors.CONSTRAINT_FAILED]: 'dialog.micConstraintFailedError',
30
+        [JitsiTrackErrors.GENERAL]: 'dialog.micUnknownError',
31
+        [JitsiTrackErrors.NO_DATA_FROM_SOURCE]: 'dialog.micNotSendingData',
32
+        [JitsiTrackErrors.NOT_FOUND]: 'dialog.micNotFoundError',
33
+        [JitsiTrackErrors.PERMISSION_DENIED]: 'dialog.micPermissionDeniedError'
34
+    },
35
+    camera: {
36
+        [JitsiTrackErrors.CONSTRAINT_FAILED]: 'dialog.cameraConstraintFailedError',
37
+        [JitsiTrackErrors.GENERAL]: 'dialog.cameraUnknownError',
38
+        [JitsiTrackErrors.NO_DATA_FROM_SOURCE]: 'dialog.cameraNotSendingData',
39
+        [JitsiTrackErrors.NOT_FOUND]: 'dialog.cameraNotFoundError',
40
+        [JitsiTrackErrors.PERMISSION_DENIED]: 'dialog.cameraPermissionDeniedError',
41
+        [JitsiTrackErrors.UNSUPPORTED_RESOLUTION]: 'dialog.cameraUnsupportedResolutionError'
42
+    }
43
+};
44
+
24 45
 /**
25 46
  * Implements the middleware of the feature base/devices.
26 47
  *
@@ -32,6 +53,53 @@ MiddlewareRegistry.register(store => next => action => {
32 53
     switch (action.type) {
33 54
     case CONFERENCE_JOINED:
34 55
         return _conferenceJoined(store, next, action);
56
+    case NOTIFY_CAMERA_ERROR: {
57
+        if (typeof APP !== 'object' || !action.error) {
58
+            break;
59
+        }
60
+
61
+        const { message, name } = action.error;
62
+
63
+        const cameraJitsiTrackErrorMsg
64
+            = JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[name];
65
+        const cameraErrorMsg = cameraJitsiTrackErrorMsg
66
+            || JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
67
+                .camera[JitsiTrackErrors.GENERAL];
68
+        const additionalCameraErrorMsg = cameraJitsiTrackErrorMsg ? null : message;
69
+
70
+        store.dispatch(showWarningNotification({
71
+            description: additionalCameraErrorMsg,
72
+            descriptionKey: cameraErrorMsg,
73
+            titleKey: name === JitsiTrackErrors.PERMISSION_DENIED
74
+                ? 'deviceError.cameraPermission' : 'deviceError.cameraError'
75
+        }));
76
+
77
+        break;
78
+    }
79
+    case NOTIFY_MIC_ERROR: {
80
+        if (typeof APP !== 'object' || !action.error) {
81
+            break;
82
+        }
83
+
84
+        const { message, name } = action.error;
85
+
86
+        const micJitsiTrackErrorMsg
87
+            = JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.microphone[name];
88
+        const micErrorMsg = micJitsiTrackErrorMsg
89
+            || JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP
90
+                .microphone[JitsiTrackErrors.GENERAL];
91
+        const additionalMicErrorMsg = micJitsiTrackErrorMsg ? null : message;
92
+
93
+        store.dispatch(showWarningNotification({
94
+            description: additionalMicErrorMsg,
95
+            descriptionKey: micErrorMsg,
96
+            titleKey: name === JitsiTrackErrors.PERMISSION_DENIED
97
+                ? 'deviceError.microphonePermission'
98
+                : 'deviceError.microphoneError'
99
+        }));
100
+
101
+        break;
102
+    }
35 103
     case SET_AUDIO_INPUT_DEVICE:
36 104
         APP.UI.emitEvent(UIEvents.AUDIO_DEVICE_CHANGED, action.deviceId);
37 105
         break;

+ 1
- 0
react/features/external-api/index.js Parādīt failu

@@ -0,0 +1 @@
1
+import './middleware';

+ 30
- 0
react/features/external-api/middleware.js Parādīt failu

@@ -0,0 +1,30 @@
1
+// @flow
2
+
3
+import { NOTIFY_CAMERA_ERROR, NOTIFY_MIC_ERROR } from '../base/devices';
4
+import { MiddlewareRegistry } from '../base/redux';
5
+
6
+declare var APP: Object;
7
+
8
+/**
9
+ * The middleware of the feature {@code external-api}.
10
+ *
11
+ * @returns {Function}
12
+ */
13
+MiddlewareRegistry.register((/* store */) => next => action => {
14
+    switch (action.type) {
15
+    case NOTIFY_CAMERA_ERROR:
16
+        if (action.error) {
17
+            APP.API.notifyOnCameraError(
18
+              action.error.name, action.error.message);
19
+        }
20
+        break;
21
+
22
+    case NOTIFY_MIC_ERROR:
23
+        if (action.error) {
24
+            APP.API.notifyOnMicError(action.error.name, action.error.message);
25
+        }
26
+        break;
27
+    }
28
+
29
+    return next(action);
30
+});

Notiek ielāde…
Atcelt
Saglabāt