@whereby.com/core 0.25.1 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +862 -661
- package/dist/index.d.cts +550 -115
- package/dist/index.d.mts +550 -115
- package/dist/index.d.ts +550 -115
- package/dist/index.mjs +848 -662
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var toolkit = require('@reduxjs/toolkit');
|
|
4
4
|
var media = require('@whereby.com/media');
|
|
5
|
-
var events$1 = require('events');
|
|
6
5
|
var Chrome111_js = require('mediasoup-client/lib/handlers/Chrome111.js');
|
|
6
|
+
var events$1 = require('events');
|
|
7
7
|
var nodeBtoa = require('btoa');
|
|
8
8
|
var axios = require('axios');
|
|
9
9
|
|
|
@@ -23,6 +23,37 @@ function createAppAuthorizedThunk(authorizationSelector, thunk) {
|
|
|
23
23
|
return thunk(payload)(dispatch, getState, extra);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
+
function createRoomConnectedThunk(thunk) {
|
|
27
|
+
return createAppThunk((payload) => (dispatch, getState, extra) => {
|
|
28
|
+
const connectionStatus = getState().roomConnection.status;
|
|
29
|
+
if (connectionStatus !== "connected") {
|
|
30
|
+
console.warn("Action cannot be performed outside of a connected room");
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return thunk(payload)(dispatch, getState, extra);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function createAsyncRoomConnectedThunk(typePrefix, payloadCreator) {
|
|
37
|
+
return createAppAsyncThunk(typePrefix, (arg, thunkApi) => {
|
|
38
|
+
const { getState } = thunkApi;
|
|
39
|
+
const connectionStatus = getState().roomConnection.status;
|
|
40
|
+
if (connectionStatus !== "connected") {
|
|
41
|
+
console.warn("Action cannot be performed outside of a connected room");
|
|
42
|
+
return Promise.reject("Action cannot be performed outside of a connected room");
|
|
43
|
+
}
|
|
44
|
+
return payloadCreator(arg, thunkApi);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function createAuthorizedRoomConnectedThunk(authorizationSelector, thunk) {
|
|
48
|
+
return createAppThunk((payload) => (dispatch, getState, extra) => {
|
|
49
|
+
const connectionStatus = getState().roomConnection.status;
|
|
50
|
+
if (connectionStatus !== "connected") {
|
|
51
|
+
console.warn("Action cannot be performed outside of a connected room");
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return createAppAuthorizedThunk(authorizationSelector, thunk)(payload)(dispatch, getState, extra);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
26
57
|
|
|
27
58
|
const listenerMiddleware = toolkit.createListenerMiddleware();
|
|
28
59
|
const startAppListening = listenerMiddleware.startListening;
|
|
@@ -45,9 +76,9 @@ const createReactor = (selectors, callback) => {
|
|
|
45
76
|
});
|
|
46
77
|
};
|
|
47
78
|
|
|
48
|
-
const coreVersion = "0.
|
|
79
|
+
const coreVersion = "0.27.0";
|
|
49
80
|
|
|
50
|
-
const initialState$
|
|
81
|
+
const initialState$g = {
|
|
51
82
|
isNodeSdk: false,
|
|
52
83
|
isActive: false,
|
|
53
84
|
isDialIn: false,
|
|
@@ -59,7 +90,7 @@ const initialState$f = {
|
|
|
59
90
|
};
|
|
60
91
|
const appSlice = toolkit.createSlice({
|
|
61
92
|
name: "app",
|
|
62
|
-
initialState: initialState$
|
|
93
|
+
initialState: initialState$g,
|
|
63
94
|
reducers: {
|
|
64
95
|
doAppStart: (state, action) => {
|
|
65
96
|
const url = new URL(action.payload.roomUrl);
|
|
@@ -110,6 +141,7 @@ const signalEvents = {
|
|
|
110
141
|
spotlightRemoved: createSignalEventAction("spotlightRemoved"),
|
|
111
142
|
streamingStopped: createSignalEventAction("streamingStopped"),
|
|
112
143
|
videoEnabled: createSignalEventAction("videoEnabled"),
|
|
144
|
+
videoEnableRequested: createSignalEventAction("videoEnableRequested"),
|
|
113
145
|
liveTranscriptionStarted: createSignalEventAction("liveTranscriptionStarted"),
|
|
114
146
|
liveTranscriptionStopped: createSignalEventAction("liveTranscriptionStopped"),
|
|
115
147
|
};
|
|
@@ -117,18 +149,19 @@ const signalEvents = {
|
|
|
117
149
|
const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
|
|
118
150
|
canLockRoom: ["host"],
|
|
119
151
|
canRequestAudioEnable: ["host"],
|
|
152
|
+
canRequestVideoEnable: ["host"],
|
|
120
153
|
canKickClient: ["host"],
|
|
121
154
|
canEndMeeting: ["host"],
|
|
122
155
|
canAskToSpeak: ["host"],
|
|
123
156
|
canSpotlight: ["host"],
|
|
124
157
|
};
|
|
125
|
-
const initialState$
|
|
158
|
+
const initialState$f = {
|
|
126
159
|
roomKey: null,
|
|
127
160
|
roleName: "none",
|
|
128
161
|
};
|
|
129
162
|
const authorizationSlice = toolkit.createSlice({
|
|
130
163
|
name: "authorization",
|
|
131
|
-
initialState: initialState$
|
|
164
|
+
initialState: initialState$f,
|
|
132
165
|
reducers: {
|
|
133
166
|
setRoomKey: (state, action) => {
|
|
134
167
|
return Object.assign(Object.assign({}, state), { roomKey: action.payload });
|
|
@@ -150,6 +183,7 @@ const selectRoomKey = (state) => state.authorization.roomKey;
|
|
|
150
183
|
const selectAuthorizationRoleName = (state) => state.authorization.roleName;
|
|
151
184
|
const selectIsAuthorizedToLockRoom = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canLockRoom.includes(localParticipantRole));
|
|
152
185
|
const selectIsAuthorizedToRequestAudioEnable = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
|
|
186
|
+
const selectIsAuthorizedToRequestVideoEnable = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canRequestVideoEnable.includes(localParticipantRole));
|
|
153
187
|
const selectIsAuthorizedToKickClient = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canKickClient.includes(localParticipantRole));
|
|
154
188
|
const selectIsAuthorizedToEndMeeting = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canEndMeeting.includes(localParticipantRole));
|
|
155
189
|
const selectIsAuthorizedToAskToSpeak = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canAskToSpeak.includes(localParticipantRole));
|
|
@@ -199,13 +233,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
199
233
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
200
234
|
};
|
|
201
235
|
|
|
202
|
-
const initialState$
|
|
236
|
+
const initialState$e = {
|
|
203
237
|
isFetching: false,
|
|
204
238
|
data: null,
|
|
205
239
|
};
|
|
206
240
|
const deviceCredentialsSlice = toolkit.createSlice({
|
|
207
241
|
name: "deviceCredentials",
|
|
208
|
-
initialState: initialState$
|
|
242
|
+
initialState: initialState$e,
|
|
209
243
|
reducers: {},
|
|
210
244
|
extraReducers: (builder) => {
|
|
211
245
|
builder.addCase(doGetDeviceCredentials.pending, (state) => {
|
|
@@ -270,6 +304,7 @@ function forwardSocketEvents(socket, dispatch) {
|
|
|
270
304
|
socket.on("spotlight_removed", (payload) => dispatch(signalEvents.spotlightRemoved(payload)));
|
|
271
305
|
socket.on("live_transcription_started", (payload) => dispatch(signalEvents.liveTranscriptionStarted(payload)));
|
|
272
306
|
socket.on("live_transcription_stopped", (payload) => dispatch(signalEvents.liveTranscriptionStopped(payload)));
|
|
307
|
+
socket.on("video_enable_requested", (payload) => dispatch(signalEvents.videoEnableRequested(payload)));
|
|
273
308
|
}
|
|
274
309
|
const SIGNAL_BASE_URL = "wss://signal.appearin.net" ;
|
|
275
310
|
function createSocket() {
|
|
@@ -280,7 +315,7 @@ function createSocket() {
|
|
|
280
315
|
};
|
|
281
316
|
return new media.ServerSocket(socketHost, socketOverrides);
|
|
282
317
|
}
|
|
283
|
-
const initialState$
|
|
318
|
+
const initialState$d = {
|
|
284
319
|
deviceIdentified: false,
|
|
285
320
|
isIdentifyingDevice: false,
|
|
286
321
|
status: "ready",
|
|
@@ -288,7 +323,7 @@ const initialState$c = {
|
|
|
288
323
|
};
|
|
289
324
|
const signalConnectionSlice = toolkit.createSlice({
|
|
290
325
|
name: "signalConnection",
|
|
291
|
-
initialState: initialState$
|
|
326
|
+
initialState: initialState$d,
|
|
292
327
|
reducers: {
|
|
293
328
|
socketConnecting: (state) => {
|
|
294
329
|
return Object.assign(Object.assign({}, state), { status: "connecting" });
|
|
@@ -297,7 +332,7 @@ const signalConnectionSlice = toolkit.createSlice({
|
|
|
297
332
|
return Object.assign(Object.assign({}, state), { socket: action.payload, status: "connected" });
|
|
298
333
|
},
|
|
299
334
|
socketDisconnected: (state) => {
|
|
300
|
-
return Object.assign(Object.assign({}, state), { deviceIdentified: false, status: "disconnected" });
|
|
335
|
+
return Object.assign(Object.assign({}, state), { socket: null, deviceIdentified: false, status: "disconnected" });
|
|
301
336
|
},
|
|
302
337
|
socketReconnecting: (state) => {
|
|
303
338
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
@@ -392,12 +427,12 @@ startAppListening({
|
|
|
392
427
|
},
|
|
393
428
|
});
|
|
394
429
|
|
|
395
|
-
const initialState$
|
|
430
|
+
const initialState$c = {
|
|
396
431
|
chatMessages: [],
|
|
397
432
|
};
|
|
398
433
|
const chatSlice = toolkit.createSlice({
|
|
399
434
|
name: "chat",
|
|
400
|
-
initialState: initialState$
|
|
435
|
+
initialState: initialState$c,
|
|
401
436
|
reducers: {},
|
|
402
437
|
extraReducers(builder) {
|
|
403
438
|
builder.addCase(signalEvents.chatMessage, (state, action) => {
|
|
@@ -410,7 +445,7 @@ const chatSlice = toolkit.createSlice({
|
|
|
410
445
|
});
|
|
411
446
|
},
|
|
412
447
|
});
|
|
413
|
-
const doSendChatMessage =
|
|
448
|
+
const doSendChatMessage = createRoomConnectedThunk((payload) => (_, getState) => {
|
|
414
449
|
const state = getState();
|
|
415
450
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
416
451
|
socket === null || socket === void 0 ? void 0 : socket.emit("chat_message", { text: payload.text });
|
|
@@ -455,7 +490,7 @@ const cloudRecordingSlice = toolkit.createSlice({
|
|
|
455
490
|
},
|
|
456
491
|
});
|
|
457
492
|
const { recordingRequestStarted } = cloudRecordingSlice.actions;
|
|
458
|
-
const doStartCloudRecording =
|
|
493
|
+
const doStartCloudRecording = createRoomConnectedThunk(() => (dispatch, getState) => {
|
|
459
494
|
const state = getState();
|
|
460
495
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
461
496
|
const status = selectCloudRecordingStatus(state);
|
|
@@ -467,7 +502,7 @@ const doStartCloudRecording = createAppThunk(() => (dispatch, getState) => {
|
|
|
467
502
|
});
|
|
468
503
|
dispatch(recordingRequestStarted());
|
|
469
504
|
});
|
|
470
|
-
const doStopCloudRecording =
|
|
505
|
+
const doStopCloudRecording = createRoomConnectedThunk(() => (dispatch, getState) => {
|
|
471
506
|
const state = getState();
|
|
472
507
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
473
508
|
socket === null || socket === void 0 ? void 0 : socket.emit("stop_recording");
|
|
@@ -478,6 +513,60 @@ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
|
|
|
478
513
|
const selectCloudRecordingError = (state) => state.cloudRecording.error;
|
|
479
514
|
const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
|
|
480
515
|
|
|
516
|
+
const initialState$b = {
|
|
517
|
+
data: null,
|
|
518
|
+
isFetching: false,
|
|
519
|
+
error: null,
|
|
520
|
+
};
|
|
521
|
+
const organizationSlice = toolkit.createSlice({
|
|
522
|
+
initialState: initialState$b,
|
|
523
|
+
name: "organization",
|
|
524
|
+
reducers: {},
|
|
525
|
+
extraReducers: (builder) => {
|
|
526
|
+
builder.addCase(doOrganizationFetch.pending, (state) => {
|
|
527
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
528
|
+
});
|
|
529
|
+
builder.addCase(doOrganizationFetch.fulfilled, (state, action) => {
|
|
530
|
+
if (!action.payload)
|
|
531
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
532
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
533
|
+
});
|
|
534
|
+
builder.addCase(doOrganizationFetch.rejected, (state) => {
|
|
535
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, error: true });
|
|
536
|
+
});
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
const doOrganizationFetch = createAppAsyncThunk("organization/doOrganizationFetch", (_, { extra, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
540
|
+
try {
|
|
541
|
+
const roomUrl = selectAppRoomUrl(getState());
|
|
542
|
+
const organization = yield extra.services.fetchOrganizationFromRoomUrl(roomUrl || "");
|
|
543
|
+
if (!organization) {
|
|
544
|
+
throw new Error("Invalid room url");
|
|
545
|
+
}
|
|
546
|
+
return organization;
|
|
547
|
+
}
|
|
548
|
+
catch (error) {
|
|
549
|
+
console.error(error);
|
|
550
|
+
}
|
|
551
|
+
}));
|
|
552
|
+
const selectOrganizationRaw = (state) => state.organization;
|
|
553
|
+
const selectOrganizationId = (state) => { var _a; return (_a = state.organization.data) === null || _a === void 0 ? void 0 : _a.organizationId; };
|
|
554
|
+
const selectShouldFetchOrganization = toolkit.createSelector(selectAppIsActive, selectOrganizationRaw, selectDeviceCredentialsRaw, (appIsActive, organization, deviceCredentials) => {
|
|
555
|
+
if (appIsActive &&
|
|
556
|
+
!organization.data &&
|
|
557
|
+
!organization.isFetching &&
|
|
558
|
+
!organization.error &&
|
|
559
|
+
!deviceCredentials.isFetching) {
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
});
|
|
564
|
+
createReactor([selectShouldFetchOrganization], ({ dispatch }, shouldFetchOrganization) => {
|
|
565
|
+
if (shouldFetchOrganization) {
|
|
566
|
+
dispatch(doOrganizationFetch());
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
481
570
|
function fakeAudioStream() {
|
|
482
571
|
const audioCtx = new AudioContext();
|
|
483
572
|
const oscillator = audioCtx.createOscillator();
|
|
@@ -1057,6 +1146,15 @@ startAppListening({
|
|
|
1057
1146
|
}
|
|
1058
1147
|
},
|
|
1059
1148
|
});
|
|
1149
|
+
startAppListening({
|
|
1150
|
+
actionCreator: signalEvents.videoEnableRequested,
|
|
1151
|
+
effect: ({ payload }, { dispatch }) => {
|
|
1152
|
+
const { enable } = payload;
|
|
1153
|
+
if (!enable) {
|
|
1154
|
+
dispatch(toggleCameraEnabled({ enabled: false }));
|
|
1155
|
+
}
|
|
1156
|
+
},
|
|
1157
|
+
});
|
|
1060
1158
|
|
|
1061
1159
|
const NON_PERSON_ROLES = ["recorder", "streamer"];
|
|
1062
1160
|
|
|
@@ -1077,7 +1175,7 @@ const localParticipantSlice = toolkit.createSlice({
|
|
|
1077
1175
|
name: "localParticipant",
|
|
1078
1176
|
initialState: initialState$a,
|
|
1079
1177
|
reducers: {
|
|
1080
|
-
|
|
1178
|
+
setDisplayName: (state, action) => {
|
|
1081
1179
|
return Object.assign(Object.assign({}, state), { displayName: action.payload.displayName });
|
|
1082
1180
|
},
|
|
1083
1181
|
},
|
|
@@ -1101,8 +1199,17 @@ const localParticipantSlice = toolkit.createSlice({
|
|
|
1101
1199
|
});
|
|
1102
1200
|
},
|
|
1103
1201
|
});
|
|
1104
|
-
const {
|
|
1105
|
-
const
|
|
1202
|
+
const { setDisplayName } = localParticipantSlice.actions;
|
|
1203
|
+
const doSetDisplayName = createRoomConnectedThunk((payload) => (dispatch, getState) => {
|
|
1204
|
+
const state = getState();
|
|
1205
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1206
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("send_client_metadata", {
|
|
1207
|
+
type: "UserData",
|
|
1208
|
+
payload: { displayName: payload.displayName },
|
|
1209
|
+
});
|
|
1210
|
+
dispatch(setDisplayName({ displayName: payload.displayName }));
|
|
1211
|
+
});
|
|
1212
|
+
const doEnableAudio = createAsyncRoomConnectedThunk("localParticipant/doEnableAudio", (payload, { dispatch, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1106
1213
|
const state = getState();
|
|
1107
1214
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1108
1215
|
socket === null || socket === void 0 ? void 0 : socket.emit("enable_audio", { enabled: payload.enabled });
|
|
@@ -1111,13 +1218,13 @@ const doEnableAudio = createAppAsyncThunk("localParticipant/doEnableAudio", (pay
|
|
|
1111
1218
|
}
|
|
1112
1219
|
return payload.enabled;
|
|
1113
1220
|
}));
|
|
1114
|
-
const doEnableVideo =
|
|
1221
|
+
const doEnableVideo = createAsyncRoomConnectedThunk("localParticipant/doEnableVideo", (payload, { getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1115
1222
|
const state = getState();
|
|
1116
1223
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1117
1224
|
socket === null || socket === void 0 ? void 0 : socket.emit("enable_video", { enabled: payload.enabled });
|
|
1118
1225
|
return payload.enabled;
|
|
1119
1226
|
}));
|
|
1120
|
-
const doSetLocalStickyReaction =
|
|
1227
|
+
const doSetLocalStickyReaction = createAsyncRoomConnectedThunk("localParticipant/doSetLocalStickyReaction", (payload, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1121
1228
|
var _a;
|
|
1122
1229
|
const state = getState();
|
|
1123
1230
|
const currentStickyReaction = selectLocalParticipantStickyReaction(state);
|
|
@@ -1129,7 +1236,7 @@ const doSetLocalStickyReaction = createAppAsyncThunk("localParticipant/doSetLoca
|
|
|
1129
1236
|
const stickyReaction = enabled ? { reaction: "✋", timestamp: new Date().toISOString() } : null;
|
|
1130
1237
|
return stickyReaction;
|
|
1131
1238
|
}));
|
|
1132
|
-
const doSendClientMetadata =
|
|
1239
|
+
const doSendClientMetadata = createRoomConnectedThunk(() => (_, getState) => {
|
|
1133
1240
|
const state = getState();
|
|
1134
1241
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1135
1242
|
const payload = {
|
|
@@ -1183,86 +1290,179 @@ createReactor([selectLocalParticipantDisplayName, selectLocalParticipantStickyRe
|
|
|
1183
1290
|
});
|
|
1184
1291
|
|
|
1185
1292
|
const initialState$9 = {
|
|
1186
|
-
|
|
1187
|
-
|
|
1293
|
+
session: null,
|
|
1294
|
+
status: "ready",
|
|
1188
1295
|
error: null,
|
|
1189
1296
|
};
|
|
1190
|
-
const
|
|
1191
|
-
name: "localScreenshare",
|
|
1297
|
+
const roomConnectionSlice = toolkit.createSlice({
|
|
1192
1298
|
initialState: initialState$9,
|
|
1299
|
+
name: "roomConnection",
|
|
1193
1300
|
reducers: {
|
|
1194
|
-
|
|
1195
|
-
return Object.assign(Object.assign({}, state), { status:
|
|
1301
|
+
connectionStatusChanged: (state, action) => {
|
|
1302
|
+
return Object.assign(Object.assign({}, state), { status: action.payload });
|
|
1196
1303
|
},
|
|
1197
1304
|
},
|
|
1198
1305
|
extraReducers: (builder) => {
|
|
1199
|
-
builder.addCase(
|
|
1200
|
-
|
|
1306
|
+
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1307
|
+
var _a, _b;
|
|
1308
|
+
const { error, isLocked } = action.payload;
|
|
1309
|
+
if (error === "room_locked" && isLocked) {
|
|
1310
|
+
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
1311
|
+
}
|
|
1312
|
+
if (error) {
|
|
1313
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected", error });
|
|
1314
|
+
}
|
|
1315
|
+
return Object.assign(Object.assign({}, state), { status: "connected", session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
1201
1316
|
});
|
|
1202
|
-
builder.addCase(
|
|
1203
|
-
|
|
1317
|
+
builder.addCase(signalEvents.disconnect, (state) => {
|
|
1318
|
+
if (["kicked", "left"].includes(state.status)) {
|
|
1319
|
+
return Object.assign({}, state);
|
|
1320
|
+
}
|
|
1321
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected" });
|
|
1204
1322
|
});
|
|
1205
|
-
builder.addCase(
|
|
1206
|
-
|
|
1323
|
+
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
1324
|
+
var _a, _b;
|
|
1325
|
+
return Object.assign(Object.assign({}, state), { session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
1326
|
+
});
|
|
1327
|
+
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
1328
|
+
var _a;
|
|
1329
|
+
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
1330
|
+
return state;
|
|
1331
|
+
}
|
|
1332
|
+
return Object.assign(Object.assign({}, state), { session: null });
|
|
1333
|
+
});
|
|
1334
|
+
builder.addCase(signalEvents.clientKicked, (state) => {
|
|
1335
|
+
return Object.assign(Object.assign({}, state), { status: "kicked" });
|
|
1336
|
+
});
|
|
1337
|
+
builder.addCase(signalEvents.roomLeft, (state) => {
|
|
1338
|
+
return Object.assign(Object.assign({}, state), { status: "left" });
|
|
1339
|
+
});
|
|
1340
|
+
builder.addCase(socketReconnecting, (state) => {
|
|
1341
|
+
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1207
1342
|
});
|
|
1208
1343
|
},
|
|
1209
1344
|
});
|
|
1210
|
-
const {
|
|
1211
|
-
const
|
|
1212
|
-
var _a;
|
|
1213
|
-
try {
|
|
1214
|
-
const state = getState();
|
|
1215
|
-
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1216
|
-
if (screenshareStream) {
|
|
1217
|
-
return { stream: screenshareStream };
|
|
1218
|
-
}
|
|
1219
|
-
const stream = yield navigator.mediaDevices.getDisplayMedia();
|
|
1220
|
-
const onEnded = () => {
|
|
1221
|
-
dispatch(doStopScreenshare());
|
|
1222
|
-
};
|
|
1223
|
-
if ("oninactive" in stream) {
|
|
1224
|
-
stream.addEventListener("inactive", onEnded);
|
|
1225
|
-
}
|
|
1226
|
-
else {
|
|
1227
|
-
(_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.addEventListener("ended", onEnded);
|
|
1228
|
-
}
|
|
1229
|
-
return { stream };
|
|
1230
|
-
}
|
|
1231
|
-
catch (error) {
|
|
1232
|
-
return rejectWithValue(error);
|
|
1233
|
-
}
|
|
1234
|
-
}));
|
|
1235
|
-
const doStopScreenshare = createAppThunk(() => (dispatch, getState) => {
|
|
1345
|
+
const { connectionStatusChanged } = roomConnectionSlice.actions;
|
|
1346
|
+
const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1236
1347
|
const state = getState();
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1348
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1349
|
+
const roomName = selectAppRoomName(state);
|
|
1350
|
+
const roomKey = selectRoomKey(state);
|
|
1351
|
+
const displayName = selectAppDisplayName(state);
|
|
1352
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1353
|
+
const userAgent = selectAppUserAgent(state);
|
|
1354
|
+
const externalId = selectAppExternalId(state);
|
|
1355
|
+
const organizationId = selectOrganizationId(state);
|
|
1356
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("knock_room", {
|
|
1357
|
+
avatarUrl: null,
|
|
1358
|
+
config: {
|
|
1359
|
+
isAudioEnabled: true,
|
|
1360
|
+
isVideoEnabled: true,
|
|
1361
|
+
},
|
|
1362
|
+
deviceCapabilities: { canScreenshare: true },
|
|
1363
|
+
displayName,
|
|
1364
|
+
isCoLocated: false,
|
|
1365
|
+
isDialIn,
|
|
1366
|
+
isDevicePermissionDenied: false,
|
|
1367
|
+
kickFromOtherRooms: false,
|
|
1368
|
+
organizationId,
|
|
1369
|
+
roomKey,
|
|
1370
|
+
roomName,
|
|
1371
|
+
userAgent,
|
|
1372
|
+
externalId,
|
|
1373
|
+
});
|
|
1374
|
+
dispatch(connectionStatusChanged("knocking"));
|
|
1243
1375
|
});
|
|
1244
|
-
const
|
|
1245
|
-
const
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1376
|
+
const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1377
|
+
const state = getState();
|
|
1378
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1379
|
+
const roomName = selectAppRoomName(state);
|
|
1380
|
+
const roomKey = selectRoomKey(state);
|
|
1381
|
+
const displayName = selectAppDisplayName(state);
|
|
1382
|
+
const userAgent = selectAppUserAgent(state);
|
|
1383
|
+
const externalId = selectAppExternalId(state);
|
|
1384
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1385
|
+
const organizationId = selectOrganizationId(state);
|
|
1386
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1387
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1388
|
+
const clientClaim = selectLocalParticipantClientClaim(getState());
|
|
1389
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
|
|
1390
|
+
isAudioEnabled: isMicrophoneEnabled,
|
|
1391
|
+
isVideoEnabled: isCameraEnabled,
|
|
1392
|
+
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDialIn, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1393
|
+
roomKey,
|
|
1394
|
+
roomName,
|
|
1395
|
+
userAgent,
|
|
1396
|
+
externalId }, (clientClaim && { clientClaim })));
|
|
1397
|
+
dispatch(connectionStatusChanged("connecting"));
|
|
1259
1398
|
});
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1399
|
+
const selectRoomConnectionRaw = (state) => state.roomConnection;
|
|
1400
|
+
const selectRoomConnectionSession = (state) => state.roomConnection.session;
|
|
1401
|
+
const selectRoomConnectionSessionId = (state) => { var _a; return (_a = state.roomConnection.session) === null || _a === void 0 ? void 0 : _a.id; };
|
|
1402
|
+
const selectRoomConnectionStatus = (state) => state.roomConnection.status;
|
|
1403
|
+
const selectRoomConnectionError = (state) => state.roomConnection.error;
|
|
1404
|
+
const selectShouldConnectRoom = toolkit.createSelector([
|
|
1405
|
+
selectAppIsActive,
|
|
1406
|
+
selectOrganizationId,
|
|
1407
|
+
selectRoomConnectionStatus,
|
|
1408
|
+
selectSignalConnectionDeviceIdentified,
|
|
1409
|
+
selectLocalMediaStatus,
|
|
1410
|
+
selectRoomConnectionError,
|
|
1411
|
+
], (appIsActive, hasOrganizationIdFetched, roomConnectionStatus, signalConnectionDeviceIdentified, localMediaStatus, roomConnectionError) => {
|
|
1412
|
+
if (appIsActive &&
|
|
1413
|
+
localMediaStatus === "started" &&
|
|
1414
|
+
signalConnectionDeviceIdentified &&
|
|
1415
|
+
!!hasOrganizationIdFetched &&
|
|
1416
|
+
["ready", "reconnecting", "disconnected"].includes(roomConnectionStatus) &&
|
|
1417
|
+
!roomConnectionError) {
|
|
1418
|
+
return true;
|
|
1419
|
+
}
|
|
1420
|
+
return false;
|
|
1421
|
+
});
|
|
1422
|
+
createReactor([selectShouldConnectRoom], ({ dispatch }, shouldConnectRoom) => {
|
|
1423
|
+
if (shouldConnectRoom) {
|
|
1424
|
+
dispatch(doConnectRoom());
|
|
1425
|
+
}
|
|
1426
|
+
});
|
|
1427
|
+
startAppListening({
|
|
1428
|
+
actionCreator: signalEvents.knockHandled,
|
|
1429
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
1430
|
+
const { clientId, resolution } = payload;
|
|
1431
|
+
const state = getState();
|
|
1432
|
+
const selfId = selectSelfId(state);
|
|
1433
|
+
if (clientId !== selfId) {
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
if (resolution === "accepted") {
|
|
1437
|
+
dispatch(setRoomKey(payload.metadata.roomKey));
|
|
1438
|
+
dispatch(doConnectRoom());
|
|
1439
|
+
}
|
|
1440
|
+
else if (resolution === "rejected") {
|
|
1441
|
+
dispatch(connectionStatusChanged("knock_rejected"));
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
});
|
|
1445
|
+
startAppListening({
|
|
1446
|
+
actionCreator: doAppStop,
|
|
1447
|
+
effect: (_, { dispatch, getState }) => {
|
|
1448
|
+
const state = getState();
|
|
1449
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
1450
|
+
if (roomConnectionStatus === "connected") {
|
|
1451
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1452
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("leave_room");
|
|
1453
|
+
dispatch(connectionStatusChanged("leaving"));
|
|
1454
|
+
}
|
|
1455
|
+
else {
|
|
1456
|
+
doSignalDisconnect();
|
|
1457
|
+
}
|
|
1458
|
+
},
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
function createRtcEventAction(name) {
|
|
1462
|
+
return toolkit.createAction(`rtcConnection/event/${name}`);
|
|
1463
|
+
}
|
|
1464
|
+
const rtcEvents = {
|
|
1465
|
+
rtcManagerCreated: createRtcEventAction("rtcManagerCreated"),
|
|
1266
1466
|
rtcManagerDestroyed: createRtcEventAction("rtcManagerDestroyed"),
|
|
1267
1467
|
streamAdded: createRtcEventAction("streamAdded"),
|
|
1268
1468
|
};
|
|
@@ -1438,7 +1638,7 @@ const remoteParticipantsSlice = toolkit.createSlice({
|
|
|
1438
1638
|
},
|
|
1439
1639
|
});
|
|
1440
1640
|
const { participantStreamAdded, participantStreamIdAdded, streamStatusUpdated } = remoteParticipantsSlice.actions;
|
|
1441
|
-
const doRequestAudioEnable =
|
|
1641
|
+
const doRequestAudioEnable = createAuthorizedRoomConnectedThunk((state) => selectIsAuthorizedToRequestAudioEnable(state), (payload) => (_, getState) => {
|
|
1442
1642
|
const state = getState();
|
|
1443
1643
|
const canEnableRemoteAudio = selectIsAuthorizedToAskToSpeak(state);
|
|
1444
1644
|
if (payload.enable && !canEnableRemoteAudio) {
|
|
@@ -1448,6 +1648,11 @@ const doRequestAudioEnable = createAppAuthorizedThunk((state) => selectIsAuthori
|
|
|
1448
1648
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1449
1649
|
socket === null || socket === void 0 ? void 0 : socket.emit("request_audio_enable", payload);
|
|
1450
1650
|
});
|
|
1651
|
+
const doRequestVideoEnable = createAuthorizedRoomConnectedThunk((state) => selectIsAuthorizedToRequestVideoEnable(state), (payload) => (_, getState) => {
|
|
1652
|
+
const state = getState();
|
|
1653
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1654
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("request_video_enable", payload);
|
|
1655
|
+
});
|
|
1451
1656
|
const selectRemoteParticipantsRaw = (state) => state.remoteParticipants;
|
|
1452
1657
|
const selectRemoteClients = (state) => state.remoteParticipants.remoteParticipants;
|
|
1453
1658
|
const selectRemoteParticipants = toolkit.createSelector(selectRemoteClients, (clients) => clients.filter((c) => !NON_PERSON_ROLES.includes(c.roleName)));
|
|
@@ -1460,373 +1665,388 @@ const selectNumParticipants = toolkit.createSelector(selectRemoteParticipants, s
|
|
|
1460
1665
|
});
|
|
1461
1666
|
|
|
1462
1667
|
const initialState$7 = {
|
|
1463
|
-
|
|
1464
|
-
|
|
1668
|
+
status: "inactive",
|
|
1669
|
+
stream: null,
|
|
1465
1670
|
error: null,
|
|
1466
1671
|
};
|
|
1467
|
-
const
|
|
1672
|
+
const localScreenshareSlice = toolkit.createSlice({
|
|
1673
|
+
name: "localScreenshare",
|
|
1468
1674
|
initialState: initialState$7,
|
|
1469
|
-
|
|
1470
|
-
|
|
1675
|
+
reducers: {
|
|
1676
|
+
stopScreenshare(state, action) {
|
|
1677
|
+
return Object.assign(Object.assign({}, state), { status: "inactive", stream: null });
|
|
1678
|
+
},
|
|
1679
|
+
},
|
|
1471
1680
|
extraReducers: (builder) => {
|
|
1472
|
-
builder.addCase(
|
|
1473
|
-
return Object.assign(Object.assign({}, state), {
|
|
1681
|
+
builder.addCase(doStartScreenshare.pending, (state) => {
|
|
1682
|
+
return Object.assign(Object.assign({}, state), { status: "starting" });
|
|
1474
1683
|
});
|
|
1475
|
-
builder.addCase(
|
|
1476
|
-
|
|
1477
|
-
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1478
|
-
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
1684
|
+
builder.addCase(doStartScreenshare.fulfilled, (state, { payload: { stream } }) => {
|
|
1685
|
+
return Object.assign(Object.assign({}, state), { status: "active", stream });
|
|
1479
1686
|
});
|
|
1480
|
-
builder.addCase(
|
|
1481
|
-
return Object.assign(Object.assign({}, state), {
|
|
1687
|
+
builder.addCase(doStartScreenshare.rejected, (state, { payload }) => {
|
|
1688
|
+
return Object.assign(Object.assign({}, state), { error: payload, status: "inactive", stream: null });
|
|
1482
1689
|
});
|
|
1483
1690
|
},
|
|
1484
1691
|
});
|
|
1485
|
-
const
|
|
1692
|
+
const { stopScreenshare } = localScreenshareSlice.actions;
|
|
1693
|
+
const doStartScreenshare = createAsyncRoomConnectedThunk("localScreenshare/doStartScreenshare", (_, { dispatch, getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1694
|
+
var _a;
|
|
1486
1695
|
try {
|
|
1487
|
-
const
|
|
1488
|
-
const
|
|
1489
|
-
if (
|
|
1490
|
-
|
|
1696
|
+
const state = getState();
|
|
1697
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1698
|
+
if (screenshareStream) {
|
|
1699
|
+
return { stream: screenshareStream };
|
|
1491
1700
|
}
|
|
1492
|
-
|
|
1701
|
+
const stream = yield navigator.mediaDevices.getDisplayMedia();
|
|
1702
|
+
const onEnded = () => {
|
|
1703
|
+
dispatch(doStopScreenshare());
|
|
1704
|
+
};
|
|
1705
|
+
if ("oninactive" in stream) {
|
|
1706
|
+
stream.addEventListener("inactive", onEnded);
|
|
1707
|
+
}
|
|
1708
|
+
else {
|
|
1709
|
+
(_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.addEventListener("ended", onEnded);
|
|
1710
|
+
}
|
|
1711
|
+
return { stream };
|
|
1493
1712
|
}
|
|
1494
1713
|
catch (error) {
|
|
1495
|
-
|
|
1714
|
+
return rejectWithValue(error);
|
|
1496
1715
|
}
|
|
1497
1716
|
}));
|
|
1498
|
-
const
|
|
1499
|
-
const
|
|
1500
|
-
const
|
|
1501
|
-
if (
|
|
1502
|
-
|
|
1503
|
-
!organization.isFetching &&
|
|
1504
|
-
!organization.error &&
|
|
1505
|
-
!deviceCredentials.isFetching) {
|
|
1506
|
-
return true;
|
|
1717
|
+
const doStopScreenshare = createRoomConnectedThunk(() => (dispatch, getState) => {
|
|
1718
|
+
const state = getState();
|
|
1719
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1720
|
+
if (!screenshareStream) {
|
|
1721
|
+
return;
|
|
1507
1722
|
}
|
|
1508
|
-
|
|
1723
|
+
screenshareStream.getTracks().forEach((track) => track.stop());
|
|
1724
|
+
dispatch(stopScreenshare({ stream: screenshareStream }));
|
|
1509
1725
|
});
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1726
|
+
const selectLocalScreenshareRaw = (state) => state.localScreenshare;
|
|
1727
|
+
const selectLocalScreenshareStatus = (state) => state.localScreenshare.status;
|
|
1728
|
+
const selectLocalScreenshareStream = (state) => state.localScreenshare.stream;
|
|
1729
|
+
startAppListening({
|
|
1730
|
+
actionCreator: localMediaStopped,
|
|
1731
|
+
effect: (_, { getState }) => {
|
|
1732
|
+
const state = getState();
|
|
1733
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1734
|
+
if (!screenshareStream) {
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
screenshareStream === null || screenshareStream === void 0 ? void 0 : screenshareStream.getTracks().forEach((track) => {
|
|
1738
|
+
track.stop();
|
|
1739
|
+
});
|
|
1740
|
+
},
|
|
1514
1741
|
});
|
|
1515
1742
|
|
|
1743
|
+
const createWebRtcEmitter = (dispatch) => {
|
|
1744
|
+
return {
|
|
1745
|
+
emit: (eventName, data) => {
|
|
1746
|
+
if (eventName === "rtc_manager_created") {
|
|
1747
|
+
dispatch(doRtcManagerCreated(data));
|
|
1748
|
+
}
|
|
1749
|
+
else if (eventName === "stream_added") {
|
|
1750
|
+
dispatch(rtcEvents.streamAdded(data));
|
|
1751
|
+
}
|
|
1752
|
+
else if (eventName === "rtc_manager_destroyed") {
|
|
1753
|
+
dispatch(rtcManagerDestroyed());
|
|
1754
|
+
}
|
|
1755
|
+
else ;
|
|
1756
|
+
},
|
|
1757
|
+
};
|
|
1758
|
+
};
|
|
1516
1759
|
const initialState$6 = {
|
|
1517
|
-
|
|
1518
|
-
status: "ready",
|
|
1760
|
+
dispatcherCreated: false,
|
|
1519
1761
|
error: null,
|
|
1762
|
+
isCreatingDispatcher: false,
|
|
1763
|
+
reportedStreamResolutions: {},
|
|
1764
|
+
rtcManager: null,
|
|
1765
|
+
rtcManagerDispatcher: null,
|
|
1766
|
+
rtcManagerInitialized: false,
|
|
1767
|
+
status: "inactive",
|
|
1768
|
+
isAcceptingStreams: false,
|
|
1520
1769
|
};
|
|
1521
|
-
const
|
|
1770
|
+
const rtcConnectionSlice = toolkit.createSlice({
|
|
1771
|
+
name: "rtcConnection",
|
|
1522
1772
|
initialState: initialState$6,
|
|
1523
|
-
name: "roomConnection",
|
|
1524
1773
|
reducers: {
|
|
1525
|
-
|
|
1526
|
-
return Object.assign(Object.assign({}, state), {
|
|
1774
|
+
isAcceptingStreams: (state, action) => {
|
|
1775
|
+
return Object.assign(Object.assign({}, state), { isAcceptingStreams: action.payload });
|
|
1776
|
+
},
|
|
1777
|
+
resolutionReported: (state, action) => {
|
|
1778
|
+
const { streamId, width, height } = action.payload;
|
|
1779
|
+
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
1780
|
+
},
|
|
1781
|
+
rtcDisconnected: () => {
|
|
1782
|
+
return Object.assign({}, initialState$6);
|
|
1783
|
+
},
|
|
1784
|
+
rtcDispatcherCreated: (state, action) => {
|
|
1785
|
+
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
1786
|
+
},
|
|
1787
|
+
rtcManagerCreated: (state, action) => {
|
|
1788
|
+
return Object.assign(Object.assign({}, state), { rtcManager: action.payload, status: "ready" });
|
|
1789
|
+
},
|
|
1790
|
+
rtcManagerDestroyed: (state) => {
|
|
1791
|
+
return Object.assign(Object.assign({}, state), { rtcManager: null });
|
|
1792
|
+
},
|
|
1793
|
+
rtcManagerInitialized: (state) => {
|
|
1794
|
+
return Object.assign(Object.assign({}, state), { rtcManagerInitialized: true });
|
|
1527
1795
|
},
|
|
1528
1796
|
},
|
|
1529
1797
|
extraReducers: (builder) => {
|
|
1530
|
-
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1531
|
-
var _a, _b;
|
|
1532
|
-
const { error, isLocked } = action.payload;
|
|
1533
|
-
if (error === "room_locked" && isLocked) {
|
|
1534
|
-
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
1535
|
-
}
|
|
1536
|
-
if (error) {
|
|
1537
|
-
return Object.assign(Object.assign({}, state), { status: "disconnected", error });
|
|
1538
|
-
}
|
|
1539
|
-
return Object.assign(Object.assign({}, state), { status: "connected", session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
1540
|
-
});
|
|
1541
|
-
builder.addCase(signalEvents.disconnect, (state) => {
|
|
1542
|
-
if (["kicked", "left"].includes(state.status)) {
|
|
1543
|
-
return Object.assign({}, state);
|
|
1544
|
-
}
|
|
1545
|
-
return Object.assign(Object.assign({}, state), { status: "disconnected" });
|
|
1546
|
-
});
|
|
1547
|
-
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
1548
|
-
var _a, _b;
|
|
1549
|
-
return Object.assign(Object.assign({}, state), { session: (_b = (_a = action.payload.room) === null || _a === void 0 ? void 0 : _a.session) !== null && _b !== void 0 ? _b : null });
|
|
1550
|
-
});
|
|
1551
|
-
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
1552
|
-
var _a;
|
|
1553
|
-
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
1554
|
-
return state;
|
|
1555
|
-
}
|
|
1556
|
-
return Object.assign(Object.assign({}, state), { session: null });
|
|
1557
|
-
});
|
|
1558
|
-
builder.addCase(signalEvents.clientKicked, (state) => {
|
|
1559
|
-
return Object.assign(Object.assign({}, state), { status: "kicked" });
|
|
1560
|
-
});
|
|
1561
|
-
builder.addCase(signalEvents.roomLeft, (state) => {
|
|
1562
|
-
return Object.assign(Object.assign({}, state), { status: "left" });
|
|
1563
|
-
});
|
|
1564
1798
|
builder.addCase(socketReconnecting, (state) => {
|
|
1565
1799
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1566
1800
|
});
|
|
1801
|
+
builder.addCase(signalEvents.roomJoined, (state) => {
|
|
1802
|
+
return Object.assign(Object.assign({}, state), { status: state.status === "reconnecting" ? "ready" : state.status });
|
|
1803
|
+
});
|
|
1567
1804
|
},
|
|
1568
1805
|
});
|
|
1569
|
-
const {
|
|
1570
|
-
const
|
|
1806
|
+
const { resolutionReported, rtcDispatcherCreated, rtcDisconnected, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, isAcceptingStreams, } = rtcConnectionSlice.actions;
|
|
1807
|
+
const doConnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1571
1808
|
const state = getState();
|
|
1572
1809
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1573
|
-
const
|
|
1574
|
-
const
|
|
1575
|
-
const
|
|
1576
|
-
const
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1810
|
+
const dispatcher = selectRtcConnectionRaw(state).rtcManagerDispatcher;
|
|
1811
|
+
const isCameraEnabled = selectIsCameraEnabled(state);
|
|
1812
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(state);
|
|
1813
|
+
const isNodeSdk = selectAppIsNodeSdk(state);
|
|
1814
|
+
if (dispatcher || !socket) {
|
|
1815
|
+
return;
|
|
1816
|
+
}
|
|
1817
|
+
const webrtcProvider = {
|
|
1818
|
+
getMediaConstraints: () => ({
|
|
1819
|
+
audio: isMicrophoneEnabled,
|
|
1820
|
+
video: isCameraEnabled,
|
|
1821
|
+
}),
|
|
1822
|
+
deferrable(clientId) {
|
|
1823
|
+
return !clientId;
|
|
1824
|
+
},
|
|
1825
|
+
};
|
|
1826
|
+
const rtcManagerDispatcher = new media.RtcManagerDispatcher({
|
|
1827
|
+
emitter: createWebRtcEmitter(dispatch),
|
|
1828
|
+
serverSocket: socket,
|
|
1829
|
+
webrtcProvider,
|
|
1830
|
+
features: {
|
|
1831
|
+
isNodeSdk,
|
|
1832
|
+
lowDataModeEnabled: false,
|
|
1833
|
+
sfuServerOverrideHost: undefined,
|
|
1834
|
+
turnServerOverrideHost: undefined,
|
|
1835
|
+
useOnlyTURN: undefined,
|
|
1836
|
+
vp9On: false,
|
|
1837
|
+
h264On: false,
|
|
1838
|
+
simulcastScreenshareOn: false,
|
|
1839
|
+
deviceHandlerFactory: isNodeSdk ? Chrome111_js.Chrome111.createFactory() : undefined,
|
|
1585
1840
|
},
|
|
1586
|
-
deviceCapabilities: { canScreenshare: true },
|
|
1587
|
-
displayName,
|
|
1588
|
-
isCoLocated: false,
|
|
1589
|
-
isDialIn,
|
|
1590
|
-
isDevicePermissionDenied: false,
|
|
1591
|
-
kickFromOtherRooms: false,
|
|
1592
|
-
organizationId,
|
|
1593
|
-
roomKey,
|
|
1594
|
-
roomName,
|
|
1595
|
-
userAgent,
|
|
1596
|
-
externalId,
|
|
1597
1841
|
});
|
|
1598
|
-
dispatch(
|
|
1599
|
-
});
|
|
1600
|
-
const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1601
|
-
const state = getState();
|
|
1602
|
-
const socket = selectSignalConnectionRaw(state).socket;
|
|
1603
|
-
const roomName = selectAppRoomName(state);
|
|
1604
|
-
const roomKey = selectRoomKey(state);
|
|
1605
|
-
const displayName = selectAppDisplayName(state);
|
|
1606
|
-
const userAgent = selectAppUserAgent(state);
|
|
1607
|
-
const externalId = selectAppExternalId(state);
|
|
1608
|
-
const isDialIn = selectAppIsDialIn(state);
|
|
1609
|
-
const organizationId = selectOrganizationId(state);
|
|
1610
|
-
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1611
|
-
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1612
|
-
const clientClaim = selectLocalParticipantClientClaim(getState());
|
|
1613
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
|
|
1614
|
-
isAudioEnabled: isMicrophoneEnabled,
|
|
1615
|
-
isVideoEnabled: isCameraEnabled,
|
|
1616
|
-
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDialIn, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1617
|
-
roomKey,
|
|
1618
|
-
roomName,
|
|
1619
|
-
userAgent,
|
|
1620
|
-
externalId }, (clientClaim && { clientClaim })));
|
|
1621
|
-
dispatch(connectionStatusChanged("connecting"));
|
|
1842
|
+
dispatch(rtcDispatcherCreated(rtcManagerDispatcher));
|
|
1622
1843
|
});
|
|
1623
|
-
const
|
|
1624
|
-
const
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
const selectRoomConnectionError = (state) => state.roomConnection.error;
|
|
1628
|
-
const selectShouldConnectRoom = toolkit.createSelector([
|
|
1629
|
-
selectAppIsActive,
|
|
1630
|
-
selectOrganizationId,
|
|
1631
|
-
selectRoomConnectionStatus,
|
|
1632
|
-
selectSignalConnectionDeviceIdentified,
|
|
1633
|
-
selectLocalMediaStatus,
|
|
1634
|
-
selectRoomConnectionError,
|
|
1635
|
-
], (appIsActive, hasOrganizationIdFetched, roomConnectionStatus, signalConnectionDeviceIdentified, localMediaStatus, roomConnectionError) => {
|
|
1636
|
-
if (appIsActive &&
|
|
1637
|
-
localMediaStatus === "started" &&
|
|
1638
|
-
signalConnectionDeviceIdentified &&
|
|
1639
|
-
!!hasOrganizationIdFetched &&
|
|
1640
|
-
["ready", "reconnecting", "disconnected"].includes(roomConnectionStatus) &&
|
|
1641
|
-
!roomConnectionError) {
|
|
1642
|
-
return true;
|
|
1844
|
+
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1845
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1846
|
+
if (rtcManager) {
|
|
1847
|
+
rtcManager.disconnectAll();
|
|
1643
1848
|
}
|
|
1644
|
-
|
|
1849
|
+
dispatch(rtcDisconnected());
|
|
1645
1850
|
});
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1851
|
+
const doHandleAcceptStreams = createAppThunk((payload) => (dispatch, getState) => {
|
|
1852
|
+
var _a;
|
|
1853
|
+
dispatch(isAcceptingStreams(true));
|
|
1854
|
+
const state = getState();
|
|
1855
|
+
const rtcManager = selectRtcConnectionRaw(state).rtcManager;
|
|
1856
|
+
const remoteClients = selectRemoteClients(state);
|
|
1857
|
+
if (!rtcManager) {
|
|
1858
|
+
throw new Error("No rtc manager");
|
|
1649
1859
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
const
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
if (
|
|
1658
|
-
|
|
1860
|
+
const activeBreakout = false;
|
|
1861
|
+
const shouldAcceptNewClients = (_a = rtcManager.shouldAcceptStreamsFromBothSides) === null || _a === void 0 ? void 0 : _a.call(rtcManager);
|
|
1862
|
+
const updates = [];
|
|
1863
|
+
for (const { clientId, streamId, state } of payload) {
|
|
1864
|
+
const participant = remoteClients.find((p) => p.id === clientId);
|
|
1865
|
+
if (!participant)
|
|
1866
|
+
continue;
|
|
1867
|
+
if (state === "to_accept" ||
|
|
1868
|
+
(state === "new_accept" && shouldAcceptNewClients) ||
|
|
1869
|
+
(state === "old_accept" && !shouldAcceptNewClients)) {
|
|
1870
|
+
const enforceTurnProtocol = participant.isDialIn ? "onlytls" : undefined;
|
|
1871
|
+
rtcManager.acceptNewStream({
|
|
1872
|
+
streamId: streamId === "0" ? clientId : streamId,
|
|
1873
|
+
clientId,
|
|
1874
|
+
shouldAddLocalVideo: streamId === "0",
|
|
1875
|
+
activeBreakout,
|
|
1876
|
+
enforceTurnProtocol,
|
|
1877
|
+
});
|
|
1659
1878
|
}
|
|
1660
|
-
if (
|
|
1661
|
-
|
|
1662
|
-
|
|
1879
|
+
else if (state === "new_accept" || state === "old_accept") ;
|
|
1880
|
+
else if (state === "to_unaccept") {
|
|
1881
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.disconnect(streamId === "0" ? clientId : streamId, activeBreakout);
|
|
1663
1882
|
}
|
|
1664
|
-
else if (
|
|
1665
|
-
|
|
1883
|
+
else if (state !== "done_accept") {
|
|
1884
|
+
continue;
|
|
1666
1885
|
}
|
|
1667
|
-
|
|
1886
|
+
else ;
|
|
1887
|
+
updates.push({ clientId, streamId, state: state.replace(/to_|new_|old_/, "done_") });
|
|
1888
|
+
}
|
|
1889
|
+
dispatch(streamStatusUpdated(updates));
|
|
1890
|
+
dispatch(isAcceptingStreams(false));
|
|
1668
1891
|
});
|
|
1892
|
+
const doRtcReportStreamResolution = createAppThunk(({ streamId, width, height }) => (dispatch, getState) => {
|
|
1893
|
+
const { reportedStreamResolutions, rtcManager } = selectRtcConnectionRaw(getState());
|
|
1894
|
+
const localStream = selectLocalMediaStream(getState());
|
|
1895
|
+
if (!rtcManager || (localStream === null || localStream === void 0 ? void 0 : localStream.id) === streamId) {
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
const old = reportedStreamResolutions[streamId];
|
|
1899
|
+
if (!old || old.width !== width || old.height !== height) {
|
|
1900
|
+
rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
|
|
1901
|
+
}
|
|
1902
|
+
dispatch(resolutionReported({ streamId, width, height }));
|
|
1903
|
+
});
|
|
1904
|
+
const doRtcManagerCreated = createAppThunk((payload) => (dispatch) => {
|
|
1905
|
+
const { rtcManager } = payload;
|
|
1906
|
+
dispatch(rtcManagerCreated(rtcManager));
|
|
1907
|
+
});
|
|
1908
|
+
const doRtcManagerInitialize = createAppThunk(() => (dispatch, getState) => {
|
|
1909
|
+
const localMediaStream = selectLocalMediaStream(getState());
|
|
1910
|
+
const rtcManager = selectRtcConnectionRaw(getState()).rtcManager;
|
|
1911
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1912
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1913
|
+
if (localMediaStream && rtcManager) {
|
|
1914
|
+
rtcManager.addNewStream("0", localMediaStream, !isMicrophoneEnabled, !isCameraEnabled);
|
|
1915
|
+
}
|
|
1916
|
+
dispatch(rtcManagerInitialized());
|
|
1917
|
+
});
|
|
1918
|
+
const selectRtcConnectionRaw = (state) => state.rtcConnection;
|
|
1919
|
+
const selectRtcManagerInitialized = (state) => state.rtcConnection.rtcManagerInitialized;
|
|
1920
|
+
const selectRtcManager = (state) => state.rtcConnection.rtcManager;
|
|
1921
|
+
const selectRtcDispatcherCreated = (state) => state.rtcConnection.dispatcherCreated;
|
|
1922
|
+
const selectRtcIsCreatingDispatcher = (state) => state.rtcConnection.isCreatingDispatcher;
|
|
1923
|
+
const selectRtcStatus = (state) => state.rtcConnection.status;
|
|
1924
|
+
const selectIsAcceptingStreams = (state) => state.rtcConnection.isAcceptingStreams;
|
|
1669
1925
|
startAppListening({
|
|
1670
|
-
actionCreator:
|
|
1671
|
-
effect: (
|
|
1672
|
-
const
|
|
1673
|
-
const
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
}
|
|
1926
|
+
actionCreator: doSetDevice.fulfilled,
|
|
1927
|
+
effect: ({ payload }, { getState }) => {
|
|
1928
|
+
const { replacedTracks } = payload;
|
|
1929
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1930
|
+
const stream = selectLocalMediaStream(getState());
|
|
1931
|
+
const replace = (kind, oldTrack) => {
|
|
1932
|
+
const track = stream === null || stream === void 0 ? void 0 : stream.getTracks().find((t) => t.kind === kind);
|
|
1933
|
+
return track && (rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.replaceTrack(oldTrack, track));
|
|
1934
|
+
};
|
|
1935
|
+
replacedTracks === null || replacedTracks === void 0 ? void 0 : replacedTracks.forEach((t) => {
|
|
1936
|
+
replace(t.kind, t);
|
|
1937
|
+
});
|
|
1682
1938
|
},
|
|
1683
1939
|
});
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
const initialNotificationsState = {
|
|
1691
|
-
emitter,
|
|
1692
|
-
events: [],
|
|
1693
|
-
};
|
|
1694
|
-
const notificationsSlice = toolkit.createSlice({
|
|
1695
|
-
name: "notifications",
|
|
1696
|
-
initialState: initialNotificationsState,
|
|
1697
|
-
reducers: {
|
|
1698
|
-
addNotification: (state, action) => {
|
|
1699
|
-
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
1700
|
-
},
|
|
1701
|
-
doClearNotifications: (state) => {
|
|
1702
|
-
return Object.assign(Object.assign({}, state), { events: [] });
|
|
1703
|
-
},
|
|
1940
|
+
startAppListening({
|
|
1941
|
+
actionCreator: doStartScreenshare.fulfilled,
|
|
1942
|
+
effect: ({ payload }, { getState }) => {
|
|
1943
|
+
const { stream } = payload;
|
|
1944
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1945
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.addNewStream(stream.id, stream, false, true);
|
|
1704
1946
|
},
|
|
1705
1947
|
});
|
|
1706
|
-
const { doClearNotifications } = notificationsSlice.actions;
|
|
1707
|
-
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
1708
|
-
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
1709
|
-
const state = getState();
|
|
1710
|
-
const emitter = selectNotificationsEmitter(state);
|
|
1711
|
-
emitter.emit(payload.type, payload);
|
|
1712
|
-
emitter.emit("*", payload);
|
|
1713
|
-
});
|
|
1714
|
-
const selectNotificationsRaw = (state) => state.notifications;
|
|
1715
|
-
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
1716
|
-
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
1717
1948
|
startAppListening({
|
|
1718
|
-
actionCreator:
|
|
1719
|
-
effect: (
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
if (!client) {
|
|
1723
|
-
console.warn("Could not find remote client that sent chat message");
|
|
1724
|
-
return;
|
|
1725
|
-
}
|
|
1726
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1727
|
-
type: "chatMessageReceived",
|
|
1728
|
-
message: `${client.displayName} says: ${payload.text}`,
|
|
1729
|
-
props: {
|
|
1730
|
-
client,
|
|
1731
|
-
chatMessage: {
|
|
1732
|
-
senderId: payload.senderId,
|
|
1733
|
-
timestamp: payload.timestamp,
|
|
1734
|
-
text: payload.text,
|
|
1735
|
-
},
|
|
1736
|
-
},
|
|
1737
|
-
})));
|
|
1949
|
+
actionCreator: doAppStop,
|
|
1950
|
+
effect: (_, { getState }) => {
|
|
1951
|
+
const rtcManager = selectRtcManager(getState());
|
|
1952
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.rtcStatsDisconnect();
|
|
1738
1953
|
},
|
|
1739
1954
|
});
|
|
1740
1955
|
startAppListening({
|
|
1741
|
-
actionCreator:
|
|
1742
|
-
effect: ({ payload }, {
|
|
1743
|
-
const {
|
|
1744
|
-
const
|
|
1745
|
-
|
|
1746
|
-
if (!client) {
|
|
1747
|
-
console.warn("Could not find remote client that requested a local audio change");
|
|
1748
|
-
return;
|
|
1749
|
-
}
|
|
1750
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1751
|
-
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
1752
|
-
message: enable
|
|
1753
|
-
? `${client.displayName} has requested for you to speak`
|
|
1754
|
-
: `${client.displayName} has muted your microphone`,
|
|
1755
|
-
props: {
|
|
1756
|
-
client,
|
|
1757
|
-
enable,
|
|
1758
|
-
},
|
|
1759
|
-
})));
|
|
1956
|
+
actionCreator: stopScreenshare,
|
|
1957
|
+
effect: ({ payload }, { getState }) => {
|
|
1958
|
+
const { stream } = payload;
|
|
1959
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1960
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.removeStream(stream.id, stream, null);
|
|
1760
1961
|
},
|
|
1761
1962
|
});
|
|
1762
1963
|
startAppListening({
|
|
1763
|
-
actionCreator:
|
|
1764
|
-
effect: (
|
|
1964
|
+
actionCreator: doSwitchLocalStream.fulfilled,
|
|
1965
|
+
effect: ({ payload }, { getState }) => {
|
|
1765
1966
|
var _a;
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
1777
|
-
if (!client) {
|
|
1778
|
-
console.warn("Could not find remote client that provided updated metadata");
|
|
1779
|
-
return;
|
|
1780
|
-
}
|
|
1781
|
-
const previousState = getOriginalState();
|
|
1782
|
-
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
1783
|
-
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
1784
|
-
(stickyReaction === null || stickyReaction === void 0 ? void 0 : stickyReaction.timestamp) === ((_a = previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction) === null || _a === void 0 ? void 0 : _a.timestamp)) {
|
|
1785
|
-
return;
|
|
1967
|
+
const stream = selectLocalMediaStream(getState());
|
|
1968
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1969
|
+
if (stream && rtcManager) {
|
|
1970
|
+
const replace = (kind, oldTrack) => {
|
|
1971
|
+
const track = stream.getTracks().find((t) => t.kind === kind);
|
|
1972
|
+
return track && rtcManager.replaceTrack(oldTrack, track);
|
|
1973
|
+
};
|
|
1974
|
+
(_a = payload === null || payload === void 0 ? void 0 : payload.replacedTracks) === null || _a === void 0 ? void 0 : _a.forEach((t) => {
|
|
1975
|
+
replace(t.kind, t);
|
|
1976
|
+
});
|
|
1786
1977
|
}
|
|
1787
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1788
|
-
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
1789
|
-
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
1790
|
-
props: {
|
|
1791
|
-
client,
|
|
1792
|
-
stickyReaction,
|
|
1793
|
-
},
|
|
1794
|
-
})));
|
|
1795
1978
|
},
|
|
1796
1979
|
});
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1980
|
+
const selectShouldConnectRtc = toolkit.createSelector(selectRtcStatus, selectAppIsActive, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectSignalConnectionSocket, (rtcStatus, appIsActive, dispatcherCreated, isCreatingDispatcher, signalSocket) => {
|
|
1981
|
+
if (appIsActive && rtcStatus === "inactive" && !dispatcherCreated && !isCreatingDispatcher && signalSocket) {
|
|
1982
|
+
return true;
|
|
1983
|
+
}
|
|
1984
|
+
return false;
|
|
1985
|
+
});
|
|
1986
|
+
createReactor([selectShouldConnectRtc], ({ dispatch }, shouldConnectRtc) => {
|
|
1987
|
+
if (shouldConnectRtc) {
|
|
1988
|
+
dispatch(doConnectRtc());
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
const selectShouldInitializeRtc = toolkit.createSelector(selectRtcManager, selectRtcManagerInitialized, selectLocalMediaStatus, (rtcManager, rtcManagerInitialized, localMediaStatus) => {
|
|
1992
|
+
if (localMediaStatus === "started" && rtcManager && !rtcManagerInitialized) {
|
|
1993
|
+
return true;
|
|
1802
1994
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
})));
|
|
1995
|
+
return false;
|
|
1996
|
+
});
|
|
1997
|
+
createReactor([selectShouldInitializeRtc], ({ dispatch }, shouldInitializeRtc) => {
|
|
1998
|
+
if (shouldInitializeRtc) {
|
|
1999
|
+
dispatch(doRtcManagerInitialize());
|
|
1809
2000
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
props: {},
|
|
1815
|
-
})));
|
|
2001
|
+
});
|
|
2002
|
+
const selectShouldDisconnectRtc = toolkit.createSelector(selectRtcStatus, selectAppIsActive, (status, appIsActive) => {
|
|
2003
|
+
if (!appIsActive && !["inactive", "disconnected"].includes(status)) {
|
|
2004
|
+
return true;
|
|
1816
2005
|
}
|
|
2006
|
+
return false;
|
|
1817
2007
|
});
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2008
|
+
createReactor([selectShouldDisconnectRtc], ({ dispatch }, shouldDisconnectRtc) => {
|
|
2009
|
+
if (shouldDisconnectRtc) {
|
|
2010
|
+
dispatch(doDisconnectRtc());
|
|
2011
|
+
}
|
|
2012
|
+
});
|
|
2013
|
+
const selectStreamsToAccept = toolkit.createSelector(selectRtcStatus, selectRemoteClients, (rtcStatus, remoteParticipants) => {
|
|
2014
|
+
if (rtcStatus !== "ready") {
|
|
2015
|
+
return [];
|
|
2016
|
+
}
|
|
2017
|
+
const upd = [];
|
|
2018
|
+
for (const client of remoteParticipants) {
|
|
2019
|
+
const { streams, id: clientId, newJoiner } = client;
|
|
2020
|
+
for (let i = 0; i < streams.length; i++) {
|
|
2021
|
+
let streamId = streams[i].id;
|
|
2022
|
+
let state = streams[i].state;
|
|
2023
|
+
if ((streams === null || streams === void 0 ? void 0 : streams.length) > 1 && streams[1].id === "0") {
|
|
2024
|
+
if (i === 0) {
|
|
2025
|
+
streamId = streams[1].id;
|
|
2026
|
+
state = streams[1].state;
|
|
2027
|
+
}
|
|
2028
|
+
else if (i === 1) {
|
|
2029
|
+
streamId = streams[0].id;
|
|
2030
|
+
state = streams[0].state;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
{
|
|
2034
|
+
if (state === "done_accept")
|
|
2035
|
+
continue;
|
|
2036
|
+
upd.push({
|
|
2037
|
+
clientId,
|
|
2038
|
+
streamId,
|
|
2039
|
+
state: `${newJoiner && streamId === "0" ? "new" : "to"}_accept`,
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
1828
2042
|
}
|
|
1829
|
-
}
|
|
2043
|
+
}
|
|
2044
|
+
return upd;
|
|
2045
|
+
});
|
|
2046
|
+
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
2047
|
+
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
2048
|
+
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
2049
|
+
}
|
|
1830
2050
|
});
|
|
1831
2051
|
|
|
1832
2052
|
function isStreamerClient(client) {
|
|
@@ -1938,313 +2158,278 @@ const selectAllClientViews = toolkit.createSelector(selectLocalParticipantView,
|
|
|
1938
2158
|
return [...(localParticipant ? [localParticipant] : []), ...remoteParticipants];
|
|
1939
2159
|
});
|
|
1940
2160
|
|
|
1941
|
-
const createWebRtcEmitter = (dispatch) => {
|
|
1942
|
-
return {
|
|
1943
|
-
emit: (eventName, data) => {
|
|
1944
|
-
if (eventName === "rtc_manager_created") {
|
|
1945
|
-
dispatch(doRtcManagerCreated(data));
|
|
1946
|
-
}
|
|
1947
|
-
else if (eventName === "stream_added") {
|
|
1948
|
-
dispatch(rtcEvents.streamAdded(data));
|
|
1949
|
-
}
|
|
1950
|
-
else if (eventName === "rtc_manager_destroyed") {
|
|
1951
|
-
dispatch(rtcManagerDestroyed());
|
|
1952
|
-
}
|
|
1953
|
-
else ;
|
|
1954
|
-
},
|
|
1955
|
-
};
|
|
1956
|
-
};
|
|
1957
2161
|
const initialState$4 = {
|
|
1958
|
-
|
|
1959
|
-
error: null,
|
|
1960
|
-
isCreatingDispatcher: false,
|
|
1961
|
-
reportedStreamResolutions: {},
|
|
1962
|
-
rtcManager: null,
|
|
1963
|
-
rtcManagerDispatcher: null,
|
|
1964
|
-
rtcManagerInitialized: false,
|
|
1965
|
-
status: "inactive",
|
|
1966
|
-
isAcceptingStreams: false,
|
|
2162
|
+
running: false,
|
|
1967
2163
|
};
|
|
1968
|
-
const
|
|
1969
|
-
name: "
|
|
2164
|
+
const connectionMonitorSlice = toolkit.createSlice({
|
|
2165
|
+
name: "connectionMonitor",
|
|
1970
2166
|
initialState: initialState$4,
|
|
1971
2167
|
reducers: {
|
|
1972
|
-
|
|
1973
|
-
return Object.assign(Object.assign({}, state), {
|
|
1974
|
-
},
|
|
1975
|
-
resolutionReported: (state, action) => {
|
|
1976
|
-
const { streamId, width, height } = action.payload;
|
|
1977
|
-
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
2168
|
+
connectionMonitorStarted: (state, action) => {
|
|
2169
|
+
return Object.assign(Object.assign({}, state), { running: true, stopCallbackFunction: action.payload.stopIssueSubscription });
|
|
1978
2170
|
},
|
|
1979
|
-
|
|
2171
|
+
connectionMonitorStopped: () => {
|
|
1980
2172
|
return Object.assign({}, initialState$4);
|
|
1981
2173
|
},
|
|
1982
|
-
rtcDispatcherCreated: (state, action) => {
|
|
1983
|
-
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
1984
|
-
},
|
|
1985
|
-
rtcManagerCreated: (state, action) => {
|
|
1986
|
-
return Object.assign(Object.assign({}, state), { rtcManager: action.payload, status: "ready" });
|
|
1987
|
-
},
|
|
1988
|
-
rtcManagerDestroyed: (state) => {
|
|
1989
|
-
return Object.assign(Object.assign({}, state), { rtcManager: null });
|
|
1990
|
-
},
|
|
1991
|
-
rtcManagerInitialized: (state) => {
|
|
1992
|
-
return Object.assign(Object.assign({}, state), { rtcManagerInitialized: true });
|
|
1993
|
-
},
|
|
1994
|
-
},
|
|
1995
|
-
extraReducers: (builder) => {
|
|
1996
|
-
builder.addCase(socketReconnecting, (state) => {
|
|
1997
|
-
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1998
|
-
});
|
|
1999
|
-
builder.addCase(signalEvents.roomJoined, (state) => {
|
|
2000
|
-
return Object.assign(Object.assign({}, state), { status: state.status === "reconnecting" ? "ready" : state.status });
|
|
2001
|
-
});
|
|
2002
2174
|
},
|
|
2003
2175
|
});
|
|
2004
|
-
const {
|
|
2005
|
-
const
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2176
|
+
const { connectionMonitorStarted, connectionMonitorStopped } = connectionMonitorSlice.actions;
|
|
2177
|
+
const doStartConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2178
|
+
media.setClientProvider(() => {
|
|
2179
|
+
const state = getState();
|
|
2180
|
+
const clientViews = selectAllClientViews(state).map((clientView) => {
|
|
2181
|
+
var _a, _b;
|
|
2182
|
+
return ({
|
|
2183
|
+
id: clientView.id,
|
|
2184
|
+
clientId: clientView.clientId,
|
|
2185
|
+
isLocalClient: clientView.isLocalClient,
|
|
2186
|
+
audio: {
|
|
2187
|
+
enabled: clientView.isAudioEnabled,
|
|
2188
|
+
track: (_a = clientView.stream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0],
|
|
2189
|
+
},
|
|
2190
|
+
video: {
|
|
2191
|
+
enabled: clientView.isVideoEnabled,
|
|
2192
|
+
track: (_b = clientView.stream) === null || _b === void 0 ? void 0 : _b.getVideoTracks()[0],
|
|
2193
|
+
},
|
|
2194
|
+
isPresentation: clientView.isPresentation,
|
|
2195
|
+
});
|
|
2196
|
+
});
|
|
2197
|
+
return clientViews;
|
|
2198
|
+
});
|
|
2199
|
+
const issueMonitorSubscription = media.subscribeIssues({
|
|
2200
|
+
onUpdatedIssues: (issuesAndMetricsByClients) => {
|
|
2201
|
+
var _a;
|
|
2202
|
+
const state = getState();
|
|
2203
|
+
const rtcManager = selectRtcManager(state);
|
|
2204
|
+
if (!rtcManager) {
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
let lossSend = 0;
|
|
2208
|
+
let lossReceive = 0;
|
|
2209
|
+
let bitrateSend = 0;
|
|
2210
|
+
let bitrateReceive = 0;
|
|
2211
|
+
Object.entries(issuesAndMetricsByClients.aggregated.metrics).forEach(([key, value]) => {
|
|
2212
|
+
if (/loc.*packetloss/.test(key))
|
|
2213
|
+
lossSend = Math.max(lossSend, value.curMax);
|
|
2214
|
+
if (/rem.*packetloss/.test(key))
|
|
2215
|
+
lossReceive = Math.max(lossReceive, value.curMax);
|
|
2216
|
+
if (/loc.*bitrate/.test(key))
|
|
2217
|
+
bitrateSend += value.curSum;
|
|
2218
|
+
if (/rem.*bitrate/.test(key))
|
|
2219
|
+
bitrateReceive += value.curSum;
|
|
2220
|
+
});
|
|
2221
|
+
rtcManager.sendStatsCustomEvent("insightsStats", {
|
|
2222
|
+
ls: Math.round(lossSend * 1000) / 1000,
|
|
2223
|
+
lr: Math.round(lossReceive * 1000) / 1000,
|
|
2224
|
+
bs: Math.round(bitrateSend),
|
|
2225
|
+
br: Math.round(bitrateReceive),
|
|
2226
|
+
cpu: (_a = issuesAndMetricsByClients.aggregated.metrics["global-cpu-pressure"]) === null || _a === void 0 ? void 0 : _a.curSum,
|
|
2227
|
+
_time: Date.now(),
|
|
2228
|
+
});
|
|
2038
2229
|
},
|
|
2039
2230
|
});
|
|
2040
|
-
dispatch(
|
|
2041
|
-
});
|
|
2042
|
-
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
2043
|
-
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
2044
|
-
if (rtcManager) {
|
|
2045
|
-
rtcManager.disconnectAll();
|
|
2046
|
-
}
|
|
2047
|
-
dispatch(rtcDisconnected());
|
|
2231
|
+
dispatch(connectionMonitorStarted({ stopIssueSubscription: issueMonitorSubscription.stop }));
|
|
2048
2232
|
});
|
|
2049
|
-
const
|
|
2050
|
-
var _a;
|
|
2051
|
-
dispatch(isAcceptingStreams(true));
|
|
2233
|
+
const doStopConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2052
2234
|
const state = getState();
|
|
2053
|
-
const
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
throw new Error("No rtc manager");
|
|
2057
|
-
}
|
|
2058
|
-
const activeBreakout = false;
|
|
2059
|
-
const shouldAcceptNewClients = (_a = rtcManager.shouldAcceptStreamsFromBothSides) === null || _a === void 0 ? void 0 : _a.call(rtcManager);
|
|
2060
|
-
const updates = [];
|
|
2061
|
-
for (const { clientId, streamId, state } of payload) {
|
|
2062
|
-
const participant = remoteClients.find((p) => p.id === clientId);
|
|
2063
|
-
if (!participant)
|
|
2064
|
-
continue;
|
|
2065
|
-
if (state === "to_accept" ||
|
|
2066
|
-
(state === "new_accept" && shouldAcceptNewClients) ||
|
|
2067
|
-
(state === "old_accept" && !shouldAcceptNewClients)) {
|
|
2068
|
-
const enforceTurnProtocol = participant.isDialIn ? "onlytls" : undefined;
|
|
2069
|
-
rtcManager.acceptNewStream({
|
|
2070
|
-
streamId: streamId === "0" ? clientId : streamId,
|
|
2071
|
-
clientId,
|
|
2072
|
-
shouldAddLocalVideo: streamId === "0",
|
|
2073
|
-
activeBreakout,
|
|
2074
|
-
enforceTurnProtocol,
|
|
2075
|
-
});
|
|
2076
|
-
}
|
|
2077
|
-
else if (state === "new_accept" || state === "old_accept") ;
|
|
2078
|
-
else if (state === "to_unaccept") {
|
|
2079
|
-
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.disconnect(streamId === "0" ? clientId : streamId, activeBreakout);
|
|
2080
|
-
}
|
|
2081
|
-
else if (state !== "done_accept") {
|
|
2082
|
-
continue;
|
|
2083
|
-
}
|
|
2084
|
-
else ;
|
|
2085
|
-
updates.push({ clientId, streamId, state: state.replace(/to_|new_|old_/, "done_") });
|
|
2235
|
+
const stopCallbackFn = selectStopCallbackFunction(state);
|
|
2236
|
+
if (stopCallbackFn) {
|
|
2237
|
+
stopCallbackFn();
|
|
2086
2238
|
}
|
|
2087
|
-
dispatch(
|
|
2088
|
-
dispatch(isAcceptingStreams(false));
|
|
2239
|
+
dispatch(connectionMonitorStopped());
|
|
2089
2240
|
});
|
|
2090
|
-
const
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
if (!
|
|
2094
|
-
return;
|
|
2095
|
-
}
|
|
2096
|
-
const old = reportedStreamResolutions[streamId];
|
|
2097
|
-
if (!old || old.width !== width || old.height !== height) {
|
|
2098
|
-
rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
|
|
2241
|
+
const selectConnectionMonitorIsRunning = (state) => state.connectionMonitor.running;
|
|
2242
|
+
const selectStopCallbackFunction = (state) => state.connectionMonitor.stopCallbackFunction;
|
|
2243
|
+
const selectShouldStartConnectionMonitor = toolkit.createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2244
|
+
if (!isRunning && roomConnectionStatus === "connected") {
|
|
2245
|
+
return true;
|
|
2099
2246
|
}
|
|
2100
|
-
|
|
2101
|
-
});
|
|
2102
|
-
const doRtcManagerCreated = createAppThunk((payload) => (dispatch) => {
|
|
2103
|
-
const { rtcManager } = payload;
|
|
2104
|
-
dispatch(rtcManagerCreated(rtcManager));
|
|
2247
|
+
return false;
|
|
2105
2248
|
});
|
|
2106
|
-
const
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2249
|
+
const selectShouldStopConnectionMonitor = toolkit.createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2250
|
+
if (isRunning && ["kicked", "left"].includes(roomConnectionStatus)) {
|
|
2251
|
+
return true;
|
|
2252
|
+
}
|
|
2253
|
+
return false;
|
|
2254
|
+
});
|
|
2255
|
+
createReactor([selectShouldStartConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2256
|
+
if (shouldStartConnectionMonitor) {
|
|
2257
|
+
dispatch(doStartConnectionMonitor());
|
|
2113
2258
|
}
|
|
2114
|
-
dispatch(rtcManagerInitialized());
|
|
2115
2259
|
});
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
const
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2260
|
+
createReactor([selectShouldStopConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2261
|
+
if (shouldStartConnectionMonitor) {
|
|
2262
|
+
dispatch(doStopConnectionMonitor());
|
|
2263
|
+
}
|
|
2264
|
+
});
|
|
2265
|
+
|
|
2266
|
+
const emitter = new events$1.EventEmitter();
|
|
2267
|
+
function createNotificationEvent(payload) {
|
|
2268
|
+
const notificationEvent = Object.assign(Object.assign({}, payload), { timestamp: Date.now() });
|
|
2269
|
+
return notificationEvent;
|
|
2270
|
+
}
|
|
2271
|
+
const initialNotificationsState = {
|
|
2272
|
+
emitter,
|
|
2273
|
+
events: [],
|
|
2274
|
+
};
|
|
2275
|
+
const notificationsSlice = toolkit.createSlice({
|
|
2276
|
+
name: "notifications",
|
|
2277
|
+
initialState: initialNotificationsState,
|
|
2278
|
+
reducers: {
|
|
2279
|
+
addNotification: (state, action) => {
|
|
2280
|
+
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
2281
|
+
},
|
|
2282
|
+
doClearNotifications: (state) => {
|
|
2283
|
+
return Object.assign(Object.assign({}, state), { events: [] });
|
|
2284
|
+
},
|
|
2136
2285
|
},
|
|
2137
2286
|
});
|
|
2287
|
+
const { doClearNotifications } = notificationsSlice.actions;
|
|
2288
|
+
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
2289
|
+
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
2290
|
+
const state = getState();
|
|
2291
|
+
const emitter = selectNotificationsEmitter(state);
|
|
2292
|
+
emitter.emit(payload.type, payload);
|
|
2293
|
+
emitter.emit("*", payload);
|
|
2294
|
+
});
|
|
2295
|
+
const selectNotificationsRaw = (state) => state.notifications;
|
|
2296
|
+
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
2297
|
+
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
2138
2298
|
startAppListening({
|
|
2139
|
-
actionCreator:
|
|
2140
|
-
effect: ({ payload }, { getState }) => {
|
|
2141
|
-
const
|
|
2142
|
-
const {
|
|
2143
|
-
|
|
2299
|
+
actionCreator: signalEvents.chatMessage,
|
|
2300
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2301
|
+
const state = getState();
|
|
2302
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === payload.senderId);
|
|
2303
|
+
if (!client) {
|
|
2304
|
+
console.warn("Could not find remote client that sent chat message");
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2308
|
+
type: "chatMessageReceived",
|
|
2309
|
+
message: `${client.displayName} says: ${payload.text}`,
|
|
2310
|
+
props: {
|
|
2311
|
+
client,
|
|
2312
|
+
chatMessage: {
|
|
2313
|
+
senderId: payload.senderId,
|
|
2314
|
+
timestamp: payload.timestamp,
|
|
2315
|
+
text: payload.text,
|
|
2316
|
+
},
|
|
2317
|
+
},
|
|
2318
|
+
})));
|
|
2144
2319
|
},
|
|
2145
2320
|
});
|
|
2146
2321
|
startAppListening({
|
|
2147
|
-
actionCreator:
|
|
2148
|
-
effect: (
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2322
|
+
actionCreator: signalEvents.audioEnableRequested,
|
|
2323
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2324
|
+
const { enable, requestedByClientId } = payload;
|
|
2325
|
+
const state = getState();
|
|
2326
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === requestedByClientId);
|
|
2327
|
+
if (!client) {
|
|
2328
|
+
console.warn("Could not find remote client that requested a local audio change");
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2331
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2332
|
+
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
2333
|
+
message: enable
|
|
2334
|
+
? `${client.displayName} has requested for you to speak`
|
|
2335
|
+
: `${client.displayName} has muted your microphone`,
|
|
2336
|
+
props: {
|
|
2337
|
+
client,
|
|
2338
|
+
enable,
|
|
2339
|
+
},
|
|
2340
|
+
})));
|
|
2151
2341
|
},
|
|
2152
2342
|
});
|
|
2153
2343
|
startAppListening({
|
|
2154
|
-
actionCreator:
|
|
2155
|
-
effect: ({ payload }, { getState }) => {
|
|
2156
|
-
const {
|
|
2157
|
-
const
|
|
2158
|
-
|
|
2344
|
+
actionCreator: signalEvents.videoEnableRequested,
|
|
2345
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2346
|
+
const { enable, requestedByClientId } = payload;
|
|
2347
|
+
const state = getState();
|
|
2348
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === requestedByClientId);
|
|
2349
|
+
if (!client) {
|
|
2350
|
+
console.warn("Could not find remote client that requested a local video change");
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2354
|
+
type: enable ? "requestVideoEnable" : "requestVideoDisable",
|
|
2355
|
+
message: enable
|
|
2356
|
+
? `${client.displayName} has requested for you to start video`
|
|
2357
|
+
: `${client.displayName} has stopped your video`,
|
|
2358
|
+
props: {
|
|
2359
|
+
client,
|
|
2360
|
+
enable,
|
|
2361
|
+
},
|
|
2362
|
+
})));
|
|
2159
2363
|
},
|
|
2160
2364
|
});
|
|
2161
2365
|
startAppListening({
|
|
2162
|
-
actionCreator:
|
|
2163
|
-
effect: ({
|
|
2366
|
+
actionCreator: signalEvents.clientMetadataReceived,
|
|
2367
|
+
effect: (action, { dispatch, getOriginalState, getState }) => {
|
|
2164
2368
|
var _a;
|
|
2165
|
-
const
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2369
|
+
const { error, payload } = action.payload;
|
|
2370
|
+
if (error || !payload) {
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
const { clientId, stickyReaction } = payload;
|
|
2374
|
+
const state = getState();
|
|
2375
|
+
const canAskToSpeak = selectIsAuthorizedToAskToSpeak(state);
|
|
2376
|
+
if (!canAskToSpeak) {
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
2380
|
+
if (!client) {
|
|
2381
|
+
console.warn("Could not find remote client that provided updated metadata");
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2384
|
+
const previousState = getOriginalState();
|
|
2385
|
+
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
2386
|
+
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
2387
|
+
(stickyReaction === null || stickyReaction === void 0 ? void 0 : stickyReaction.timestamp) === ((_a = previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction) === null || _a === void 0 ? void 0 : _a.timestamp)) {
|
|
2388
|
+
return;
|
|
2175
2389
|
}
|
|
2390
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2391
|
+
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
2392
|
+
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
2393
|
+
props: {
|
|
2394
|
+
client,
|
|
2395
|
+
stickyReaction,
|
|
2396
|
+
},
|
|
2397
|
+
})));
|
|
2176
2398
|
},
|
|
2177
2399
|
});
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
});
|
|
2184
|
-
createReactor([selectShouldConnectRtc], ({ dispatch }, shouldConnectRtc) => {
|
|
2185
|
-
if (shouldConnectRtc) {
|
|
2186
|
-
dispatch(doConnectRtc());
|
|
2187
|
-
}
|
|
2188
|
-
});
|
|
2189
|
-
const selectShouldInitializeRtc = toolkit.createSelector(selectRtcManager, selectRtcManagerInitialized, selectLocalMediaStatus, (rtcManager, rtcManagerInitialized, localMediaStatus) => {
|
|
2190
|
-
if (localMediaStatus === "started" && rtcManager && !rtcManagerInitialized) {
|
|
2191
|
-
return true;
|
|
2192
|
-
}
|
|
2193
|
-
return false;
|
|
2194
|
-
});
|
|
2195
|
-
createReactor([selectShouldInitializeRtc], ({ dispatch }, shouldInitializeRtc) => {
|
|
2196
|
-
if (shouldInitializeRtc) {
|
|
2197
|
-
dispatch(doRtcManagerInitialize());
|
|
2400
|
+
createReactor([selectSignalStatus], ({ dispatch, getState }, signalStatus) => {
|
|
2401
|
+
const state = getState();
|
|
2402
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
2403
|
+
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
2404
|
+
return;
|
|
2198
2405
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2406
|
+
if (signalStatus === "disconnected") {
|
|
2407
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2408
|
+
type: "signalTrouble",
|
|
2409
|
+
message: `Network connection lost. Trying to reconnect you...`,
|
|
2410
|
+
props: {},
|
|
2411
|
+
})));
|
|
2203
2412
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2413
|
+
else if (signalStatus === "connected") {
|
|
2414
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2415
|
+
type: "signalOk",
|
|
2416
|
+
message: `Network connection available`,
|
|
2417
|
+
props: {},
|
|
2418
|
+
})));
|
|
2209
2419
|
}
|
|
2210
2420
|
});
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
if ((streams === null || streams === void 0 ? void 0 : streams.length) > 1 && streams[1].id === "0") {
|
|
2222
|
-
if (i === 0) {
|
|
2223
|
-
streamId = streams[1].id;
|
|
2224
|
-
state = streams[1].state;
|
|
2225
|
-
}
|
|
2226
|
-
else if (i === 1) {
|
|
2227
|
-
streamId = streams[0].id;
|
|
2228
|
-
state = streams[0].state;
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
{
|
|
2232
|
-
if (state === "done_accept")
|
|
2233
|
-
continue;
|
|
2234
|
-
upd.push({
|
|
2235
|
-
clientId,
|
|
2236
|
-
streamId,
|
|
2237
|
-
state: `${newJoiner && streamId === "0" ? "new" : "to"}_accept`,
|
|
2238
|
-
});
|
|
2239
|
-
}
|
|
2421
|
+
startAppListening({
|
|
2422
|
+
actionCreator: signalEvents.clientUnableToJoin,
|
|
2423
|
+
effect: (action, { dispatch }) => {
|
|
2424
|
+
var _a;
|
|
2425
|
+
if (((_a = action.payload) === null || _a === void 0 ? void 0 : _a.error) === "room_full") {
|
|
2426
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2427
|
+
type: "clientUnableToJoinFullRoom",
|
|
2428
|
+
message: "Someone tried to join but the room is full and at capacity.",
|
|
2429
|
+
props: {},
|
|
2430
|
+
})));
|
|
2240
2431
|
}
|
|
2241
|
-
}
|
|
2242
|
-
return upd;
|
|
2243
|
-
});
|
|
2244
|
-
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
2245
|
-
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
2246
|
-
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
2247
|
-
}
|
|
2432
|
+
},
|
|
2248
2433
|
});
|
|
2249
2434
|
|
|
2250
2435
|
const rtcAnalyticsCustomEvents = {
|
|
@@ -2285,7 +2470,7 @@ const rtcAnalyticsCustomEvents = {
|
|
|
2285
2470
|
getOutput: () => ({}),
|
|
2286
2471
|
},
|
|
2287
2472
|
displayName: {
|
|
2288
|
-
actions: [
|
|
2473
|
+
actions: [setDisplayName],
|
|
2289
2474
|
rtcEventName: "displayName",
|
|
2290
2475
|
getValue: (state) => selectAppDisplayName(state),
|
|
2291
2476
|
getOutput: (value) => ({ displayName: value }),
|
|
@@ -2586,7 +2771,7 @@ const waitingParticipantsSlice = toolkit.createSlice({
|
|
|
2586
2771
|
});
|
|
2587
2772
|
},
|
|
2588
2773
|
});
|
|
2589
|
-
const doAcceptWaitingParticipant =
|
|
2774
|
+
const doAcceptWaitingParticipant = createRoomConnectedThunk((payload) => (dispatch, getState) => {
|
|
2590
2775
|
const { participantId } = payload;
|
|
2591
2776
|
const state = getState();
|
|
2592
2777
|
const socket = selectSignalConnectionSocket(state);
|
|
@@ -2596,7 +2781,7 @@ const doAcceptWaitingParticipant = createAppThunk((payload) => (dispatch, getSta
|
|
|
2596
2781
|
response: {},
|
|
2597
2782
|
});
|
|
2598
2783
|
});
|
|
2599
|
-
const doRejectWaitingParticipant =
|
|
2784
|
+
const doRejectWaitingParticipant = createRoomConnectedThunk((payload) => (dispatch, getState) => {
|
|
2600
2785
|
const { participantId } = payload;
|
|
2601
2786
|
const state = getState();
|
|
2602
2787
|
const socket = selectSignalConnectionSocket(state);
|
|
@@ -2616,6 +2801,7 @@ const appReducer = toolkit.combineReducers({
|
|
|
2616
2801
|
authorization: authorizationSlice.reducer,
|
|
2617
2802
|
chat: chatSlice.reducer,
|
|
2618
2803
|
cloudRecording: cloudRecordingSlice.reducer,
|
|
2804
|
+
connectionMonitor: connectionMonitorSlice.reducer,
|
|
2619
2805
|
deviceCredentials: deviceCredentialsSlice.reducer,
|
|
2620
2806
|
localMedia: localMediaSlice.reducer,
|
|
2621
2807
|
localParticipant: localParticipantSlice.reducer,
|
|
@@ -3693,10 +3879,16 @@ exports.appSlice = appSlice;
|
|
|
3693
3879
|
exports.authorizationSlice = authorizationSlice;
|
|
3694
3880
|
exports.chatSlice = chatSlice;
|
|
3695
3881
|
exports.cloudRecordingSlice = cloudRecordingSlice;
|
|
3882
|
+
exports.connectionMonitorSlice = connectionMonitorSlice;
|
|
3883
|
+
exports.connectionMonitorStarted = connectionMonitorStarted;
|
|
3884
|
+
exports.connectionMonitorStopped = connectionMonitorStopped;
|
|
3696
3885
|
exports.createAppAsyncThunk = createAppAsyncThunk;
|
|
3697
3886
|
exports.createAppAuthorizedThunk = createAppAuthorizedThunk;
|
|
3698
3887
|
exports.createAppThunk = createAppThunk;
|
|
3888
|
+
exports.createAsyncRoomConnectedThunk = createAsyncRoomConnectedThunk;
|
|
3889
|
+
exports.createAuthorizedRoomConnectedThunk = createAuthorizedRoomConnectedThunk;
|
|
3699
3890
|
exports.createReactor = createReactor;
|
|
3891
|
+
exports.createRoomConnectedThunk = createRoomConnectedThunk;
|
|
3700
3892
|
exports.createServices = createServices;
|
|
3701
3893
|
exports.createStore = createStore;
|
|
3702
3894
|
exports.createWebRtcEmitter = createWebRtcEmitter;
|
|
@@ -3726,6 +3918,7 @@ exports.doOrganizationFetch = doOrganizationFetch;
|
|
|
3726
3918
|
exports.doRejectWaitingParticipant = doRejectWaitingParticipant;
|
|
3727
3919
|
exports.doRemoveSpotlight = doRemoveSpotlight;
|
|
3728
3920
|
exports.doRequestAudioEnable = doRequestAudioEnable;
|
|
3921
|
+
exports.doRequestVideoEnable = doRequestVideoEnable;
|
|
3729
3922
|
exports.doRtcAnalyticsCustomEventsInitialize = doRtcAnalyticsCustomEventsInitialize;
|
|
3730
3923
|
exports.doRtcManagerCreated = doRtcManagerCreated;
|
|
3731
3924
|
exports.doRtcManagerInitialize = doRtcManagerInitialize;
|
|
@@ -3741,9 +3934,11 @@ exports.doSignalDisconnect = doSignalDisconnect;
|
|
|
3741
3934
|
exports.doSignalIdentifyDevice = doSignalIdentifyDevice;
|
|
3742
3935
|
exports.doSpotlightParticipant = doSpotlightParticipant;
|
|
3743
3936
|
exports.doStartCloudRecording = doStartCloudRecording;
|
|
3937
|
+
exports.doStartConnectionMonitor = doStartConnectionMonitor;
|
|
3744
3938
|
exports.doStartLocalMedia = doStartLocalMedia;
|
|
3745
3939
|
exports.doStartScreenshare = doStartScreenshare;
|
|
3746
3940
|
exports.doStopCloudRecording = doStopCloudRecording;
|
|
3941
|
+
exports.doStopConnectionMonitor = doStopConnectionMonitor;
|
|
3747
3942
|
exports.doStopLocalMedia = doStopLocalMedia;
|
|
3748
3943
|
exports.doStopScreenshare = doStopScreenshare;
|
|
3749
3944
|
exports.doSwitchLocalStream = doSwitchLocalStream;
|
|
@@ -3757,7 +3952,7 @@ exports.hasValue = hasValue;
|
|
|
3757
3952
|
exports.initialCloudRecordingState = initialCloudRecordingState;
|
|
3758
3953
|
exports.initialLocalMediaState = initialLocalMediaState;
|
|
3759
3954
|
exports.initialNotificationsState = initialNotificationsState;
|
|
3760
|
-
exports.initialState = initialState$
|
|
3955
|
+
exports.initialState = initialState$g;
|
|
3761
3956
|
exports.isAcceptingStreams = isAcceptingStreams;
|
|
3762
3957
|
exports.isClientSpotlighted = isClientSpotlighted;
|
|
3763
3958
|
exports.listenerMiddleware = listenerMiddleware;
|
|
@@ -3809,6 +4004,7 @@ exports.selectCloudRecordingError = selectCloudRecordingError;
|
|
|
3809
4004
|
exports.selectCloudRecordingRaw = selectCloudRecordingRaw;
|
|
3810
4005
|
exports.selectCloudRecordingStartedAt = selectCloudRecordingStartedAt;
|
|
3811
4006
|
exports.selectCloudRecordingStatus = selectCloudRecordingStatus;
|
|
4007
|
+
exports.selectConnectionMonitorIsRunning = selectConnectionMonitorIsRunning;
|
|
3812
4008
|
exports.selectCurrentCameraDeviceId = selectCurrentCameraDeviceId;
|
|
3813
4009
|
exports.selectCurrentMicrophoneDeviceId = selectCurrentMicrophoneDeviceId;
|
|
3814
4010
|
exports.selectCurrentSpeakerDeviceId = selectCurrentSpeakerDeviceId;
|
|
@@ -3821,6 +4017,7 @@ exports.selectIsAuthorizedToEndMeeting = selectIsAuthorizedToEndMeeting;
|
|
|
3821
4017
|
exports.selectIsAuthorizedToKickClient = selectIsAuthorizedToKickClient;
|
|
3822
4018
|
exports.selectIsAuthorizedToLockRoom = selectIsAuthorizedToLockRoom;
|
|
3823
4019
|
exports.selectIsAuthorizedToRequestAudioEnable = selectIsAuthorizedToRequestAudioEnable;
|
|
4020
|
+
exports.selectIsAuthorizedToRequestVideoEnable = selectIsAuthorizedToRequestVideoEnable;
|
|
3824
4021
|
exports.selectIsAuthorizedToSpotlight = selectIsAuthorizedToSpotlight;
|
|
3825
4022
|
exports.selectIsCameraEnabled = selectIsCameraEnabled;
|
|
3826
4023
|
exports.selectIsCloudRecording = selectIsCloudRecording;
|
|
@@ -3887,6 +4084,8 @@ exports.selectShouldFetchDeviceCredentials = selectShouldFetchDeviceCredentials;
|
|
|
3887
4084
|
exports.selectShouldFetchOrganization = selectShouldFetchOrganization;
|
|
3888
4085
|
exports.selectShouldIdentifyDevice = selectShouldIdentifyDevice;
|
|
3889
4086
|
exports.selectShouldInitializeRtc = selectShouldInitializeRtc;
|
|
4087
|
+
exports.selectShouldStartConnectionMonitor = selectShouldStartConnectionMonitor;
|
|
4088
|
+
exports.selectShouldStopConnectionMonitor = selectShouldStopConnectionMonitor;
|
|
3890
4089
|
exports.selectSignalConnectionDeviceIdentified = selectSignalConnectionDeviceIdentified;
|
|
3891
4090
|
exports.selectSignalConnectionRaw = selectSignalConnectionRaw;
|
|
3892
4091
|
exports.selectSignalConnectionSocket = selectSignalConnectionSocket;
|
|
@@ -3896,6 +4095,7 @@ exports.selectSpeakerDevices = selectSpeakerDevices;
|
|
|
3896
4095
|
exports.selectSpotlightedClientViews = selectSpotlightedClientViews;
|
|
3897
4096
|
exports.selectSpotlights = selectSpotlights;
|
|
3898
4097
|
exports.selectSpotlightsRaw = selectSpotlightsRaw;
|
|
4098
|
+
exports.selectStopCallbackFunction = selectStopCallbackFunction;
|
|
3899
4099
|
exports.selectStreamingRaw = selectStreamingRaw;
|
|
3900
4100
|
exports.selectStreamsToAccept = selectStreamsToAccept;
|
|
3901
4101
|
exports.selectWaitingParticipants = selectWaitingParticipants;
|
|
@@ -3903,6 +4103,7 @@ exports.selectWaitingParticipantsRaw = selectWaitingParticipantsRaw;
|
|
|
3903
4103
|
exports.setCurrentCameraDeviceId = setCurrentCameraDeviceId;
|
|
3904
4104
|
exports.setCurrentMicrophoneDeviceId = setCurrentMicrophoneDeviceId;
|
|
3905
4105
|
exports.setCurrentSpeakerDeviceId = setCurrentSpeakerDeviceId;
|
|
4106
|
+
exports.setDisplayName = setDisplayName;
|
|
3906
4107
|
exports.setLocalMediaOptions = setLocalMediaOptions;
|
|
3907
4108
|
exports.setLocalMediaStream = setLocalMediaStream;
|
|
3908
4109
|
exports.setRoomKey = setRoomKey;
|