@whereby.com/core 0.25.0 → 0.26.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 +757 -642
- package/dist/index.d.cts +323 -104
- package/dist/index.d.mts +323 -104
- package/dist/index.d.ts +323 -104
- package/dist/index.mjs +749 -643
- 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
|
|
|
@@ -45,9 +45,9 @@ const createReactor = (selectors, callback) => {
|
|
|
45
45
|
});
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const coreVersion = "0.
|
|
48
|
+
const coreVersion = "0.26.0";
|
|
49
49
|
|
|
50
|
-
const initialState$
|
|
50
|
+
const initialState$g = {
|
|
51
51
|
isNodeSdk: false,
|
|
52
52
|
isActive: false,
|
|
53
53
|
isDialIn: false,
|
|
@@ -59,7 +59,7 @@ const initialState$f = {
|
|
|
59
59
|
};
|
|
60
60
|
const appSlice = toolkit.createSlice({
|
|
61
61
|
name: "app",
|
|
62
|
-
initialState: initialState$
|
|
62
|
+
initialState: initialState$g,
|
|
63
63
|
reducers: {
|
|
64
64
|
doAppStart: (state, action) => {
|
|
65
65
|
const url = new URL(action.payload.roomUrl);
|
|
@@ -122,13 +122,13 @@ const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
|
|
|
122
122
|
canAskToSpeak: ["host"],
|
|
123
123
|
canSpotlight: ["host"],
|
|
124
124
|
};
|
|
125
|
-
const initialState$
|
|
125
|
+
const initialState$f = {
|
|
126
126
|
roomKey: null,
|
|
127
127
|
roleName: "none",
|
|
128
128
|
};
|
|
129
129
|
const authorizationSlice = toolkit.createSlice({
|
|
130
130
|
name: "authorization",
|
|
131
|
-
initialState: initialState$
|
|
131
|
+
initialState: initialState$f,
|
|
132
132
|
reducers: {
|
|
133
133
|
setRoomKey: (state, action) => {
|
|
134
134
|
return Object.assign(Object.assign({}, state), { roomKey: action.payload });
|
|
@@ -199,13 +199,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
199
199
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
200
200
|
};
|
|
201
201
|
|
|
202
|
-
const initialState$
|
|
202
|
+
const initialState$e = {
|
|
203
203
|
isFetching: false,
|
|
204
204
|
data: null,
|
|
205
205
|
};
|
|
206
206
|
const deviceCredentialsSlice = toolkit.createSlice({
|
|
207
207
|
name: "deviceCredentials",
|
|
208
|
-
initialState: initialState$
|
|
208
|
+
initialState: initialState$e,
|
|
209
209
|
reducers: {},
|
|
210
210
|
extraReducers: (builder) => {
|
|
211
211
|
builder.addCase(doGetDeviceCredentials.pending, (state) => {
|
|
@@ -280,7 +280,7 @@ function createSocket() {
|
|
|
280
280
|
};
|
|
281
281
|
return new media.ServerSocket(socketHost, socketOverrides);
|
|
282
282
|
}
|
|
283
|
-
const initialState$
|
|
283
|
+
const initialState$d = {
|
|
284
284
|
deviceIdentified: false,
|
|
285
285
|
isIdentifyingDevice: false,
|
|
286
286
|
status: "ready",
|
|
@@ -288,7 +288,7 @@ const initialState$c = {
|
|
|
288
288
|
};
|
|
289
289
|
const signalConnectionSlice = toolkit.createSlice({
|
|
290
290
|
name: "signalConnection",
|
|
291
|
-
initialState: initialState$
|
|
291
|
+
initialState: initialState$d,
|
|
292
292
|
reducers: {
|
|
293
293
|
socketConnecting: (state) => {
|
|
294
294
|
return Object.assign(Object.assign({}, state), { status: "connecting" });
|
|
@@ -297,7 +297,7 @@ const signalConnectionSlice = toolkit.createSlice({
|
|
|
297
297
|
return Object.assign(Object.assign({}, state), { socket: action.payload, status: "connected" });
|
|
298
298
|
},
|
|
299
299
|
socketDisconnected: (state) => {
|
|
300
|
-
return Object.assign(Object.assign({}, state), { deviceIdentified: false, status: "disconnected" });
|
|
300
|
+
return Object.assign(Object.assign({}, state), { socket: null, deviceIdentified: false, status: "disconnected" });
|
|
301
301
|
},
|
|
302
302
|
socketReconnecting: (state) => {
|
|
303
303
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
@@ -392,12 +392,12 @@ startAppListening({
|
|
|
392
392
|
},
|
|
393
393
|
});
|
|
394
394
|
|
|
395
|
-
const initialState$
|
|
395
|
+
const initialState$c = {
|
|
396
396
|
chatMessages: [],
|
|
397
397
|
};
|
|
398
398
|
const chatSlice = toolkit.createSlice({
|
|
399
399
|
name: "chat",
|
|
400
|
-
initialState: initialState$
|
|
400
|
+
initialState: initialState$c,
|
|
401
401
|
reducers: {},
|
|
402
402
|
extraReducers(builder) {
|
|
403
403
|
builder.addCase(signalEvents.chatMessage, (state, action) => {
|
|
@@ -478,6 +478,60 @@ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
|
|
|
478
478
|
const selectCloudRecordingError = (state) => state.cloudRecording.error;
|
|
479
479
|
const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
|
|
480
480
|
|
|
481
|
+
const initialState$b = {
|
|
482
|
+
data: null,
|
|
483
|
+
isFetching: false,
|
|
484
|
+
error: null,
|
|
485
|
+
};
|
|
486
|
+
const organizationSlice = toolkit.createSlice({
|
|
487
|
+
initialState: initialState$b,
|
|
488
|
+
name: "organization",
|
|
489
|
+
reducers: {},
|
|
490
|
+
extraReducers: (builder) => {
|
|
491
|
+
builder.addCase(doOrganizationFetch.pending, (state) => {
|
|
492
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
493
|
+
});
|
|
494
|
+
builder.addCase(doOrganizationFetch.fulfilled, (state, action) => {
|
|
495
|
+
if (!action.payload)
|
|
496
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
497
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
498
|
+
});
|
|
499
|
+
builder.addCase(doOrganizationFetch.rejected, (state) => {
|
|
500
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, error: true });
|
|
501
|
+
});
|
|
502
|
+
},
|
|
503
|
+
});
|
|
504
|
+
const doOrganizationFetch = createAppAsyncThunk("organization/doOrganizationFetch", (_, { extra, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
505
|
+
try {
|
|
506
|
+
const roomUrl = selectAppRoomUrl(getState());
|
|
507
|
+
const organization = yield extra.services.fetchOrganizationFromRoomUrl(roomUrl || "");
|
|
508
|
+
if (!organization) {
|
|
509
|
+
throw new Error("Invalid room url");
|
|
510
|
+
}
|
|
511
|
+
return organization;
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
console.error(error);
|
|
515
|
+
}
|
|
516
|
+
}));
|
|
517
|
+
const selectOrganizationRaw = (state) => state.organization;
|
|
518
|
+
const selectOrganizationId = (state) => { var _a; return (_a = state.organization.data) === null || _a === void 0 ? void 0 : _a.organizationId; };
|
|
519
|
+
const selectShouldFetchOrganization = toolkit.createSelector(selectAppIsActive, selectOrganizationRaw, selectDeviceCredentialsRaw, (appIsActive, organization, deviceCredentials) => {
|
|
520
|
+
if (appIsActive &&
|
|
521
|
+
!organization.data &&
|
|
522
|
+
!organization.isFetching &&
|
|
523
|
+
!organization.error &&
|
|
524
|
+
!deviceCredentials.isFetching) {
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
return false;
|
|
528
|
+
});
|
|
529
|
+
createReactor([selectShouldFetchOrganization], ({ dispatch }, shouldFetchOrganization) => {
|
|
530
|
+
if (shouldFetchOrganization) {
|
|
531
|
+
dispatch(doOrganizationFetch());
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
|
|
481
535
|
function fakeAudioStream() {
|
|
482
536
|
const audioCtx = new AudioContext();
|
|
483
537
|
const oscillator = audioCtx.createOscillator();
|
|
@@ -1183,82 +1237,175 @@ createReactor([selectLocalParticipantDisplayName, selectLocalParticipantStickyRe
|
|
|
1183
1237
|
});
|
|
1184
1238
|
|
|
1185
1239
|
const initialState$9 = {
|
|
1186
|
-
|
|
1187
|
-
|
|
1240
|
+
session: null,
|
|
1241
|
+
status: "ready",
|
|
1188
1242
|
error: null,
|
|
1189
1243
|
};
|
|
1190
|
-
const
|
|
1191
|
-
name: "localScreenshare",
|
|
1244
|
+
const roomConnectionSlice = toolkit.createSlice({
|
|
1192
1245
|
initialState: initialState$9,
|
|
1246
|
+
name: "roomConnection",
|
|
1193
1247
|
reducers: {
|
|
1194
|
-
|
|
1195
|
-
return Object.assign(Object.assign({}, state), { status:
|
|
1248
|
+
connectionStatusChanged: (state, action) => {
|
|
1249
|
+
return Object.assign(Object.assign({}, state), { status: action.payload });
|
|
1196
1250
|
},
|
|
1197
1251
|
},
|
|
1198
1252
|
extraReducers: (builder) => {
|
|
1199
|
-
builder.addCase(
|
|
1200
|
-
|
|
1253
|
+
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1254
|
+
var _a, _b;
|
|
1255
|
+
const { error, isLocked } = action.payload;
|
|
1256
|
+
if (error === "room_locked" && isLocked) {
|
|
1257
|
+
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
1258
|
+
}
|
|
1259
|
+
if (error) {
|
|
1260
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected", error });
|
|
1261
|
+
}
|
|
1262
|
+
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
1263
|
});
|
|
1202
|
-
builder.addCase(
|
|
1203
|
-
|
|
1264
|
+
builder.addCase(signalEvents.disconnect, (state) => {
|
|
1265
|
+
if (["kicked", "left"].includes(state.status)) {
|
|
1266
|
+
return Object.assign({}, state);
|
|
1267
|
+
}
|
|
1268
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected" });
|
|
1204
1269
|
});
|
|
1205
|
-
builder.addCase(
|
|
1206
|
-
|
|
1270
|
+
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
1271
|
+
var _a, _b;
|
|
1272
|
+
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 });
|
|
1273
|
+
});
|
|
1274
|
+
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
1275
|
+
var _a;
|
|
1276
|
+
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
1277
|
+
return state;
|
|
1278
|
+
}
|
|
1279
|
+
return Object.assign(Object.assign({}, state), { session: null });
|
|
1280
|
+
});
|
|
1281
|
+
builder.addCase(signalEvents.clientKicked, (state) => {
|
|
1282
|
+
return Object.assign(Object.assign({}, state), { status: "kicked" });
|
|
1283
|
+
});
|
|
1284
|
+
builder.addCase(signalEvents.roomLeft, (state) => {
|
|
1285
|
+
return Object.assign(Object.assign({}, state), { status: "left" });
|
|
1286
|
+
});
|
|
1287
|
+
builder.addCase(socketReconnecting, (state) => {
|
|
1288
|
+
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1207
1289
|
});
|
|
1208
1290
|
},
|
|
1209
1291
|
});
|
|
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) => {
|
|
1292
|
+
const { connectionStatusChanged } = roomConnectionSlice.actions;
|
|
1293
|
+
const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1236
1294
|
const state = getState();
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
|
|
1295
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1296
|
+
const roomName = selectAppRoomName(state);
|
|
1297
|
+
const roomKey = selectRoomKey(state);
|
|
1298
|
+
const displayName = selectAppDisplayName(state);
|
|
1299
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1300
|
+
const userAgent = selectAppUserAgent(state);
|
|
1301
|
+
const externalId = selectAppExternalId(state);
|
|
1302
|
+
const organizationId = selectOrganizationId(state);
|
|
1303
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("knock_room", {
|
|
1304
|
+
avatarUrl: null,
|
|
1305
|
+
config: {
|
|
1306
|
+
isAudioEnabled: true,
|
|
1307
|
+
isVideoEnabled: true,
|
|
1308
|
+
},
|
|
1309
|
+
deviceCapabilities: { canScreenshare: true },
|
|
1310
|
+
displayName,
|
|
1311
|
+
isCoLocated: false,
|
|
1312
|
+
isDialIn,
|
|
1313
|
+
isDevicePermissionDenied: false,
|
|
1314
|
+
kickFromOtherRooms: false,
|
|
1315
|
+
organizationId,
|
|
1316
|
+
roomKey,
|
|
1317
|
+
roomName,
|
|
1318
|
+
userAgent,
|
|
1319
|
+
externalId,
|
|
1320
|
+
});
|
|
1321
|
+
dispatch(connectionStatusChanged("knocking"));
|
|
1322
|
+
});
|
|
1323
|
+
const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1324
|
+
const state = getState();
|
|
1325
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1326
|
+
const roomName = selectAppRoomName(state);
|
|
1327
|
+
const roomKey = selectRoomKey(state);
|
|
1328
|
+
const displayName = selectAppDisplayName(state);
|
|
1329
|
+
const userAgent = selectAppUserAgent(state);
|
|
1330
|
+
const externalId = selectAppExternalId(state);
|
|
1331
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1332
|
+
const organizationId = selectOrganizationId(state);
|
|
1333
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1334
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1335
|
+
const clientClaim = selectLocalParticipantClientClaim(getState());
|
|
1336
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
|
|
1337
|
+
isAudioEnabled: isMicrophoneEnabled,
|
|
1338
|
+
isVideoEnabled: isCameraEnabled,
|
|
1339
|
+
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDialIn, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1340
|
+
roomKey,
|
|
1341
|
+
roomName,
|
|
1342
|
+
userAgent,
|
|
1343
|
+
externalId }, (clientClaim && { clientClaim })));
|
|
1344
|
+
dispatch(connectionStatusChanged("connecting"));
|
|
1345
|
+
});
|
|
1346
|
+
const selectRoomConnectionRaw = (state) => state.roomConnection;
|
|
1347
|
+
const selectRoomConnectionSession = (state) => state.roomConnection.session;
|
|
1348
|
+
const selectRoomConnectionSessionId = (state) => { var _a; return (_a = state.roomConnection.session) === null || _a === void 0 ? void 0 : _a.id; };
|
|
1349
|
+
const selectRoomConnectionStatus = (state) => state.roomConnection.status;
|
|
1350
|
+
const selectRoomConnectionError = (state) => state.roomConnection.error;
|
|
1351
|
+
const selectShouldConnectRoom = toolkit.createSelector([
|
|
1352
|
+
selectAppIsActive,
|
|
1353
|
+
selectOrganizationId,
|
|
1354
|
+
selectRoomConnectionStatus,
|
|
1355
|
+
selectSignalConnectionDeviceIdentified,
|
|
1356
|
+
selectLocalMediaStatus,
|
|
1357
|
+
selectRoomConnectionError,
|
|
1358
|
+
], (appIsActive, hasOrganizationIdFetched, roomConnectionStatus, signalConnectionDeviceIdentified, localMediaStatus, roomConnectionError) => {
|
|
1359
|
+
if (appIsActive &&
|
|
1360
|
+
localMediaStatus === "started" &&
|
|
1361
|
+
signalConnectionDeviceIdentified &&
|
|
1362
|
+
!!hasOrganizationIdFetched &&
|
|
1363
|
+
["ready", "reconnecting", "disconnected"].includes(roomConnectionStatus) &&
|
|
1364
|
+
!roomConnectionError) {
|
|
1365
|
+
return true;
|
|
1366
|
+
}
|
|
1367
|
+
return false;
|
|
1368
|
+
});
|
|
1369
|
+
createReactor([selectShouldConnectRoom], ({ dispatch }, shouldConnectRoom) => {
|
|
1370
|
+
if (shouldConnectRoom) {
|
|
1371
|
+
dispatch(doConnectRoom());
|
|
1240
1372
|
}
|
|
1241
|
-
screenshareStream.getTracks().forEach((track) => track.stop());
|
|
1242
|
-
dispatch(stopScreenshare({ stream: screenshareStream }));
|
|
1243
1373
|
});
|
|
1244
|
-
const selectLocalScreenshareRaw = (state) => state.localScreenshare;
|
|
1245
|
-
const selectLocalScreenshareStatus = (state) => state.localScreenshare.status;
|
|
1246
|
-
const selectLocalScreenshareStream = (state) => state.localScreenshare.stream;
|
|
1247
1374
|
startAppListening({
|
|
1248
|
-
actionCreator:
|
|
1249
|
-
effect: (
|
|
1375
|
+
actionCreator: signalEvents.knockHandled,
|
|
1376
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
1377
|
+
const { clientId, resolution } = payload;
|
|
1250
1378
|
const state = getState();
|
|
1251
|
-
const
|
|
1252
|
-
if (
|
|
1379
|
+
const selfId = selectSelfId(state);
|
|
1380
|
+
if (clientId !== selfId) {
|
|
1253
1381
|
return;
|
|
1254
1382
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1383
|
+
if (resolution === "accepted") {
|
|
1384
|
+
dispatch(setRoomKey(payload.metadata.roomKey));
|
|
1385
|
+
dispatch(doConnectRoom());
|
|
1386
|
+
}
|
|
1387
|
+
else if (resolution === "rejected") {
|
|
1388
|
+
dispatch(connectionStatusChanged("knock_rejected"));
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
});
|
|
1392
|
+
startAppListening({
|
|
1393
|
+
actionCreator: doAppStop,
|
|
1394
|
+
effect: (_, { dispatch, getState }) => {
|
|
1395
|
+
const state = getState();
|
|
1396
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
1397
|
+
if (roomConnectionStatus === "connected") {
|
|
1398
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1399
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("leave_room");
|
|
1400
|
+
dispatch(connectionStatusChanged("leaving"));
|
|
1401
|
+
}
|
|
1402
|
+
else {
|
|
1403
|
+
doSignalDisconnect();
|
|
1404
|
+
}
|
|
1405
|
+
},
|
|
1406
|
+
});
|
|
1407
|
+
|
|
1408
|
+
function createRtcEventAction(name) {
|
|
1262
1409
|
return toolkit.createAction(`rtcConnection/event/${name}`);
|
|
1263
1410
|
}
|
|
1264
1411
|
const rtcEvents = {
|
|
@@ -1460,373 +1607,388 @@ const selectNumParticipants = toolkit.createSelector(selectRemoteParticipants, s
|
|
|
1460
1607
|
});
|
|
1461
1608
|
|
|
1462
1609
|
const initialState$7 = {
|
|
1463
|
-
|
|
1464
|
-
|
|
1610
|
+
status: "inactive",
|
|
1611
|
+
stream: null,
|
|
1465
1612
|
error: null,
|
|
1466
1613
|
};
|
|
1467
|
-
const
|
|
1614
|
+
const localScreenshareSlice = toolkit.createSlice({
|
|
1615
|
+
name: "localScreenshare",
|
|
1468
1616
|
initialState: initialState$7,
|
|
1469
|
-
|
|
1470
|
-
|
|
1617
|
+
reducers: {
|
|
1618
|
+
stopScreenshare(state, action) {
|
|
1619
|
+
return Object.assign(Object.assign({}, state), { status: "inactive", stream: null });
|
|
1620
|
+
},
|
|
1621
|
+
},
|
|
1471
1622
|
extraReducers: (builder) => {
|
|
1472
|
-
builder.addCase(
|
|
1473
|
-
return Object.assign(Object.assign({}, state), {
|
|
1623
|
+
builder.addCase(doStartScreenshare.pending, (state) => {
|
|
1624
|
+
return Object.assign(Object.assign({}, state), { status: "starting" });
|
|
1474
1625
|
});
|
|
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 });
|
|
1626
|
+
builder.addCase(doStartScreenshare.fulfilled, (state, { payload: { stream } }) => {
|
|
1627
|
+
return Object.assign(Object.assign({}, state), { status: "active", stream });
|
|
1479
1628
|
});
|
|
1480
|
-
builder.addCase(
|
|
1481
|
-
return Object.assign(Object.assign({}, state), {
|
|
1629
|
+
builder.addCase(doStartScreenshare.rejected, (state, { payload }) => {
|
|
1630
|
+
return Object.assign(Object.assign({}, state), { error: payload, status: "inactive", stream: null });
|
|
1482
1631
|
});
|
|
1483
1632
|
},
|
|
1484
1633
|
});
|
|
1485
|
-
const
|
|
1634
|
+
const { stopScreenshare } = localScreenshareSlice.actions;
|
|
1635
|
+
const doStartScreenshare = createAppAsyncThunk("localScreenshare/doStartScreenshare", (_, { dispatch, getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1636
|
+
var _a;
|
|
1486
1637
|
try {
|
|
1487
|
-
const
|
|
1488
|
-
const
|
|
1489
|
-
if (
|
|
1490
|
-
|
|
1638
|
+
const state = getState();
|
|
1639
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1640
|
+
if (screenshareStream) {
|
|
1641
|
+
return { stream: screenshareStream };
|
|
1491
1642
|
}
|
|
1492
|
-
|
|
1643
|
+
const stream = yield navigator.mediaDevices.getDisplayMedia();
|
|
1644
|
+
const onEnded = () => {
|
|
1645
|
+
dispatch(doStopScreenshare());
|
|
1646
|
+
};
|
|
1647
|
+
if ("oninactive" in stream) {
|
|
1648
|
+
stream.addEventListener("inactive", onEnded);
|
|
1649
|
+
}
|
|
1650
|
+
else {
|
|
1651
|
+
(_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.addEventListener("ended", onEnded);
|
|
1652
|
+
}
|
|
1653
|
+
return { stream };
|
|
1493
1654
|
}
|
|
1494
1655
|
catch (error) {
|
|
1495
|
-
|
|
1656
|
+
return rejectWithValue(error);
|
|
1496
1657
|
}
|
|
1497
1658
|
}));
|
|
1498
|
-
const
|
|
1499
|
-
const
|
|
1500
|
-
const
|
|
1501
|
-
if (
|
|
1502
|
-
|
|
1503
|
-
!organization.isFetching &&
|
|
1504
|
-
!organization.error &&
|
|
1505
|
-
!deviceCredentials.isFetching) {
|
|
1506
|
-
return true;
|
|
1659
|
+
const doStopScreenshare = createAppThunk(() => (dispatch, getState) => {
|
|
1660
|
+
const state = getState();
|
|
1661
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1662
|
+
if (!screenshareStream) {
|
|
1663
|
+
return;
|
|
1507
1664
|
}
|
|
1508
|
-
|
|
1665
|
+
screenshareStream.getTracks().forEach((track) => track.stop());
|
|
1666
|
+
dispatch(stopScreenshare({ stream: screenshareStream }));
|
|
1509
1667
|
});
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1668
|
+
const selectLocalScreenshareRaw = (state) => state.localScreenshare;
|
|
1669
|
+
const selectLocalScreenshareStatus = (state) => state.localScreenshare.status;
|
|
1670
|
+
const selectLocalScreenshareStream = (state) => state.localScreenshare.stream;
|
|
1671
|
+
startAppListening({
|
|
1672
|
+
actionCreator: localMediaStopped,
|
|
1673
|
+
effect: (_, { getState }) => {
|
|
1674
|
+
const state = getState();
|
|
1675
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1676
|
+
if (!screenshareStream) {
|
|
1677
|
+
return;
|
|
1678
|
+
}
|
|
1679
|
+
screenshareStream === null || screenshareStream === void 0 ? void 0 : screenshareStream.getTracks().forEach((track) => {
|
|
1680
|
+
track.stop();
|
|
1681
|
+
});
|
|
1682
|
+
},
|
|
1514
1683
|
});
|
|
1515
1684
|
|
|
1685
|
+
const createWebRtcEmitter = (dispatch) => {
|
|
1686
|
+
return {
|
|
1687
|
+
emit: (eventName, data) => {
|
|
1688
|
+
if (eventName === "rtc_manager_created") {
|
|
1689
|
+
dispatch(doRtcManagerCreated(data));
|
|
1690
|
+
}
|
|
1691
|
+
else if (eventName === "stream_added") {
|
|
1692
|
+
dispatch(rtcEvents.streamAdded(data));
|
|
1693
|
+
}
|
|
1694
|
+
else if (eventName === "rtc_manager_destroyed") {
|
|
1695
|
+
dispatch(rtcManagerDestroyed());
|
|
1696
|
+
}
|
|
1697
|
+
else ;
|
|
1698
|
+
},
|
|
1699
|
+
};
|
|
1700
|
+
};
|
|
1516
1701
|
const initialState$6 = {
|
|
1517
|
-
|
|
1518
|
-
status: "ready",
|
|
1702
|
+
dispatcherCreated: false,
|
|
1519
1703
|
error: null,
|
|
1704
|
+
isCreatingDispatcher: false,
|
|
1705
|
+
reportedStreamResolutions: {},
|
|
1706
|
+
rtcManager: null,
|
|
1707
|
+
rtcManagerDispatcher: null,
|
|
1708
|
+
rtcManagerInitialized: false,
|
|
1709
|
+
status: "inactive",
|
|
1710
|
+
isAcceptingStreams: false,
|
|
1520
1711
|
};
|
|
1521
|
-
const
|
|
1712
|
+
const rtcConnectionSlice = toolkit.createSlice({
|
|
1713
|
+
name: "rtcConnection",
|
|
1522
1714
|
initialState: initialState$6,
|
|
1523
|
-
name: "roomConnection",
|
|
1524
1715
|
reducers: {
|
|
1525
|
-
|
|
1526
|
-
return Object.assign(Object.assign({}, state), {
|
|
1716
|
+
isAcceptingStreams: (state, action) => {
|
|
1717
|
+
return Object.assign(Object.assign({}, state), { isAcceptingStreams: action.payload });
|
|
1718
|
+
},
|
|
1719
|
+
resolutionReported: (state, action) => {
|
|
1720
|
+
const { streamId, width, height } = action.payload;
|
|
1721
|
+
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
1722
|
+
},
|
|
1723
|
+
rtcDisconnected: () => {
|
|
1724
|
+
return Object.assign({}, initialState$6);
|
|
1725
|
+
},
|
|
1726
|
+
rtcDispatcherCreated: (state, action) => {
|
|
1727
|
+
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
1728
|
+
},
|
|
1729
|
+
rtcManagerCreated: (state, action) => {
|
|
1730
|
+
return Object.assign(Object.assign({}, state), { rtcManager: action.payload, status: "ready" });
|
|
1731
|
+
},
|
|
1732
|
+
rtcManagerDestroyed: (state) => {
|
|
1733
|
+
return Object.assign(Object.assign({}, state), { rtcManager: null });
|
|
1734
|
+
},
|
|
1735
|
+
rtcManagerInitialized: (state) => {
|
|
1736
|
+
return Object.assign(Object.assign({}, state), { rtcManagerInitialized: true });
|
|
1527
1737
|
},
|
|
1528
1738
|
},
|
|
1529
1739
|
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
1740
|
builder.addCase(socketReconnecting, (state) => {
|
|
1565
1741
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1566
1742
|
});
|
|
1743
|
+
builder.addCase(signalEvents.roomJoined, (state) => {
|
|
1744
|
+
return Object.assign(Object.assign({}, state), { status: state.status === "reconnecting" ? "ready" : state.status });
|
|
1745
|
+
});
|
|
1567
1746
|
},
|
|
1568
1747
|
});
|
|
1569
|
-
const {
|
|
1570
|
-
const
|
|
1748
|
+
const { resolutionReported, rtcDispatcherCreated, rtcDisconnected, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, isAcceptingStreams, } = rtcConnectionSlice.actions;
|
|
1749
|
+
const doConnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1571
1750
|
const state = getState();
|
|
1572
1751
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1573
|
-
const
|
|
1574
|
-
const
|
|
1575
|
-
const
|
|
1576
|
-
const
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1752
|
+
const dispatcher = selectRtcConnectionRaw(state).rtcManagerDispatcher;
|
|
1753
|
+
const isCameraEnabled = selectIsCameraEnabled(state);
|
|
1754
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(state);
|
|
1755
|
+
const isNodeSdk = selectAppIsNodeSdk(state);
|
|
1756
|
+
if (dispatcher || !socket) {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
const webrtcProvider = {
|
|
1760
|
+
getMediaConstraints: () => ({
|
|
1761
|
+
audio: isMicrophoneEnabled,
|
|
1762
|
+
video: isCameraEnabled,
|
|
1763
|
+
}),
|
|
1764
|
+
deferrable(clientId) {
|
|
1765
|
+
return !clientId;
|
|
1585
1766
|
},
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
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"));
|
|
1767
|
+
};
|
|
1768
|
+
const rtcManagerDispatcher = new media.RtcManagerDispatcher({
|
|
1769
|
+
emitter: createWebRtcEmitter(dispatch),
|
|
1770
|
+
serverSocket: socket,
|
|
1771
|
+
webrtcProvider,
|
|
1772
|
+
features: {
|
|
1773
|
+
isNodeSdk,
|
|
1774
|
+
lowDataModeEnabled: false,
|
|
1775
|
+
sfuServerOverrideHost: undefined,
|
|
1776
|
+
turnServerOverrideHost: undefined,
|
|
1777
|
+
useOnlyTURN: undefined,
|
|
1778
|
+
vp9On: false,
|
|
1779
|
+
h264On: false,
|
|
1780
|
+
simulcastScreenshareOn: false,
|
|
1781
|
+
deviceHandlerFactory: isNodeSdk ? Chrome111_js.Chrome111.createFactory() : undefined,
|
|
1782
|
+
},
|
|
1783
|
+
});
|
|
1784
|
+
dispatch(rtcDispatcherCreated(rtcManagerDispatcher));
|
|
1622
1785
|
});
|
|
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;
|
|
1786
|
+
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1787
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1788
|
+
if (rtcManager) {
|
|
1789
|
+
rtcManager.disconnectAll();
|
|
1643
1790
|
}
|
|
1644
|
-
|
|
1791
|
+
dispatch(rtcDisconnected());
|
|
1645
1792
|
});
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1793
|
+
const doHandleAcceptStreams = createAppThunk((payload) => (dispatch, getState) => {
|
|
1794
|
+
var _a;
|
|
1795
|
+
dispatch(isAcceptingStreams(true));
|
|
1796
|
+
const state = getState();
|
|
1797
|
+
const rtcManager = selectRtcConnectionRaw(state).rtcManager;
|
|
1798
|
+
const remoteClients = selectRemoteClients(state);
|
|
1799
|
+
if (!rtcManager) {
|
|
1800
|
+
throw new Error("No rtc manager");
|
|
1649
1801
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
const
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
if (
|
|
1658
|
-
|
|
1802
|
+
const activeBreakout = false;
|
|
1803
|
+
const shouldAcceptNewClients = (_a = rtcManager.shouldAcceptStreamsFromBothSides) === null || _a === void 0 ? void 0 : _a.call(rtcManager);
|
|
1804
|
+
const updates = [];
|
|
1805
|
+
for (const { clientId, streamId, state } of payload) {
|
|
1806
|
+
const participant = remoteClients.find((p) => p.id === clientId);
|
|
1807
|
+
if (!participant)
|
|
1808
|
+
continue;
|
|
1809
|
+
if (state === "to_accept" ||
|
|
1810
|
+
(state === "new_accept" && shouldAcceptNewClients) ||
|
|
1811
|
+
(state === "old_accept" && !shouldAcceptNewClients)) {
|
|
1812
|
+
const enforceTurnProtocol = participant.isDialIn ? "onlytls" : undefined;
|
|
1813
|
+
rtcManager.acceptNewStream({
|
|
1814
|
+
streamId: streamId === "0" ? clientId : streamId,
|
|
1815
|
+
clientId,
|
|
1816
|
+
shouldAddLocalVideo: streamId === "0",
|
|
1817
|
+
activeBreakout,
|
|
1818
|
+
enforceTurnProtocol,
|
|
1819
|
+
});
|
|
1659
1820
|
}
|
|
1660
|
-
if (
|
|
1661
|
-
|
|
1662
|
-
|
|
1821
|
+
else if (state === "new_accept" || state === "old_accept") ;
|
|
1822
|
+
else if (state === "to_unaccept") {
|
|
1823
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.disconnect(streamId === "0" ? clientId : streamId, activeBreakout);
|
|
1663
1824
|
}
|
|
1664
|
-
else if (
|
|
1665
|
-
|
|
1825
|
+
else if (state !== "done_accept") {
|
|
1826
|
+
continue;
|
|
1666
1827
|
}
|
|
1667
|
-
|
|
1828
|
+
else ;
|
|
1829
|
+
updates.push({ clientId, streamId, state: state.replace(/to_|new_|old_/, "done_") });
|
|
1830
|
+
}
|
|
1831
|
+
dispatch(streamStatusUpdated(updates));
|
|
1832
|
+
dispatch(isAcceptingStreams(false));
|
|
1833
|
+
});
|
|
1834
|
+
const doRtcReportStreamResolution = createAppThunk(({ streamId, width, height }) => (dispatch, getState) => {
|
|
1835
|
+
const { reportedStreamResolutions, rtcManager } = selectRtcConnectionRaw(getState());
|
|
1836
|
+
const localStream = selectLocalMediaStream(getState());
|
|
1837
|
+
if (!rtcManager || (localStream === null || localStream === void 0 ? void 0 : localStream.id) === streamId) {
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
const old = reportedStreamResolutions[streamId];
|
|
1841
|
+
if (!old || old.width !== width || old.height !== height) {
|
|
1842
|
+
rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
|
|
1843
|
+
}
|
|
1844
|
+
dispatch(resolutionReported({ streamId, width, height }));
|
|
1845
|
+
});
|
|
1846
|
+
const doRtcManagerCreated = createAppThunk((payload) => (dispatch) => {
|
|
1847
|
+
const { rtcManager } = payload;
|
|
1848
|
+
dispatch(rtcManagerCreated(rtcManager));
|
|
1849
|
+
});
|
|
1850
|
+
const doRtcManagerInitialize = createAppThunk(() => (dispatch, getState) => {
|
|
1851
|
+
const localMediaStream = selectLocalMediaStream(getState());
|
|
1852
|
+
const rtcManager = selectRtcConnectionRaw(getState()).rtcManager;
|
|
1853
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1854
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1855
|
+
if (localMediaStream && rtcManager) {
|
|
1856
|
+
rtcManager.addNewStream("0", localMediaStream, !isMicrophoneEnabled, !isCameraEnabled);
|
|
1857
|
+
}
|
|
1858
|
+
dispatch(rtcManagerInitialized());
|
|
1668
1859
|
});
|
|
1860
|
+
const selectRtcConnectionRaw = (state) => state.rtcConnection;
|
|
1861
|
+
const selectRtcManagerInitialized = (state) => state.rtcConnection.rtcManagerInitialized;
|
|
1862
|
+
const selectRtcManager = (state) => state.rtcConnection.rtcManager;
|
|
1863
|
+
const selectRtcDispatcherCreated = (state) => state.rtcConnection.dispatcherCreated;
|
|
1864
|
+
const selectRtcIsCreatingDispatcher = (state) => state.rtcConnection.isCreatingDispatcher;
|
|
1865
|
+
const selectRtcStatus = (state) => state.rtcConnection.status;
|
|
1866
|
+
const selectIsAcceptingStreams = (state) => state.rtcConnection.isAcceptingStreams;
|
|
1669
1867
|
startAppListening({
|
|
1670
|
-
actionCreator:
|
|
1671
|
-
effect: (
|
|
1672
|
-
const
|
|
1673
|
-
const
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
}
|
|
1868
|
+
actionCreator: doSetDevice.fulfilled,
|
|
1869
|
+
effect: ({ payload }, { getState }) => {
|
|
1870
|
+
const { replacedTracks } = payload;
|
|
1871
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1872
|
+
const stream = selectLocalMediaStream(getState());
|
|
1873
|
+
const replace = (kind, oldTrack) => {
|
|
1874
|
+
const track = stream === null || stream === void 0 ? void 0 : stream.getTracks().find((t) => t.kind === kind);
|
|
1875
|
+
return track && (rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.replaceTrack(oldTrack, track));
|
|
1876
|
+
};
|
|
1877
|
+
replacedTracks === null || replacedTracks === void 0 ? void 0 : replacedTracks.forEach((t) => {
|
|
1878
|
+
replace(t.kind, t);
|
|
1879
|
+
});
|
|
1682
1880
|
},
|
|
1683
1881
|
});
|
|
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
|
-
},
|
|
1882
|
+
startAppListening({
|
|
1883
|
+
actionCreator: doStartScreenshare.fulfilled,
|
|
1884
|
+
effect: ({ payload }, { getState }) => {
|
|
1885
|
+
const { stream } = payload;
|
|
1886
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1887
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.addNewStream(stream.id, stream, false, true);
|
|
1704
1888
|
},
|
|
1705
1889
|
});
|
|
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
1890
|
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
|
-
})));
|
|
1891
|
+
actionCreator: doAppStop,
|
|
1892
|
+
effect: (_, { getState }) => {
|
|
1893
|
+
const rtcManager = selectRtcManager(getState());
|
|
1894
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.rtcStatsDisconnect();
|
|
1738
1895
|
},
|
|
1739
1896
|
});
|
|
1740
1897
|
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
|
-
})));
|
|
1898
|
+
actionCreator: stopScreenshare,
|
|
1899
|
+
effect: ({ payload }, { getState }) => {
|
|
1900
|
+
const { stream } = payload;
|
|
1901
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1902
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.removeStream(stream.id, stream, null);
|
|
1760
1903
|
},
|
|
1761
1904
|
});
|
|
1762
1905
|
startAppListening({
|
|
1763
|
-
actionCreator:
|
|
1764
|
-
effect: (
|
|
1906
|
+
actionCreator: doSwitchLocalStream.fulfilled,
|
|
1907
|
+
effect: ({ payload }, { getState }) => {
|
|
1765
1908
|
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;
|
|
1909
|
+
const stream = selectLocalMediaStream(getState());
|
|
1910
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1911
|
+
if (stream && rtcManager) {
|
|
1912
|
+
const replace = (kind, oldTrack) => {
|
|
1913
|
+
const track = stream.getTracks().find((t) => t.kind === kind);
|
|
1914
|
+
return track && rtcManager.replaceTrack(oldTrack, track);
|
|
1915
|
+
};
|
|
1916
|
+
(_a = payload === null || payload === void 0 ? void 0 : payload.replacedTracks) === null || _a === void 0 ? void 0 : _a.forEach((t) => {
|
|
1917
|
+
replace(t.kind, t);
|
|
1918
|
+
});
|
|
1786
1919
|
}
|
|
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
1920
|
},
|
|
1796
1921
|
});
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
1801
|
-
return;
|
|
1922
|
+
const selectShouldConnectRtc = toolkit.createSelector(selectRtcStatus, selectAppIsActive, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectSignalConnectionSocket, (rtcStatus, appIsActive, dispatcherCreated, isCreatingDispatcher, signalSocket) => {
|
|
1923
|
+
if (appIsActive && rtcStatus === "inactive" && !dispatcherCreated && !isCreatingDispatcher && signalSocket) {
|
|
1924
|
+
return true;
|
|
1802
1925
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
})));
|
|
1926
|
+
return false;
|
|
1927
|
+
});
|
|
1928
|
+
createReactor([selectShouldConnectRtc], ({ dispatch }, shouldConnectRtc) => {
|
|
1929
|
+
if (shouldConnectRtc) {
|
|
1930
|
+
dispatch(doConnectRtc());
|
|
1809
1931
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
props: {},
|
|
1815
|
-
})));
|
|
1932
|
+
});
|
|
1933
|
+
const selectShouldInitializeRtc = toolkit.createSelector(selectRtcManager, selectRtcManagerInitialized, selectLocalMediaStatus, (rtcManager, rtcManagerInitialized, localMediaStatus) => {
|
|
1934
|
+
if (localMediaStatus === "started" && rtcManager && !rtcManagerInitialized) {
|
|
1935
|
+
return true;
|
|
1816
1936
|
}
|
|
1937
|
+
return false;
|
|
1817
1938
|
});
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1939
|
+
createReactor([selectShouldInitializeRtc], ({ dispatch }, shouldInitializeRtc) => {
|
|
1940
|
+
if (shouldInitializeRtc) {
|
|
1941
|
+
dispatch(doRtcManagerInitialize());
|
|
1942
|
+
}
|
|
1943
|
+
});
|
|
1944
|
+
const selectShouldDisconnectRtc = toolkit.createSelector(selectRtcStatus, selectAppIsActive, (status, appIsActive) => {
|
|
1945
|
+
if (!appIsActive && !["inactive", "disconnected"].includes(status)) {
|
|
1946
|
+
return true;
|
|
1947
|
+
}
|
|
1948
|
+
return false;
|
|
1949
|
+
});
|
|
1950
|
+
createReactor([selectShouldDisconnectRtc], ({ dispatch }, shouldDisconnectRtc) => {
|
|
1951
|
+
if (shouldDisconnectRtc) {
|
|
1952
|
+
dispatch(doDisconnectRtc());
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1955
|
+
const selectStreamsToAccept = toolkit.createSelector(selectRtcStatus, selectRemoteClients, (rtcStatus, remoteParticipants) => {
|
|
1956
|
+
if (rtcStatus !== "ready") {
|
|
1957
|
+
return [];
|
|
1958
|
+
}
|
|
1959
|
+
const upd = [];
|
|
1960
|
+
for (const client of remoteParticipants) {
|
|
1961
|
+
const { streams, id: clientId, newJoiner } = client;
|
|
1962
|
+
for (let i = 0; i < streams.length; i++) {
|
|
1963
|
+
let streamId = streams[i].id;
|
|
1964
|
+
let state = streams[i].state;
|
|
1965
|
+
if ((streams === null || streams === void 0 ? void 0 : streams.length) > 1 && streams[1].id === "0") {
|
|
1966
|
+
if (i === 0) {
|
|
1967
|
+
streamId = streams[1].id;
|
|
1968
|
+
state = streams[1].state;
|
|
1969
|
+
}
|
|
1970
|
+
else if (i === 1) {
|
|
1971
|
+
streamId = streams[0].id;
|
|
1972
|
+
state = streams[0].state;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
{
|
|
1976
|
+
if (state === "done_accept")
|
|
1977
|
+
continue;
|
|
1978
|
+
upd.push({
|
|
1979
|
+
clientId,
|
|
1980
|
+
streamId,
|
|
1981
|
+
state: `${newJoiner && streamId === "0" ? "new" : "to"}_accept`,
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1828
1984
|
}
|
|
1829
|
-
}
|
|
1985
|
+
}
|
|
1986
|
+
return upd;
|
|
1987
|
+
});
|
|
1988
|
+
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
1989
|
+
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
1990
|
+
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
1991
|
+
}
|
|
1830
1992
|
});
|
|
1831
1993
|
|
|
1832
1994
|
function isStreamerClient(client) {
|
|
@@ -1938,313 +2100,256 @@ const selectAllClientViews = toolkit.createSelector(selectLocalParticipantView,
|
|
|
1938
2100
|
return [...(localParticipant ? [localParticipant] : []), ...remoteParticipants];
|
|
1939
2101
|
});
|
|
1940
2102
|
|
|
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
2103
|
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,
|
|
2104
|
+
running: false,
|
|
1967
2105
|
};
|
|
1968
|
-
const
|
|
1969
|
-
name: "
|
|
2106
|
+
const connectionMonitorSlice = toolkit.createSlice({
|
|
2107
|
+
name: "connectionMonitor",
|
|
1970
2108
|
initialState: initialState$4,
|
|
1971
2109
|
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 } }) });
|
|
2110
|
+
connectionMonitorStarted: (state, action) => {
|
|
2111
|
+
return Object.assign(Object.assign({}, state), { running: true, stopCallbackFunction: action.payload.stopIssueSubscription });
|
|
1978
2112
|
},
|
|
1979
|
-
|
|
2113
|
+
connectionMonitorStopped: () => {
|
|
1980
2114
|
return Object.assign({}, initialState$4);
|
|
1981
2115
|
},
|
|
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
2116
|
},
|
|
2003
2117
|
});
|
|
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
|
-
|
|
2118
|
+
const { connectionMonitorStarted, connectionMonitorStopped } = connectionMonitorSlice.actions;
|
|
2119
|
+
const doStartConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2120
|
+
media.setClientProvider(() => {
|
|
2121
|
+
const state = getState();
|
|
2122
|
+
const clientViews = selectAllClientViews(state).map((clientView) => {
|
|
2123
|
+
var _a, _b;
|
|
2124
|
+
return ({
|
|
2125
|
+
id: clientView.id,
|
|
2126
|
+
clientId: clientView.clientId,
|
|
2127
|
+
isLocalClient: clientView.isLocalClient,
|
|
2128
|
+
audio: {
|
|
2129
|
+
enabled: clientView.isAudioEnabled,
|
|
2130
|
+
track: (_a = clientView.stream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0],
|
|
2131
|
+
},
|
|
2132
|
+
video: {
|
|
2133
|
+
enabled: clientView.isVideoEnabled,
|
|
2134
|
+
track: (_b = clientView.stream) === null || _b === void 0 ? void 0 : _b.getVideoTracks()[0],
|
|
2135
|
+
},
|
|
2136
|
+
isPresentation: clientView.isPresentation,
|
|
2137
|
+
});
|
|
2138
|
+
});
|
|
2139
|
+
return clientViews;
|
|
2140
|
+
});
|
|
2141
|
+
const issueMonitorSubscription = media.subscribeIssues({
|
|
2142
|
+
onUpdatedIssues: (issuesAndMetricsByClients) => {
|
|
2143
|
+
var _a;
|
|
2144
|
+
const state = getState();
|
|
2145
|
+
const rtcManager = selectRtcManager(state);
|
|
2146
|
+
if (!rtcManager) {
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
let lossSend = 0;
|
|
2150
|
+
let lossReceive = 0;
|
|
2151
|
+
let bitrateSend = 0;
|
|
2152
|
+
let bitrateReceive = 0;
|
|
2153
|
+
Object.entries(issuesAndMetricsByClients.aggregated.metrics).forEach(([key, value]) => {
|
|
2154
|
+
if (/loc.*packetloss/.test(key))
|
|
2155
|
+
lossSend = Math.max(lossSend, value.curMax);
|
|
2156
|
+
if (/rem.*packetloss/.test(key))
|
|
2157
|
+
lossReceive = Math.max(lossReceive, value.curMax);
|
|
2158
|
+
if (/loc.*bitrate/.test(key))
|
|
2159
|
+
bitrateSend += value.curSum;
|
|
2160
|
+
if (/rem.*bitrate/.test(key))
|
|
2161
|
+
bitrateReceive += value.curSum;
|
|
2162
|
+
});
|
|
2163
|
+
rtcManager.sendStatsCustomEvent("insightsStats", {
|
|
2164
|
+
ls: Math.round(lossSend * 1000) / 1000,
|
|
2165
|
+
lr: Math.round(lossReceive * 1000) / 1000,
|
|
2166
|
+
bs: Math.round(bitrateSend),
|
|
2167
|
+
br: Math.round(bitrateReceive),
|
|
2168
|
+
cpu: (_a = issuesAndMetricsByClients.aggregated.metrics["global-cpu-pressure"]) === null || _a === void 0 ? void 0 : _a.curSum,
|
|
2169
|
+
_time: Date.now(),
|
|
2170
|
+
});
|
|
2038
2171
|
},
|
|
2039
2172
|
});
|
|
2040
|
-
dispatch(
|
|
2041
|
-
});
|
|
2042
|
-
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
2043
|
-
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
2044
|
-
if (rtcManager) {
|
|
2045
|
-
rtcManager.disconnectAll();
|
|
2046
|
-
}
|
|
2047
|
-
dispatch(rtcDisconnected());
|
|
2173
|
+
dispatch(connectionMonitorStarted({ stopIssueSubscription: issueMonitorSubscription.stop }));
|
|
2048
2174
|
});
|
|
2049
|
-
const
|
|
2050
|
-
var _a;
|
|
2051
|
-
dispatch(isAcceptingStreams(true));
|
|
2175
|
+
const doStopConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2052
2176
|
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_") });
|
|
2177
|
+
const stopCallbackFn = selectStopCallbackFunction(state);
|
|
2178
|
+
if (stopCallbackFn) {
|
|
2179
|
+
stopCallbackFn();
|
|
2086
2180
|
}
|
|
2087
|
-
dispatch(
|
|
2088
|
-
dispatch(isAcceptingStreams(false));
|
|
2181
|
+
dispatch(connectionMonitorStopped());
|
|
2089
2182
|
});
|
|
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 });
|
|
2183
|
+
const selectConnectionMonitorIsRunning = (state) => state.connectionMonitor.running;
|
|
2184
|
+
const selectStopCallbackFunction = (state) => state.connectionMonitor.stopCallbackFunction;
|
|
2185
|
+
const selectShouldStartConnectionMonitor = toolkit.createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2186
|
+
if (!isRunning && roomConnectionStatus === "connected") {
|
|
2187
|
+
return true;
|
|
2099
2188
|
}
|
|
2100
|
-
|
|
2189
|
+
return false;
|
|
2101
2190
|
});
|
|
2102
|
-
const
|
|
2103
|
-
|
|
2104
|
-
|
|
2191
|
+
const selectShouldStopConnectionMonitor = toolkit.createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2192
|
+
if (isRunning && ["kicked", "left"].includes(roomConnectionStatus)) {
|
|
2193
|
+
return true;
|
|
2194
|
+
}
|
|
2195
|
+
return false;
|
|
2105
2196
|
});
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
2110
|
-
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
2111
|
-
if (localMediaStream && rtcManager) {
|
|
2112
|
-
rtcManager.addNewStream("0", localMediaStream, !isMicrophoneEnabled, !isCameraEnabled);
|
|
2197
|
+
createReactor([selectShouldStartConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2198
|
+
if (shouldStartConnectionMonitor) {
|
|
2199
|
+
dispatch(doStartConnectionMonitor());
|
|
2113
2200
|
}
|
|
2114
|
-
dispatch(rtcManagerInitialized());
|
|
2115
2201
|
});
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
const selectRtcIsCreatingDispatcher = (state) => state.rtcConnection.isCreatingDispatcher;
|
|
2121
|
-
const selectRtcStatus = (state) => state.rtcConnection.status;
|
|
2122
|
-
const selectIsAcceptingStreams = (state) => state.rtcConnection.isAcceptingStreams;
|
|
2123
|
-
startAppListening({
|
|
2124
|
-
actionCreator: doSetDevice.fulfilled,
|
|
2125
|
-
effect: ({ payload }, { getState }) => {
|
|
2126
|
-
const { replacedTracks } = payload;
|
|
2127
|
-
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
2128
|
-
const stream = selectLocalMediaStream(getState());
|
|
2129
|
-
const replace = (kind, oldTrack) => {
|
|
2130
|
-
const track = stream === null || stream === void 0 ? void 0 : stream.getTracks().find((t) => t.kind === kind);
|
|
2131
|
-
return track && (rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.replaceTrack(oldTrack, track));
|
|
2132
|
-
};
|
|
2133
|
-
replacedTracks === null || replacedTracks === void 0 ? void 0 : replacedTracks.forEach((t) => {
|
|
2134
|
-
replace(t.kind, t);
|
|
2135
|
-
});
|
|
2136
|
-
},
|
|
2202
|
+
createReactor([selectShouldStopConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2203
|
+
if (shouldStartConnectionMonitor) {
|
|
2204
|
+
dispatch(doStopConnectionMonitor());
|
|
2205
|
+
}
|
|
2137
2206
|
});
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2207
|
+
|
|
2208
|
+
const emitter = new events$1.EventEmitter();
|
|
2209
|
+
function createNotificationEvent(payload) {
|
|
2210
|
+
const notificationEvent = Object.assign(Object.assign({}, payload), { timestamp: Date.now() });
|
|
2211
|
+
return notificationEvent;
|
|
2212
|
+
}
|
|
2213
|
+
const initialNotificationsState = {
|
|
2214
|
+
emitter,
|
|
2215
|
+
events: [],
|
|
2216
|
+
};
|
|
2217
|
+
const notificationsSlice = toolkit.createSlice({
|
|
2218
|
+
name: "notifications",
|
|
2219
|
+
initialState: initialNotificationsState,
|
|
2220
|
+
reducers: {
|
|
2221
|
+
addNotification: (state, action) => {
|
|
2222
|
+
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
2223
|
+
},
|
|
2224
|
+
doClearNotifications: (state) => {
|
|
2225
|
+
return Object.assign(Object.assign({}, state), { events: [] });
|
|
2226
|
+
},
|
|
2144
2227
|
},
|
|
2145
2228
|
});
|
|
2229
|
+
const { doClearNotifications } = notificationsSlice.actions;
|
|
2230
|
+
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
2231
|
+
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
2232
|
+
const state = getState();
|
|
2233
|
+
const emitter = selectNotificationsEmitter(state);
|
|
2234
|
+
emitter.emit(payload.type, payload);
|
|
2235
|
+
emitter.emit("*", payload);
|
|
2236
|
+
});
|
|
2237
|
+
const selectNotificationsRaw = (state) => state.notifications;
|
|
2238
|
+
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
2239
|
+
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
2146
2240
|
startAppListening({
|
|
2147
|
-
actionCreator:
|
|
2148
|
-
effect: (
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2241
|
+
actionCreator: signalEvents.chatMessage,
|
|
2242
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2243
|
+
const state = getState();
|
|
2244
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === payload.senderId);
|
|
2245
|
+
if (!client) {
|
|
2246
|
+
console.warn("Could not find remote client that sent chat message");
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2250
|
+
type: "chatMessageReceived",
|
|
2251
|
+
message: `${client.displayName} says: ${payload.text}`,
|
|
2252
|
+
props: {
|
|
2253
|
+
client,
|
|
2254
|
+
chatMessage: {
|
|
2255
|
+
senderId: payload.senderId,
|
|
2256
|
+
timestamp: payload.timestamp,
|
|
2257
|
+
text: payload.text,
|
|
2258
|
+
},
|
|
2259
|
+
},
|
|
2260
|
+
})));
|
|
2151
2261
|
},
|
|
2152
2262
|
});
|
|
2153
2263
|
startAppListening({
|
|
2154
|
-
actionCreator:
|
|
2155
|
-
effect: ({ payload }, { getState }) => {
|
|
2156
|
-
const {
|
|
2157
|
-
const
|
|
2158
|
-
|
|
2264
|
+
actionCreator: signalEvents.audioEnableRequested,
|
|
2265
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2266
|
+
const { enable, requestedByClientId } = payload;
|
|
2267
|
+
const state = getState();
|
|
2268
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === requestedByClientId);
|
|
2269
|
+
if (!client) {
|
|
2270
|
+
console.warn("Could not find remote client that requested a local audio change");
|
|
2271
|
+
return;
|
|
2272
|
+
}
|
|
2273
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2274
|
+
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
2275
|
+
message: enable
|
|
2276
|
+
? `${client.displayName} has requested for you to speak`
|
|
2277
|
+
: `${client.displayName} has muted your microphone`,
|
|
2278
|
+
props: {
|
|
2279
|
+
client,
|
|
2280
|
+
enable,
|
|
2281
|
+
},
|
|
2282
|
+
})));
|
|
2159
2283
|
},
|
|
2160
2284
|
});
|
|
2161
2285
|
startAppListening({
|
|
2162
|
-
actionCreator:
|
|
2163
|
-
effect: ({
|
|
2286
|
+
actionCreator: signalEvents.clientMetadataReceived,
|
|
2287
|
+
effect: (action, { dispatch, getOriginalState, getState }) => {
|
|
2164
2288
|
var _a;
|
|
2165
|
-
const
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2289
|
+
const { error, payload } = action.payload;
|
|
2290
|
+
if (error || !payload) {
|
|
2291
|
+
return;
|
|
2292
|
+
}
|
|
2293
|
+
const { clientId, stickyReaction } = payload;
|
|
2294
|
+
const state = getState();
|
|
2295
|
+
const canAskToSpeak = selectIsAuthorizedToAskToSpeak(state);
|
|
2296
|
+
if (!canAskToSpeak) {
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
2300
|
+
if (!client) {
|
|
2301
|
+
console.warn("Could not find remote client that provided updated metadata");
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
const previousState = getOriginalState();
|
|
2305
|
+
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
2306
|
+
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
2307
|
+
(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)) {
|
|
2308
|
+
return;
|
|
2175
2309
|
}
|
|
2310
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2311
|
+
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
2312
|
+
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
2313
|
+
props: {
|
|
2314
|
+
client,
|
|
2315
|
+
stickyReaction,
|
|
2316
|
+
},
|
|
2317
|
+
})));
|
|
2176
2318
|
},
|
|
2177
2319
|
});
|
|
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());
|
|
2320
|
+
createReactor([selectSignalStatus], ({ dispatch, getState }, signalStatus) => {
|
|
2321
|
+
const state = getState();
|
|
2322
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
2323
|
+
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
2324
|
+
return;
|
|
2198
2325
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2326
|
+
if (signalStatus === "disconnected") {
|
|
2327
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2328
|
+
type: "signalTrouble",
|
|
2329
|
+
message: `Network connection lost. Trying to reconnect you...`,
|
|
2330
|
+
props: {},
|
|
2331
|
+
})));
|
|
2203
2332
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2333
|
+
else if (signalStatus === "connected") {
|
|
2334
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2335
|
+
type: "signalOk",
|
|
2336
|
+
message: `Network connection available`,
|
|
2337
|
+
props: {},
|
|
2338
|
+
})));
|
|
2209
2339
|
}
|
|
2210
2340
|
});
|
|
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
|
-
}
|
|
2341
|
+
startAppListening({
|
|
2342
|
+
actionCreator: signalEvents.clientUnableToJoin,
|
|
2343
|
+
effect: (action, { dispatch }) => {
|
|
2344
|
+
var _a;
|
|
2345
|
+
if (((_a = action.payload) === null || _a === void 0 ? void 0 : _a.error) === "room_full") {
|
|
2346
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2347
|
+
type: "clientUnableToJoinFullRoom",
|
|
2348
|
+
message: "Someone tried to join but the room is full and at capacity.",
|
|
2349
|
+
props: {},
|
|
2350
|
+
})));
|
|
2240
2351
|
}
|
|
2241
|
-
}
|
|
2242
|
-
return upd;
|
|
2243
|
-
});
|
|
2244
|
-
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
2245
|
-
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
2246
|
-
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
2247
|
-
}
|
|
2352
|
+
},
|
|
2248
2353
|
});
|
|
2249
2354
|
|
|
2250
2355
|
const rtcAnalyticsCustomEvents = {
|
|
@@ -2616,6 +2721,7 @@ const appReducer = toolkit.combineReducers({
|
|
|
2616
2721
|
authorization: authorizationSlice.reducer,
|
|
2617
2722
|
chat: chatSlice.reducer,
|
|
2618
2723
|
cloudRecording: cloudRecordingSlice.reducer,
|
|
2724
|
+
connectionMonitor: connectionMonitorSlice.reducer,
|
|
2619
2725
|
deviceCredentials: deviceCredentialsSlice.reducer,
|
|
2620
2726
|
localMedia: localMediaSlice.reducer,
|
|
2621
2727
|
localParticipant: localParticipantSlice.reducer,
|
|
@@ -3693,6 +3799,9 @@ exports.appSlice = appSlice;
|
|
|
3693
3799
|
exports.authorizationSlice = authorizationSlice;
|
|
3694
3800
|
exports.chatSlice = chatSlice;
|
|
3695
3801
|
exports.cloudRecordingSlice = cloudRecordingSlice;
|
|
3802
|
+
exports.connectionMonitorSlice = connectionMonitorSlice;
|
|
3803
|
+
exports.connectionMonitorStarted = connectionMonitorStarted;
|
|
3804
|
+
exports.connectionMonitorStopped = connectionMonitorStopped;
|
|
3696
3805
|
exports.createAppAsyncThunk = createAppAsyncThunk;
|
|
3697
3806
|
exports.createAppAuthorizedThunk = createAppAuthorizedThunk;
|
|
3698
3807
|
exports.createAppThunk = createAppThunk;
|
|
@@ -3741,9 +3850,11 @@ exports.doSignalDisconnect = doSignalDisconnect;
|
|
|
3741
3850
|
exports.doSignalIdentifyDevice = doSignalIdentifyDevice;
|
|
3742
3851
|
exports.doSpotlightParticipant = doSpotlightParticipant;
|
|
3743
3852
|
exports.doStartCloudRecording = doStartCloudRecording;
|
|
3853
|
+
exports.doStartConnectionMonitor = doStartConnectionMonitor;
|
|
3744
3854
|
exports.doStartLocalMedia = doStartLocalMedia;
|
|
3745
3855
|
exports.doStartScreenshare = doStartScreenshare;
|
|
3746
3856
|
exports.doStopCloudRecording = doStopCloudRecording;
|
|
3857
|
+
exports.doStopConnectionMonitor = doStopConnectionMonitor;
|
|
3747
3858
|
exports.doStopLocalMedia = doStopLocalMedia;
|
|
3748
3859
|
exports.doStopScreenshare = doStopScreenshare;
|
|
3749
3860
|
exports.doSwitchLocalStream = doSwitchLocalStream;
|
|
@@ -3757,7 +3868,7 @@ exports.hasValue = hasValue;
|
|
|
3757
3868
|
exports.initialCloudRecordingState = initialCloudRecordingState;
|
|
3758
3869
|
exports.initialLocalMediaState = initialLocalMediaState;
|
|
3759
3870
|
exports.initialNotificationsState = initialNotificationsState;
|
|
3760
|
-
exports.initialState = initialState$
|
|
3871
|
+
exports.initialState = initialState$g;
|
|
3761
3872
|
exports.isAcceptingStreams = isAcceptingStreams;
|
|
3762
3873
|
exports.isClientSpotlighted = isClientSpotlighted;
|
|
3763
3874
|
exports.listenerMiddleware = listenerMiddleware;
|
|
@@ -3809,6 +3920,7 @@ exports.selectCloudRecordingError = selectCloudRecordingError;
|
|
|
3809
3920
|
exports.selectCloudRecordingRaw = selectCloudRecordingRaw;
|
|
3810
3921
|
exports.selectCloudRecordingStartedAt = selectCloudRecordingStartedAt;
|
|
3811
3922
|
exports.selectCloudRecordingStatus = selectCloudRecordingStatus;
|
|
3923
|
+
exports.selectConnectionMonitorIsRunning = selectConnectionMonitorIsRunning;
|
|
3812
3924
|
exports.selectCurrentCameraDeviceId = selectCurrentCameraDeviceId;
|
|
3813
3925
|
exports.selectCurrentMicrophoneDeviceId = selectCurrentMicrophoneDeviceId;
|
|
3814
3926
|
exports.selectCurrentSpeakerDeviceId = selectCurrentSpeakerDeviceId;
|
|
@@ -3887,6 +3999,8 @@ exports.selectShouldFetchDeviceCredentials = selectShouldFetchDeviceCredentials;
|
|
|
3887
3999
|
exports.selectShouldFetchOrganization = selectShouldFetchOrganization;
|
|
3888
4000
|
exports.selectShouldIdentifyDevice = selectShouldIdentifyDevice;
|
|
3889
4001
|
exports.selectShouldInitializeRtc = selectShouldInitializeRtc;
|
|
4002
|
+
exports.selectShouldStartConnectionMonitor = selectShouldStartConnectionMonitor;
|
|
4003
|
+
exports.selectShouldStopConnectionMonitor = selectShouldStopConnectionMonitor;
|
|
3890
4004
|
exports.selectSignalConnectionDeviceIdentified = selectSignalConnectionDeviceIdentified;
|
|
3891
4005
|
exports.selectSignalConnectionRaw = selectSignalConnectionRaw;
|
|
3892
4006
|
exports.selectSignalConnectionSocket = selectSignalConnectionSocket;
|
|
@@ -3896,6 +4010,7 @@ exports.selectSpeakerDevices = selectSpeakerDevices;
|
|
|
3896
4010
|
exports.selectSpotlightedClientViews = selectSpotlightedClientViews;
|
|
3897
4011
|
exports.selectSpotlights = selectSpotlights;
|
|
3898
4012
|
exports.selectSpotlightsRaw = selectSpotlightsRaw;
|
|
4013
|
+
exports.selectStopCallbackFunction = selectStopCallbackFunction;
|
|
3899
4014
|
exports.selectStreamingRaw = selectStreamingRaw;
|
|
3900
4015
|
exports.selectStreamsToAccept = selectStreamsToAccept;
|
|
3901
4016
|
exports.selectWaitingParticipants = selectWaitingParticipants;
|