|
|
@@ -17,12 +17,18 @@ import {
|
|
17
|
17
|
} from '../../base/conference';
|
|
18
|
18
|
import { getInviteURL } from '../../base/connection';
|
|
19
|
19
|
import {
|
|
20
|
|
- isVideoMutedByAudioOnly,
|
|
|
20
|
+ MEDIA_TYPE,
|
|
21
|
21
|
SET_AUDIO_MUTED,
|
|
22
|
22
|
SET_VIDEO_MUTED,
|
|
|
23
|
+ VIDEO_MUTISM_AUTHORITY,
|
|
|
24
|
+ isVideoMutedByAudioOnly,
|
|
23
|
25
|
setAudioMuted
|
|
24
|
26
|
} from '../../base/media';
|
|
25
|
27
|
import { MiddlewareRegistry } from '../../base/redux';
|
|
|
28
|
+import {
|
|
|
29
|
+ TRACK_CREATE_ERROR,
|
|
|
30
|
+ isLocalTrackMuted
|
|
|
31
|
+} from '../../base/tracks';
|
|
26
|
32
|
|
|
27
|
33
|
import { _SET_CALLKIT_SUBSCRIPTIONS } from './actionTypes';
|
|
28
|
34
|
import CallKit from './CallKit';
|
|
|
@@ -65,6 +71,9 @@ CallKit && MiddlewareRegistry.register(store => next => action => {
|
|
65
|
71
|
|
|
66
|
72
|
case SET_VIDEO_MUTED:
|
|
67
|
73
|
return _setVideoMuted(store, next, action);
|
|
|
74
|
+
|
|
|
75
|
+ case TRACK_CREATE_ERROR:
|
|
|
76
|
+ return _trackCreateError(store, next, action);
|
|
68
|
77
|
}
|
|
69
|
78
|
|
|
70
|
79
|
return next(action);
|
|
|
@@ -230,10 +239,14 @@ function _conferenceWillJoin({ getState }, next, action) {
|
|
230
|
239
|
.then(() => {
|
|
231
|
240
|
const { room } = state['features/base/conference'];
|
|
232
|
241
|
const { callee } = state['features/base/jwt'];
|
|
|
242
|
+ const tracks = state['features/base/tracks'];
|
|
|
243
|
+ const muted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
|
|
233
|
244
|
|
|
234
|
245
|
CallKit.updateCall(
|
|
235
|
246
|
conference.callUUID,
|
|
236
|
247
|
{ displayName: (callee && callee.name) || room });
|
|
|
248
|
+
|
|
|
249
|
+ CallKit.setMuted(conference.callUUID, muted);
|
|
237
|
250
|
});
|
|
238
|
251
|
|
|
239
|
252
|
return result;
|
|
|
@@ -280,7 +293,8 @@ function _onPerformSetMutedCallAction({ callUUID, muted: newValue }) {
|
|
280
|
293
|
const value = Boolean(newValue);
|
|
281
|
294
|
|
|
282
|
295
|
sendAnalytics(createTrackMutedEvent('audio', 'callkit', value));
|
|
283
|
|
- dispatch(setAudioMuted(value));
|
|
|
296
|
+ dispatch(setAudioMuted(
|
|
|
297
|
+ value, VIDEO_MUTISM_AUTHORITY.USER, /* ensureTrack */ true));
|
|
284
|
298
|
}
|
|
285
|
299
|
}
|
|
286
|
300
|
}
|
|
|
@@ -361,3 +375,33 @@ function _setVideoMuted({ getState }, next, action) {
|
|
361
|
375
|
|
|
362
|
376
|
return result;
|
|
363
|
377
|
}
|
|
|
378
|
+
|
|
|
379
|
+/**
|
|
|
380
|
+ * Handles a track creation failure. This is relevant to us in the following
|
|
|
381
|
+ * (corner) case: if the user never gave their permission to use the microphone
|
|
|
382
|
+ * and try to unmute from the CallKit interface, this will fail, and we need
|
|
|
383
|
+ * to sync back the CallKit button state.
|
|
|
384
|
+ *
|
|
|
385
|
+ * @param {Store} store - The redux store in which the specified {@code action}
|
|
|
386
|
+ * is being dispatched.
|
|
|
387
|
+ * @param {Dispatch} next - The redux dispatch function to dispatch the
|
|
|
388
|
+ * specified {@code action} to the specified {@code store}.
|
|
|
389
|
+ * @param {Action} action - The redux action {@code TRACK_CREARE_ERROR} which is
|
|
|
390
|
+ * being dispatched in the specified {@code store}.
|
|
|
391
|
+ * @private
|
|
|
392
|
+ * @returns {*}
|
|
|
393
|
+ */
|
|
|
394
|
+function _trackCreateError({ getState }, next, action) {
|
|
|
395
|
+ const result = next(action);
|
|
|
396
|
+ const state = getState();
|
|
|
397
|
+ const conference = getCurrentConference(state);
|
|
|
398
|
+
|
|
|
399
|
+ if (conference && conference.callUUID) {
|
|
|
400
|
+ const tracks = state['features/base/tracks'];
|
|
|
401
|
+ const muted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);
|
|
|
402
|
+
|
|
|
403
|
+ CallKit.setMuted(conference.callUUID, muted);
|
|
|
404
|
+ }
|
|
|
405
|
+
|
|
|
406
|
+ return result;
|
|
|
407
|
+}
|