@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.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAsyncThunk, createListenerMiddleware, addListener, createSlice, createAction, createSelector, isAnyOf, combineReducers, configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import { ServerSocket, getDeviceData, getStream, getUpdatedDevices, RtcManagerDispatcher, assert, fromLocation } from '@whereby.com/media';
|
|
3
|
-
import { EventEmitter } from 'events';
|
|
2
|
+
import { ServerSocket, getDeviceData, getStream, getUpdatedDevices, RtcManagerDispatcher, setClientProvider, subscribeIssues, assert, fromLocation } from '@whereby.com/media';
|
|
4
3
|
import { Chrome111 } from 'mediasoup-client/lib/handlers/Chrome111.js';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
5
|
import nodeBtoa from 'btoa';
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
|
|
@@ -43,9 +43,9 @@ const createReactor = (selectors, callback) => {
|
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
const coreVersion = "0.
|
|
46
|
+
const coreVersion = "0.26.0";
|
|
47
47
|
|
|
48
|
-
const initialState$
|
|
48
|
+
const initialState$g = {
|
|
49
49
|
isNodeSdk: false,
|
|
50
50
|
isActive: false,
|
|
51
51
|
isDialIn: false,
|
|
@@ -57,7 +57,7 @@ const initialState$f = {
|
|
|
57
57
|
};
|
|
58
58
|
const appSlice = createSlice({
|
|
59
59
|
name: "app",
|
|
60
|
-
initialState: initialState$
|
|
60
|
+
initialState: initialState$g,
|
|
61
61
|
reducers: {
|
|
62
62
|
doAppStart: (state, action) => {
|
|
63
63
|
const url = new URL(action.payload.roomUrl);
|
|
@@ -120,13 +120,13 @@ const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
|
|
|
120
120
|
canAskToSpeak: ["host"],
|
|
121
121
|
canSpotlight: ["host"],
|
|
122
122
|
};
|
|
123
|
-
const initialState$
|
|
123
|
+
const initialState$f = {
|
|
124
124
|
roomKey: null,
|
|
125
125
|
roleName: "none",
|
|
126
126
|
};
|
|
127
127
|
const authorizationSlice = createSlice({
|
|
128
128
|
name: "authorization",
|
|
129
|
-
initialState: initialState$
|
|
129
|
+
initialState: initialState$f,
|
|
130
130
|
reducers: {
|
|
131
131
|
setRoomKey: (state, action) => {
|
|
132
132
|
return Object.assign(Object.assign({}, state), { roomKey: action.payload });
|
|
@@ -197,13 +197,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
197
197
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
198
198
|
};
|
|
199
199
|
|
|
200
|
-
const initialState$
|
|
200
|
+
const initialState$e = {
|
|
201
201
|
isFetching: false,
|
|
202
202
|
data: null,
|
|
203
203
|
};
|
|
204
204
|
const deviceCredentialsSlice = createSlice({
|
|
205
205
|
name: "deviceCredentials",
|
|
206
|
-
initialState: initialState$
|
|
206
|
+
initialState: initialState$e,
|
|
207
207
|
reducers: {},
|
|
208
208
|
extraReducers: (builder) => {
|
|
209
209
|
builder.addCase(doGetDeviceCredentials.pending, (state) => {
|
|
@@ -278,7 +278,7 @@ function createSocket() {
|
|
|
278
278
|
};
|
|
279
279
|
return new ServerSocket(socketHost, socketOverrides);
|
|
280
280
|
}
|
|
281
|
-
const initialState$
|
|
281
|
+
const initialState$d = {
|
|
282
282
|
deviceIdentified: false,
|
|
283
283
|
isIdentifyingDevice: false,
|
|
284
284
|
status: "ready",
|
|
@@ -286,7 +286,7 @@ const initialState$c = {
|
|
|
286
286
|
};
|
|
287
287
|
const signalConnectionSlice = createSlice({
|
|
288
288
|
name: "signalConnection",
|
|
289
|
-
initialState: initialState$
|
|
289
|
+
initialState: initialState$d,
|
|
290
290
|
reducers: {
|
|
291
291
|
socketConnecting: (state) => {
|
|
292
292
|
return Object.assign(Object.assign({}, state), { status: "connecting" });
|
|
@@ -295,7 +295,7 @@ const signalConnectionSlice = createSlice({
|
|
|
295
295
|
return Object.assign(Object.assign({}, state), { socket: action.payload, status: "connected" });
|
|
296
296
|
},
|
|
297
297
|
socketDisconnected: (state) => {
|
|
298
|
-
return Object.assign(Object.assign({}, state), { deviceIdentified: false, status: "disconnected" });
|
|
298
|
+
return Object.assign(Object.assign({}, state), { socket: null, deviceIdentified: false, status: "disconnected" });
|
|
299
299
|
},
|
|
300
300
|
socketReconnecting: (state) => {
|
|
301
301
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
@@ -390,12 +390,12 @@ startAppListening({
|
|
|
390
390
|
},
|
|
391
391
|
});
|
|
392
392
|
|
|
393
|
-
const initialState$
|
|
393
|
+
const initialState$c = {
|
|
394
394
|
chatMessages: [],
|
|
395
395
|
};
|
|
396
396
|
const chatSlice = createSlice({
|
|
397
397
|
name: "chat",
|
|
398
|
-
initialState: initialState$
|
|
398
|
+
initialState: initialState$c,
|
|
399
399
|
reducers: {},
|
|
400
400
|
extraReducers(builder) {
|
|
401
401
|
builder.addCase(signalEvents.chatMessage, (state, action) => {
|
|
@@ -476,6 +476,60 @@ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
|
|
|
476
476
|
const selectCloudRecordingError = (state) => state.cloudRecording.error;
|
|
477
477
|
const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
|
|
478
478
|
|
|
479
|
+
const initialState$b = {
|
|
480
|
+
data: null,
|
|
481
|
+
isFetching: false,
|
|
482
|
+
error: null,
|
|
483
|
+
};
|
|
484
|
+
const organizationSlice = createSlice({
|
|
485
|
+
initialState: initialState$b,
|
|
486
|
+
name: "organization",
|
|
487
|
+
reducers: {},
|
|
488
|
+
extraReducers: (builder) => {
|
|
489
|
+
builder.addCase(doOrganizationFetch.pending, (state) => {
|
|
490
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
491
|
+
});
|
|
492
|
+
builder.addCase(doOrganizationFetch.fulfilled, (state, action) => {
|
|
493
|
+
if (!action.payload)
|
|
494
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
495
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
496
|
+
});
|
|
497
|
+
builder.addCase(doOrganizationFetch.rejected, (state) => {
|
|
498
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, error: true });
|
|
499
|
+
});
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
const doOrganizationFetch = createAppAsyncThunk("organization/doOrganizationFetch", (_, { extra, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
503
|
+
try {
|
|
504
|
+
const roomUrl = selectAppRoomUrl(getState());
|
|
505
|
+
const organization = yield extra.services.fetchOrganizationFromRoomUrl(roomUrl || "");
|
|
506
|
+
if (!organization) {
|
|
507
|
+
throw new Error("Invalid room url");
|
|
508
|
+
}
|
|
509
|
+
return organization;
|
|
510
|
+
}
|
|
511
|
+
catch (error) {
|
|
512
|
+
console.error(error);
|
|
513
|
+
}
|
|
514
|
+
}));
|
|
515
|
+
const selectOrganizationRaw = (state) => state.organization;
|
|
516
|
+
const selectOrganizationId = (state) => { var _a; return (_a = state.organization.data) === null || _a === void 0 ? void 0 : _a.organizationId; };
|
|
517
|
+
const selectShouldFetchOrganization = createSelector(selectAppIsActive, selectOrganizationRaw, selectDeviceCredentialsRaw, (appIsActive, organization, deviceCredentials) => {
|
|
518
|
+
if (appIsActive &&
|
|
519
|
+
!organization.data &&
|
|
520
|
+
!organization.isFetching &&
|
|
521
|
+
!organization.error &&
|
|
522
|
+
!deviceCredentials.isFetching) {
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
return false;
|
|
526
|
+
});
|
|
527
|
+
createReactor([selectShouldFetchOrganization], ({ dispatch }, shouldFetchOrganization) => {
|
|
528
|
+
if (shouldFetchOrganization) {
|
|
529
|
+
dispatch(doOrganizationFetch());
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
|
|
479
533
|
function fakeAudioStream() {
|
|
480
534
|
const audioCtx = new AudioContext();
|
|
481
535
|
const oscillator = audioCtx.createOscillator();
|
|
@@ -1181,82 +1235,175 @@ createReactor([selectLocalParticipantDisplayName, selectLocalParticipantStickyRe
|
|
|
1181
1235
|
});
|
|
1182
1236
|
|
|
1183
1237
|
const initialState$9 = {
|
|
1184
|
-
|
|
1185
|
-
|
|
1238
|
+
session: null,
|
|
1239
|
+
status: "ready",
|
|
1186
1240
|
error: null,
|
|
1187
1241
|
};
|
|
1188
|
-
const
|
|
1189
|
-
name: "localScreenshare",
|
|
1242
|
+
const roomConnectionSlice = createSlice({
|
|
1190
1243
|
initialState: initialState$9,
|
|
1244
|
+
name: "roomConnection",
|
|
1191
1245
|
reducers: {
|
|
1192
|
-
|
|
1193
|
-
return Object.assign(Object.assign({}, state), { status:
|
|
1246
|
+
connectionStatusChanged: (state, action) => {
|
|
1247
|
+
return Object.assign(Object.assign({}, state), { status: action.payload });
|
|
1194
1248
|
},
|
|
1195
1249
|
},
|
|
1196
1250
|
extraReducers: (builder) => {
|
|
1197
|
-
builder.addCase(
|
|
1198
|
-
|
|
1251
|
+
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1252
|
+
var _a, _b;
|
|
1253
|
+
const { error, isLocked } = action.payload;
|
|
1254
|
+
if (error === "room_locked" && isLocked) {
|
|
1255
|
+
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
1256
|
+
}
|
|
1257
|
+
if (error) {
|
|
1258
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected", error });
|
|
1259
|
+
}
|
|
1260
|
+
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 });
|
|
1199
1261
|
});
|
|
1200
|
-
builder.addCase(
|
|
1201
|
-
|
|
1262
|
+
builder.addCase(signalEvents.disconnect, (state) => {
|
|
1263
|
+
if (["kicked", "left"].includes(state.status)) {
|
|
1264
|
+
return Object.assign({}, state);
|
|
1265
|
+
}
|
|
1266
|
+
return Object.assign(Object.assign({}, state), { status: "disconnected" });
|
|
1202
1267
|
});
|
|
1203
|
-
builder.addCase(
|
|
1204
|
-
|
|
1268
|
+
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
1269
|
+
var _a, _b;
|
|
1270
|
+
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 });
|
|
1271
|
+
});
|
|
1272
|
+
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
1273
|
+
var _a;
|
|
1274
|
+
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
1275
|
+
return state;
|
|
1276
|
+
}
|
|
1277
|
+
return Object.assign(Object.assign({}, state), { session: null });
|
|
1278
|
+
});
|
|
1279
|
+
builder.addCase(signalEvents.clientKicked, (state) => {
|
|
1280
|
+
return Object.assign(Object.assign({}, state), { status: "kicked" });
|
|
1281
|
+
});
|
|
1282
|
+
builder.addCase(signalEvents.roomLeft, (state) => {
|
|
1283
|
+
return Object.assign(Object.assign({}, state), { status: "left" });
|
|
1284
|
+
});
|
|
1285
|
+
builder.addCase(socketReconnecting, (state) => {
|
|
1286
|
+
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1205
1287
|
});
|
|
1206
1288
|
},
|
|
1207
1289
|
});
|
|
1208
|
-
const {
|
|
1209
|
-
const
|
|
1210
|
-
var _a;
|
|
1211
|
-
try {
|
|
1212
|
-
const state = getState();
|
|
1213
|
-
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1214
|
-
if (screenshareStream) {
|
|
1215
|
-
return { stream: screenshareStream };
|
|
1216
|
-
}
|
|
1217
|
-
const stream = yield navigator.mediaDevices.getDisplayMedia();
|
|
1218
|
-
const onEnded = () => {
|
|
1219
|
-
dispatch(doStopScreenshare());
|
|
1220
|
-
};
|
|
1221
|
-
if ("oninactive" in stream) {
|
|
1222
|
-
stream.addEventListener("inactive", onEnded);
|
|
1223
|
-
}
|
|
1224
|
-
else {
|
|
1225
|
-
(_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.addEventListener("ended", onEnded);
|
|
1226
|
-
}
|
|
1227
|
-
return { stream };
|
|
1228
|
-
}
|
|
1229
|
-
catch (error) {
|
|
1230
|
-
return rejectWithValue(error);
|
|
1231
|
-
}
|
|
1232
|
-
}));
|
|
1233
|
-
const doStopScreenshare = createAppThunk(() => (dispatch, getState) => {
|
|
1290
|
+
const { connectionStatusChanged } = roomConnectionSlice.actions;
|
|
1291
|
+
const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1234
1292
|
const state = getState();
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
|
|
1293
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1294
|
+
const roomName = selectAppRoomName(state);
|
|
1295
|
+
const roomKey = selectRoomKey(state);
|
|
1296
|
+
const displayName = selectAppDisplayName(state);
|
|
1297
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1298
|
+
const userAgent = selectAppUserAgent(state);
|
|
1299
|
+
const externalId = selectAppExternalId(state);
|
|
1300
|
+
const organizationId = selectOrganizationId(state);
|
|
1301
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("knock_room", {
|
|
1302
|
+
avatarUrl: null,
|
|
1303
|
+
config: {
|
|
1304
|
+
isAudioEnabled: true,
|
|
1305
|
+
isVideoEnabled: true,
|
|
1306
|
+
},
|
|
1307
|
+
deviceCapabilities: { canScreenshare: true },
|
|
1308
|
+
displayName,
|
|
1309
|
+
isCoLocated: false,
|
|
1310
|
+
isDialIn,
|
|
1311
|
+
isDevicePermissionDenied: false,
|
|
1312
|
+
kickFromOtherRooms: false,
|
|
1313
|
+
organizationId,
|
|
1314
|
+
roomKey,
|
|
1315
|
+
roomName,
|
|
1316
|
+
userAgent,
|
|
1317
|
+
externalId,
|
|
1318
|
+
});
|
|
1319
|
+
dispatch(connectionStatusChanged("knocking"));
|
|
1320
|
+
});
|
|
1321
|
+
const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
|
|
1322
|
+
const state = getState();
|
|
1323
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1324
|
+
const roomName = selectAppRoomName(state);
|
|
1325
|
+
const roomKey = selectRoomKey(state);
|
|
1326
|
+
const displayName = selectAppDisplayName(state);
|
|
1327
|
+
const userAgent = selectAppUserAgent(state);
|
|
1328
|
+
const externalId = selectAppExternalId(state);
|
|
1329
|
+
const isDialIn = selectAppIsDialIn(state);
|
|
1330
|
+
const organizationId = selectOrganizationId(state);
|
|
1331
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1332
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1333
|
+
const clientClaim = selectLocalParticipantClientClaim(getState());
|
|
1334
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
|
|
1335
|
+
isAudioEnabled: isMicrophoneEnabled,
|
|
1336
|
+
isVideoEnabled: isCameraEnabled,
|
|
1337
|
+
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDialIn, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1338
|
+
roomKey,
|
|
1339
|
+
roomName,
|
|
1340
|
+
userAgent,
|
|
1341
|
+
externalId }, (clientClaim && { clientClaim })));
|
|
1342
|
+
dispatch(connectionStatusChanged("connecting"));
|
|
1343
|
+
});
|
|
1344
|
+
const selectRoomConnectionRaw = (state) => state.roomConnection;
|
|
1345
|
+
const selectRoomConnectionSession = (state) => state.roomConnection.session;
|
|
1346
|
+
const selectRoomConnectionSessionId = (state) => { var _a; return (_a = state.roomConnection.session) === null || _a === void 0 ? void 0 : _a.id; };
|
|
1347
|
+
const selectRoomConnectionStatus = (state) => state.roomConnection.status;
|
|
1348
|
+
const selectRoomConnectionError = (state) => state.roomConnection.error;
|
|
1349
|
+
const selectShouldConnectRoom = createSelector([
|
|
1350
|
+
selectAppIsActive,
|
|
1351
|
+
selectOrganizationId,
|
|
1352
|
+
selectRoomConnectionStatus,
|
|
1353
|
+
selectSignalConnectionDeviceIdentified,
|
|
1354
|
+
selectLocalMediaStatus,
|
|
1355
|
+
selectRoomConnectionError,
|
|
1356
|
+
], (appIsActive, hasOrganizationIdFetched, roomConnectionStatus, signalConnectionDeviceIdentified, localMediaStatus, roomConnectionError) => {
|
|
1357
|
+
if (appIsActive &&
|
|
1358
|
+
localMediaStatus === "started" &&
|
|
1359
|
+
signalConnectionDeviceIdentified &&
|
|
1360
|
+
!!hasOrganizationIdFetched &&
|
|
1361
|
+
["ready", "reconnecting", "disconnected"].includes(roomConnectionStatus) &&
|
|
1362
|
+
!roomConnectionError) {
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
return false;
|
|
1366
|
+
});
|
|
1367
|
+
createReactor([selectShouldConnectRoom], ({ dispatch }, shouldConnectRoom) => {
|
|
1368
|
+
if (shouldConnectRoom) {
|
|
1369
|
+
dispatch(doConnectRoom());
|
|
1238
1370
|
}
|
|
1239
|
-
screenshareStream.getTracks().forEach((track) => track.stop());
|
|
1240
|
-
dispatch(stopScreenshare({ stream: screenshareStream }));
|
|
1241
1371
|
});
|
|
1242
|
-
const selectLocalScreenshareRaw = (state) => state.localScreenshare;
|
|
1243
|
-
const selectLocalScreenshareStatus = (state) => state.localScreenshare.status;
|
|
1244
|
-
const selectLocalScreenshareStream = (state) => state.localScreenshare.stream;
|
|
1245
1372
|
startAppListening({
|
|
1246
|
-
actionCreator:
|
|
1247
|
-
effect: (
|
|
1373
|
+
actionCreator: signalEvents.knockHandled,
|
|
1374
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
1375
|
+
const { clientId, resolution } = payload;
|
|
1248
1376
|
const state = getState();
|
|
1249
|
-
const
|
|
1250
|
-
if (
|
|
1377
|
+
const selfId = selectSelfId(state);
|
|
1378
|
+
if (clientId !== selfId) {
|
|
1251
1379
|
return;
|
|
1252
1380
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1381
|
+
if (resolution === "accepted") {
|
|
1382
|
+
dispatch(setRoomKey(payload.metadata.roomKey));
|
|
1383
|
+
dispatch(doConnectRoom());
|
|
1384
|
+
}
|
|
1385
|
+
else if (resolution === "rejected") {
|
|
1386
|
+
dispatch(connectionStatusChanged("knock_rejected"));
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1389
|
+
});
|
|
1390
|
+
startAppListening({
|
|
1391
|
+
actionCreator: doAppStop,
|
|
1392
|
+
effect: (_, { dispatch, getState }) => {
|
|
1393
|
+
const state = getState();
|
|
1394
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
1395
|
+
if (roomConnectionStatus === "connected") {
|
|
1396
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1397
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("leave_room");
|
|
1398
|
+
dispatch(connectionStatusChanged("leaving"));
|
|
1399
|
+
}
|
|
1400
|
+
else {
|
|
1401
|
+
doSignalDisconnect();
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1404
|
+
});
|
|
1405
|
+
|
|
1406
|
+
function createRtcEventAction(name) {
|
|
1260
1407
|
return createAction(`rtcConnection/event/${name}`);
|
|
1261
1408
|
}
|
|
1262
1409
|
const rtcEvents = {
|
|
@@ -1458,373 +1605,388 @@ const selectNumParticipants = createSelector(selectRemoteParticipants, selectLoc
|
|
|
1458
1605
|
});
|
|
1459
1606
|
|
|
1460
1607
|
const initialState$7 = {
|
|
1461
|
-
|
|
1462
|
-
|
|
1608
|
+
status: "inactive",
|
|
1609
|
+
stream: null,
|
|
1463
1610
|
error: null,
|
|
1464
1611
|
};
|
|
1465
|
-
const
|
|
1612
|
+
const localScreenshareSlice = createSlice({
|
|
1613
|
+
name: "localScreenshare",
|
|
1466
1614
|
initialState: initialState$7,
|
|
1467
|
-
|
|
1468
|
-
|
|
1615
|
+
reducers: {
|
|
1616
|
+
stopScreenshare(state, action) {
|
|
1617
|
+
return Object.assign(Object.assign({}, state), { status: "inactive", stream: null });
|
|
1618
|
+
},
|
|
1619
|
+
},
|
|
1469
1620
|
extraReducers: (builder) => {
|
|
1470
|
-
builder.addCase(
|
|
1471
|
-
return Object.assign(Object.assign({}, state), {
|
|
1621
|
+
builder.addCase(doStartScreenshare.pending, (state) => {
|
|
1622
|
+
return Object.assign(Object.assign({}, state), { status: "starting" });
|
|
1472
1623
|
});
|
|
1473
|
-
builder.addCase(
|
|
1474
|
-
|
|
1475
|
-
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1476
|
-
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
1624
|
+
builder.addCase(doStartScreenshare.fulfilled, (state, { payload: { stream } }) => {
|
|
1625
|
+
return Object.assign(Object.assign({}, state), { status: "active", stream });
|
|
1477
1626
|
});
|
|
1478
|
-
builder.addCase(
|
|
1479
|
-
return Object.assign(Object.assign({}, state), {
|
|
1627
|
+
builder.addCase(doStartScreenshare.rejected, (state, { payload }) => {
|
|
1628
|
+
return Object.assign(Object.assign({}, state), { error: payload, status: "inactive", stream: null });
|
|
1480
1629
|
});
|
|
1481
1630
|
},
|
|
1482
1631
|
});
|
|
1483
|
-
const
|
|
1632
|
+
const { stopScreenshare } = localScreenshareSlice.actions;
|
|
1633
|
+
const doStartScreenshare = createAppAsyncThunk("localScreenshare/doStartScreenshare", (_, { dispatch, getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1634
|
+
var _a;
|
|
1484
1635
|
try {
|
|
1485
|
-
const
|
|
1486
|
-
const
|
|
1487
|
-
if (
|
|
1488
|
-
|
|
1636
|
+
const state = getState();
|
|
1637
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1638
|
+
if (screenshareStream) {
|
|
1639
|
+
return { stream: screenshareStream };
|
|
1489
1640
|
}
|
|
1490
|
-
|
|
1641
|
+
const stream = yield navigator.mediaDevices.getDisplayMedia();
|
|
1642
|
+
const onEnded = () => {
|
|
1643
|
+
dispatch(doStopScreenshare());
|
|
1644
|
+
};
|
|
1645
|
+
if ("oninactive" in stream) {
|
|
1646
|
+
stream.addEventListener("inactive", onEnded);
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
(_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.addEventListener("ended", onEnded);
|
|
1650
|
+
}
|
|
1651
|
+
return { stream };
|
|
1491
1652
|
}
|
|
1492
1653
|
catch (error) {
|
|
1493
|
-
|
|
1654
|
+
return rejectWithValue(error);
|
|
1494
1655
|
}
|
|
1495
1656
|
}));
|
|
1496
|
-
const
|
|
1497
|
-
const
|
|
1498
|
-
const
|
|
1499
|
-
if (
|
|
1500
|
-
|
|
1501
|
-
!organization.isFetching &&
|
|
1502
|
-
!organization.error &&
|
|
1503
|
-
!deviceCredentials.isFetching) {
|
|
1504
|
-
return true;
|
|
1657
|
+
const doStopScreenshare = createAppThunk(() => (dispatch, getState) => {
|
|
1658
|
+
const state = getState();
|
|
1659
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1660
|
+
if (!screenshareStream) {
|
|
1661
|
+
return;
|
|
1505
1662
|
}
|
|
1506
|
-
|
|
1663
|
+
screenshareStream.getTracks().forEach((track) => track.stop());
|
|
1664
|
+
dispatch(stopScreenshare({ stream: screenshareStream }));
|
|
1507
1665
|
});
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1666
|
+
const selectLocalScreenshareRaw = (state) => state.localScreenshare;
|
|
1667
|
+
const selectLocalScreenshareStatus = (state) => state.localScreenshare.status;
|
|
1668
|
+
const selectLocalScreenshareStream = (state) => state.localScreenshare.stream;
|
|
1669
|
+
startAppListening({
|
|
1670
|
+
actionCreator: localMediaStopped,
|
|
1671
|
+
effect: (_, { getState }) => {
|
|
1672
|
+
const state = getState();
|
|
1673
|
+
const screenshareStream = selectLocalScreenshareStream(state);
|
|
1674
|
+
if (!screenshareStream) {
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
screenshareStream === null || screenshareStream === void 0 ? void 0 : screenshareStream.getTracks().forEach((track) => {
|
|
1678
|
+
track.stop();
|
|
1679
|
+
});
|
|
1680
|
+
},
|
|
1512
1681
|
});
|
|
1513
1682
|
|
|
1683
|
+
const createWebRtcEmitter = (dispatch) => {
|
|
1684
|
+
return {
|
|
1685
|
+
emit: (eventName, data) => {
|
|
1686
|
+
if (eventName === "rtc_manager_created") {
|
|
1687
|
+
dispatch(doRtcManagerCreated(data));
|
|
1688
|
+
}
|
|
1689
|
+
else if (eventName === "stream_added") {
|
|
1690
|
+
dispatch(rtcEvents.streamAdded(data));
|
|
1691
|
+
}
|
|
1692
|
+
else if (eventName === "rtc_manager_destroyed") {
|
|
1693
|
+
dispatch(rtcManagerDestroyed());
|
|
1694
|
+
}
|
|
1695
|
+
else ;
|
|
1696
|
+
},
|
|
1697
|
+
};
|
|
1698
|
+
};
|
|
1514
1699
|
const initialState$6 = {
|
|
1515
|
-
|
|
1516
|
-
status: "ready",
|
|
1700
|
+
dispatcherCreated: false,
|
|
1517
1701
|
error: null,
|
|
1702
|
+
isCreatingDispatcher: false,
|
|
1703
|
+
reportedStreamResolutions: {},
|
|
1704
|
+
rtcManager: null,
|
|
1705
|
+
rtcManagerDispatcher: null,
|
|
1706
|
+
rtcManagerInitialized: false,
|
|
1707
|
+
status: "inactive",
|
|
1708
|
+
isAcceptingStreams: false,
|
|
1518
1709
|
};
|
|
1519
|
-
const
|
|
1710
|
+
const rtcConnectionSlice = createSlice({
|
|
1711
|
+
name: "rtcConnection",
|
|
1520
1712
|
initialState: initialState$6,
|
|
1521
|
-
name: "roomConnection",
|
|
1522
1713
|
reducers: {
|
|
1523
|
-
|
|
1524
|
-
return Object.assign(Object.assign({}, state), {
|
|
1714
|
+
isAcceptingStreams: (state, action) => {
|
|
1715
|
+
return Object.assign(Object.assign({}, state), { isAcceptingStreams: action.payload });
|
|
1716
|
+
},
|
|
1717
|
+
resolutionReported: (state, action) => {
|
|
1718
|
+
const { streamId, width, height } = action.payload;
|
|
1719
|
+
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
1720
|
+
},
|
|
1721
|
+
rtcDisconnected: () => {
|
|
1722
|
+
return Object.assign({}, initialState$6);
|
|
1723
|
+
},
|
|
1724
|
+
rtcDispatcherCreated: (state, action) => {
|
|
1725
|
+
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
1726
|
+
},
|
|
1727
|
+
rtcManagerCreated: (state, action) => {
|
|
1728
|
+
return Object.assign(Object.assign({}, state), { rtcManager: action.payload, status: "ready" });
|
|
1729
|
+
},
|
|
1730
|
+
rtcManagerDestroyed: (state) => {
|
|
1731
|
+
return Object.assign(Object.assign({}, state), { rtcManager: null });
|
|
1732
|
+
},
|
|
1733
|
+
rtcManagerInitialized: (state) => {
|
|
1734
|
+
return Object.assign(Object.assign({}, state), { rtcManagerInitialized: true });
|
|
1525
1735
|
},
|
|
1526
1736
|
},
|
|
1527
1737
|
extraReducers: (builder) => {
|
|
1528
|
-
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1529
|
-
var _a, _b;
|
|
1530
|
-
const { error, isLocked } = action.payload;
|
|
1531
|
-
if (error === "room_locked" && isLocked) {
|
|
1532
|
-
return Object.assign(Object.assign({}, state), { status: "room_locked" });
|
|
1533
|
-
}
|
|
1534
|
-
if (error) {
|
|
1535
|
-
return Object.assign(Object.assign({}, state), { status: "disconnected", error });
|
|
1536
|
-
}
|
|
1537
|
-
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 });
|
|
1538
|
-
});
|
|
1539
|
-
builder.addCase(signalEvents.disconnect, (state) => {
|
|
1540
|
-
if (["kicked", "left"].includes(state.status)) {
|
|
1541
|
-
return Object.assign({}, state);
|
|
1542
|
-
}
|
|
1543
|
-
return Object.assign(Object.assign({}, state), { status: "disconnected" });
|
|
1544
|
-
});
|
|
1545
|
-
builder.addCase(signalEvents.newClient, (state, action) => {
|
|
1546
|
-
var _a, _b;
|
|
1547
|
-
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 });
|
|
1548
|
-
});
|
|
1549
|
-
builder.addCase(signalEvents.roomSessionEnded, (state, action) => {
|
|
1550
|
-
var _a;
|
|
1551
|
-
if (((_a = state.session) === null || _a === void 0 ? void 0 : _a.id) !== action.payload.roomSessionId) {
|
|
1552
|
-
return state;
|
|
1553
|
-
}
|
|
1554
|
-
return Object.assign(Object.assign({}, state), { session: null });
|
|
1555
|
-
});
|
|
1556
|
-
builder.addCase(signalEvents.clientKicked, (state) => {
|
|
1557
|
-
return Object.assign(Object.assign({}, state), { status: "kicked" });
|
|
1558
|
-
});
|
|
1559
|
-
builder.addCase(signalEvents.roomLeft, (state) => {
|
|
1560
|
-
return Object.assign(Object.assign({}, state), { status: "left" });
|
|
1561
|
-
});
|
|
1562
1738
|
builder.addCase(socketReconnecting, (state) => {
|
|
1563
1739
|
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1564
1740
|
});
|
|
1741
|
+
builder.addCase(signalEvents.roomJoined, (state) => {
|
|
1742
|
+
return Object.assign(Object.assign({}, state), { status: state.status === "reconnecting" ? "ready" : state.status });
|
|
1743
|
+
});
|
|
1565
1744
|
},
|
|
1566
1745
|
});
|
|
1567
|
-
const {
|
|
1568
|
-
const
|
|
1746
|
+
const { resolutionReported, rtcDispatcherCreated, rtcDisconnected, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, isAcceptingStreams, } = rtcConnectionSlice.actions;
|
|
1747
|
+
const doConnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1569
1748
|
const state = getState();
|
|
1570
1749
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1571
|
-
const
|
|
1572
|
-
const
|
|
1573
|
-
const
|
|
1574
|
-
const
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1750
|
+
const dispatcher = selectRtcConnectionRaw(state).rtcManagerDispatcher;
|
|
1751
|
+
const isCameraEnabled = selectIsCameraEnabled(state);
|
|
1752
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(state);
|
|
1753
|
+
const isNodeSdk = selectAppIsNodeSdk(state);
|
|
1754
|
+
if (dispatcher || !socket) {
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
const webrtcProvider = {
|
|
1758
|
+
getMediaConstraints: () => ({
|
|
1759
|
+
audio: isMicrophoneEnabled,
|
|
1760
|
+
video: isCameraEnabled,
|
|
1761
|
+
}),
|
|
1762
|
+
deferrable(clientId) {
|
|
1763
|
+
return !clientId;
|
|
1583
1764
|
},
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
const roomKey = selectRoomKey(state);
|
|
1603
|
-
const displayName = selectAppDisplayName(state);
|
|
1604
|
-
const userAgent = selectAppUserAgent(state);
|
|
1605
|
-
const externalId = selectAppExternalId(state);
|
|
1606
|
-
const isDialIn = selectAppIsDialIn(state);
|
|
1607
|
-
const organizationId = selectOrganizationId(state);
|
|
1608
|
-
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1609
|
-
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1610
|
-
const clientClaim = selectLocalParticipantClientClaim(getState());
|
|
1611
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
|
|
1612
|
-
isAudioEnabled: isMicrophoneEnabled,
|
|
1613
|
-
isVideoEnabled: isCameraEnabled,
|
|
1614
|
-
}, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDialIn, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
|
|
1615
|
-
roomKey,
|
|
1616
|
-
roomName,
|
|
1617
|
-
userAgent,
|
|
1618
|
-
externalId }, (clientClaim && { clientClaim })));
|
|
1619
|
-
dispatch(connectionStatusChanged("connecting"));
|
|
1765
|
+
};
|
|
1766
|
+
const rtcManagerDispatcher = new RtcManagerDispatcher({
|
|
1767
|
+
emitter: createWebRtcEmitter(dispatch),
|
|
1768
|
+
serverSocket: socket,
|
|
1769
|
+
webrtcProvider,
|
|
1770
|
+
features: {
|
|
1771
|
+
isNodeSdk,
|
|
1772
|
+
lowDataModeEnabled: false,
|
|
1773
|
+
sfuServerOverrideHost: undefined,
|
|
1774
|
+
turnServerOverrideHost: undefined,
|
|
1775
|
+
useOnlyTURN: undefined,
|
|
1776
|
+
vp9On: false,
|
|
1777
|
+
h264On: false,
|
|
1778
|
+
simulcastScreenshareOn: false,
|
|
1779
|
+
deviceHandlerFactory: isNodeSdk ? Chrome111.createFactory() : undefined,
|
|
1780
|
+
},
|
|
1781
|
+
});
|
|
1782
|
+
dispatch(rtcDispatcherCreated(rtcManagerDispatcher));
|
|
1620
1783
|
});
|
|
1621
|
-
const
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
const selectRoomConnectionError = (state) => state.roomConnection.error;
|
|
1626
|
-
const selectShouldConnectRoom = createSelector([
|
|
1627
|
-
selectAppIsActive,
|
|
1628
|
-
selectOrganizationId,
|
|
1629
|
-
selectRoomConnectionStatus,
|
|
1630
|
-
selectSignalConnectionDeviceIdentified,
|
|
1631
|
-
selectLocalMediaStatus,
|
|
1632
|
-
selectRoomConnectionError,
|
|
1633
|
-
], (appIsActive, hasOrganizationIdFetched, roomConnectionStatus, signalConnectionDeviceIdentified, localMediaStatus, roomConnectionError) => {
|
|
1634
|
-
if (appIsActive &&
|
|
1635
|
-
localMediaStatus === "started" &&
|
|
1636
|
-
signalConnectionDeviceIdentified &&
|
|
1637
|
-
!!hasOrganizationIdFetched &&
|
|
1638
|
-
["ready", "reconnecting", "disconnected"].includes(roomConnectionStatus) &&
|
|
1639
|
-
!roomConnectionError) {
|
|
1640
|
-
return true;
|
|
1784
|
+
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
1785
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1786
|
+
if (rtcManager) {
|
|
1787
|
+
rtcManager.disconnectAll();
|
|
1641
1788
|
}
|
|
1642
|
-
|
|
1789
|
+
dispatch(rtcDisconnected());
|
|
1643
1790
|
});
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1791
|
+
const doHandleAcceptStreams = createAppThunk((payload) => (dispatch, getState) => {
|
|
1792
|
+
var _a;
|
|
1793
|
+
dispatch(isAcceptingStreams(true));
|
|
1794
|
+
const state = getState();
|
|
1795
|
+
const rtcManager = selectRtcConnectionRaw(state).rtcManager;
|
|
1796
|
+
const remoteClients = selectRemoteClients(state);
|
|
1797
|
+
if (!rtcManager) {
|
|
1798
|
+
throw new Error("No rtc manager");
|
|
1647
1799
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
const
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
if (
|
|
1656
|
-
|
|
1800
|
+
const activeBreakout = false;
|
|
1801
|
+
const shouldAcceptNewClients = (_a = rtcManager.shouldAcceptStreamsFromBothSides) === null || _a === void 0 ? void 0 : _a.call(rtcManager);
|
|
1802
|
+
const updates = [];
|
|
1803
|
+
for (const { clientId, streamId, state } of payload) {
|
|
1804
|
+
const participant = remoteClients.find((p) => p.id === clientId);
|
|
1805
|
+
if (!participant)
|
|
1806
|
+
continue;
|
|
1807
|
+
if (state === "to_accept" ||
|
|
1808
|
+
(state === "new_accept" && shouldAcceptNewClients) ||
|
|
1809
|
+
(state === "old_accept" && !shouldAcceptNewClients)) {
|
|
1810
|
+
const enforceTurnProtocol = participant.isDialIn ? "onlytls" : undefined;
|
|
1811
|
+
rtcManager.acceptNewStream({
|
|
1812
|
+
streamId: streamId === "0" ? clientId : streamId,
|
|
1813
|
+
clientId,
|
|
1814
|
+
shouldAddLocalVideo: streamId === "0",
|
|
1815
|
+
activeBreakout,
|
|
1816
|
+
enforceTurnProtocol,
|
|
1817
|
+
});
|
|
1657
1818
|
}
|
|
1658
|
-
if (
|
|
1659
|
-
|
|
1660
|
-
|
|
1819
|
+
else if (state === "new_accept" || state === "old_accept") ;
|
|
1820
|
+
else if (state === "to_unaccept") {
|
|
1821
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.disconnect(streamId === "0" ? clientId : streamId, activeBreakout);
|
|
1661
1822
|
}
|
|
1662
|
-
else if (
|
|
1663
|
-
|
|
1823
|
+
else if (state !== "done_accept") {
|
|
1824
|
+
continue;
|
|
1664
1825
|
}
|
|
1665
|
-
|
|
1826
|
+
else ;
|
|
1827
|
+
updates.push({ clientId, streamId, state: state.replace(/to_|new_|old_/, "done_") });
|
|
1828
|
+
}
|
|
1829
|
+
dispatch(streamStatusUpdated(updates));
|
|
1830
|
+
dispatch(isAcceptingStreams(false));
|
|
1831
|
+
});
|
|
1832
|
+
const doRtcReportStreamResolution = createAppThunk(({ streamId, width, height }) => (dispatch, getState) => {
|
|
1833
|
+
const { reportedStreamResolutions, rtcManager } = selectRtcConnectionRaw(getState());
|
|
1834
|
+
const localStream = selectLocalMediaStream(getState());
|
|
1835
|
+
if (!rtcManager || (localStream === null || localStream === void 0 ? void 0 : localStream.id) === streamId) {
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
const old = reportedStreamResolutions[streamId];
|
|
1839
|
+
if (!old || old.width !== width || old.height !== height) {
|
|
1840
|
+
rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
|
|
1841
|
+
}
|
|
1842
|
+
dispatch(resolutionReported({ streamId, width, height }));
|
|
1843
|
+
});
|
|
1844
|
+
const doRtcManagerCreated = createAppThunk((payload) => (dispatch) => {
|
|
1845
|
+
const { rtcManager } = payload;
|
|
1846
|
+
dispatch(rtcManagerCreated(rtcManager));
|
|
1847
|
+
});
|
|
1848
|
+
const doRtcManagerInitialize = createAppThunk(() => (dispatch, getState) => {
|
|
1849
|
+
const localMediaStream = selectLocalMediaStream(getState());
|
|
1850
|
+
const rtcManager = selectRtcConnectionRaw(getState()).rtcManager;
|
|
1851
|
+
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
1852
|
+
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
1853
|
+
if (localMediaStream && rtcManager) {
|
|
1854
|
+
rtcManager.addNewStream("0", localMediaStream, !isMicrophoneEnabled, !isCameraEnabled);
|
|
1855
|
+
}
|
|
1856
|
+
dispatch(rtcManagerInitialized());
|
|
1666
1857
|
});
|
|
1858
|
+
const selectRtcConnectionRaw = (state) => state.rtcConnection;
|
|
1859
|
+
const selectRtcManagerInitialized = (state) => state.rtcConnection.rtcManagerInitialized;
|
|
1860
|
+
const selectRtcManager = (state) => state.rtcConnection.rtcManager;
|
|
1861
|
+
const selectRtcDispatcherCreated = (state) => state.rtcConnection.dispatcherCreated;
|
|
1862
|
+
const selectRtcIsCreatingDispatcher = (state) => state.rtcConnection.isCreatingDispatcher;
|
|
1863
|
+
const selectRtcStatus = (state) => state.rtcConnection.status;
|
|
1864
|
+
const selectIsAcceptingStreams = (state) => state.rtcConnection.isAcceptingStreams;
|
|
1667
1865
|
startAppListening({
|
|
1668
|
-
actionCreator:
|
|
1669
|
-
effect: (
|
|
1670
|
-
const
|
|
1671
|
-
const
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
}
|
|
1866
|
+
actionCreator: doSetDevice.fulfilled,
|
|
1867
|
+
effect: ({ payload }, { getState }) => {
|
|
1868
|
+
const { replacedTracks } = payload;
|
|
1869
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1870
|
+
const stream = selectLocalMediaStream(getState());
|
|
1871
|
+
const replace = (kind, oldTrack) => {
|
|
1872
|
+
const track = stream === null || stream === void 0 ? void 0 : stream.getTracks().find((t) => t.kind === kind);
|
|
1873
|
+
return track && (rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.replaceTrack(oldTrack, track));
|
|
1874
|
+
};
|
|
1875
|
+
replacedTracks === null || replacedTracks === void 0 ? void 0 : replacedTracks.forEach((t) => {
|
|
1876
|
+
replace(t.kind, t);
|
|
1877
|
+
});
|
|
1680
1878
|
},
|
|
1681
1879
|
});
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
const initialNotificationsState = {
|
|
1689
|
-
emitter,
|
|
1690
|
-
events: [],
|
|
1691
|
-
};
|
|
1692
|
-
const notificationsSlice = createSlice({
|
|
1693
|
-
name: "notifications",
|
|
1694
|
-
initialState: initialNotificationsState,
|
|
1695
|
-
reducers: {
|
|
1696
|
-
addNotification: (state, action) => {
|
|
1697
|
-
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
1698
|
-
},
|
|
1699
|
-
doClearNotifications: (state) => {
|
|
1700
|
-
return Object.assign(Object.assign({}, state), { events: [] });
|
|
1701
|
-
},
|
|
1880
|
+
startAppListening({
|
|
1881
|
+
actionCreator: doStartScreenshare.fulfilled,
|
|
1882
|
+
effect: ({ payload }, { getState }) => {
|
|
1883
|
+
const { stream } = payload;
|
|
1884
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1885
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.addNewStream(stream.id, stream, false, true);
|
|
1702
1886
|
},
|
|
1703
1887
|
});
|
|
1704
|
-
const { doClearNotifications } = notificationsSlice.actions;
|
|
1705
|
-
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
1706
|
-
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
1707
|
-
const state = getState();
|
|
1708
|
-
const emitter = selectNotificationsEmitter(state);
|
|
1709
|
-
emitter.emit(payload.type, payload);
|
|
1710
|
-
emitter.emit("*", payload);
|
|
1711
|
-
});
|
|
1712
|
-
const selectNotificationsRaw = (state) => state.notifications;
|
|
1713
|
-
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
1714
|
-
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
1715
1888
|
startAppListening({
|
|
1716
|
-
actionCreator:
|
|
1717
|
-
effect: (
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
if (!client) {
|
|
1721
|
-
console.warn("Could not find remote client that sent chat message");
|
|
1722
|
-
return;
|
|
1723
|
-
}
|
|
1724
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1725
|
-
type: "chatMessageReceived",
|
|
1726
|
-
message: `${client.displayName} says: ${payload.text}`,
|
|
1727
|
-
props: {
|
|
1728
|
-
client,
|
|
1729
|
-
chatMessage: {
|
|
1730
|
-
senderId: payload.senderId,
|
|
1731
|
-
timestamp: payload.timestamp,
|
|
1732
|
-
text: payload.text,
|
|
1733
|
-
},
|
|
1734
|
-
},
|
|
1735
|
-
})));
|
|
1889
|
+
actionCreator: doAppStop,
|
|
1890
|
+
effect: (_, { getState }) => {
|
|
1891
|
+
const rtcManager = selectRtcManager(getState());
|
|
1892
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.rtcStatsDisconnect();
|
|
1736
1893
|
},
|
|
1737
1894
|
});
|
|
1738
1895
|
startAppListening({
|
|
1739
|
-
actionCreator:
|
|
1740
|
-
effect: ({ payload }, {
|
|
1741
|
-
const {
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1744
|
-
if (!client) {
|
|
1745
|
-
console.warn("Could not find remote client that requested a local audio change");
|
|
1746
|
-
return;
|
|
1747
|
-
}
|
|
1748
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1749
|
-
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
1750
|
-
message: enable
|
|
1751
|
-
? `${client.displayName} has requested for you to speak`
|
|
1752
|
-
: `${client.displayName} has muted your microphone`,
|
|
1753
|
-
props: {
|
|
1754
|
-
client,
|
|
1755
|
-
enable,
|
|
1756
|
-
},
|
|
1757
|
-
})));
|
|
1896
|
+
actionCreator: stopScreenshare,
|
|
1897
|
+
effect: ({ payload }, { getState }) => {
|
|
1898
|
+
const { stream } = payload;
|
|
1899
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1900
|
+
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.removeStream(stream.id, stream, null);
|
|
1758
1901
|
},
|
|
1759
1902
|
});
|
|
1760
1903
|
startAppListening({
|
|
1761
|
-
actionCreator:
|
|
1762
|
-
effect: (
|
|
1904
|
+
actionCreator: doSwitchLocalStream.fulfilled,
|
|
1905
|
+
effect: ({ payload }, { getState }) => {
|
|
1763
1906
|
var _a;
|
|
1764
|
-
const
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
1775
|
-
if (!client) {
|
|
1776
|
-
console.warn("Could not find remote client that provided updated metadata");
|
|
1777
|
-
return;
|
|
1778
|
-
}
|
|
1779
|
-
const previousState = getOriginalState();
|
|
1780
|
-
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
1781
|
-
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
1782
|
-
(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)) {
|
|
1783
|
-
return;
|
|
1907
|
+
const stream = selectLocalMediaStream(getState());
|
|
1908
|
+
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
1909
|
+
if (stream && rtcManager) {
|
|
1910
|
+
const replace = (kind, oldTrack) => {
|
|
1911
|
+
const track = stream.getTracks().find((t) => t.kind === kind);
|
|
1912
|
+
return track && rtcManager.replaceTrack(oldTrack, track);
|
|
1913
|
+
};
|
|
1914
|
+
(_a = payload === null || payload === void 0 ? void 0 : payload.replacedTracks) === null || _a === void 0 ? void 0 : _a.forEach((t) => {
|
|
1915
|
+
replace(t.kind, t);
|
|
1916
|
+
});
|
|
1784
1917
|
}
|
|
1785
|
-
dispatch(doSetNotification(createNotificationEvent({
|
|
1786
|
-
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
1787
|
-
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
1788
|
-
props: {
|
|
1789
|
-
client,
|
|
1790
|
-
stickyReaction,
|
|
1791
|
-
},
|
|
1792
|
-
})));
|
|
1793
1918
|
},
|
|
1794
1919
|
});
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
1799
|
-
return;
|
|
1920
|
+
const selectShouldConnectRtc = createSelector(selectRtcStatus, selectAppIsActive, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectSignalConnectionSocket, (rtcStatus, appIsActive, dispatcherCreated, isCreatingDispatcher, signalSocket) => {
|
|
1921
|
+
if (appIsActive && rtcStatus === "inactive" && !dispatcherCreated && !isCreatingDispatcher && signalSocket) {
|
|
1922
|
+
return true;
|
|
1800
1923
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
})));
|
|
1924
|
+
return false;
|
|
1925
|
+
});
|
|
1926
|
+
createReactor([selectShouldConnectRtc], ({ dispatch }, shouldConnectRtc) => {
|
|
1927
|
+
if (shouldConnectRtc) {
|
|
1928
|
+
dispatch(doConnectRtc());
|
|
1807
1929
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
props: {},
|
|
1813
|
-
})));
|
|
1930
|
+
});
|
|
1931
|
+
const selectShouldInitializeRtc = createSelector(selectRtcManager, selectRtcManagerInitialized, selectLocalMediaStatus, (rtcManager, rtcManagerInitialized, localMediaStatus) => {
|
|
1932
|
+
if (localMediaStatus === "started" && rtcManager && !rtcManagerInitialized) {
|
|
1933
|
+
return true;
|
|
1814
1934
|
}
|
|
1935
|
+
return false;
|
|
1815
1936
|
});
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1937
|
+
createReactor([selectShouldInitializeRtc], ({ dispatch }, shouldInitializeRtc) => {
|
|
1938
|
+
if (shouldInitializeRtc) {
|
|
1939
|
+
dispatch(doRtcManagerInitialize());
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
const selectShouldDisconnectRtc = createSelector(selectRtcStatus, selectAppIsActive, (status, appIsActive) => {
|
|
1943
|
+
if (!appIsActive && !["inactive", "disconnected"].includes(status)) {
|
|
1944
|
+
return true;
|
|
1945
|
+
}
|
|
1946
|
+
return false;
|
|
1947
|
+
});
|
|
1948
|
+
createReactor([selectShouldDisconnectRtc], ({ dispatch }, shouldDisconnectRtc) => {
|
|
1949
|
+
if (shouldDisconnectRtc) {
|
|
1950
|
+
dispatch(doDisconnectRtc());
|
|
1951
|
+
}
|
|
1952
|
+
});
|
|
1953
|
+
const selectStreamsToAccept = createSelector(selectRtcStatus, selectRemoteClients, (rtcStatus, remoteParticipants) => {
|
|
1954
|
+
if (rtcStatus !== "ready") {
|
|
1955
|
+
return [];
|
|
1956
|
+
}
|
|
1957
|
+
const upd = [];
|
|
1958
|
+
for (const client of remoteParticipants) {
|
|
1959
|
+
const { streams, id: clientId, newJoiner } = client;
|
|
1960
|
+
for (let i = 0; i < streams.length; i++) {
|
|
1961
|
+
let streamId = streams[i].id;
|
|
1962
|
+
let state = streams[i].state;
|
|
1963
|
+
if ((streams === null || streams === void 0 ? void 0 : streams.length) > 1 && streams[1].id === "0") {
|
|
1964
|
+
if (i === 0) {
|
|
1965
|
+
streamId = streams[1].id;
|
|
1966
|
+
state = streams[1].state;
|
|
1967
|
+
}
|
|
1968
|
+
else if (i === 1) {
|
|
1969
|
+
streamId = streams[0].id;
|
|
1970
|
+
state = streams[0].state;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
{
|
|
1974
|
+
if (state === "done_accept")
|
|
1975
|
+
continue;
|
|
1976
|
+
upd.push({
|
|
1977
|
+
clientId,
|
|
1978
|
+
streamId,
|
|
1979
|
+
state: `${newJoiner && streamId === "0" ? "new" : "to"}_accept`,
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1826
1982
|
}
|
|
1827
|
-
}
|
|
1983
|
+
}
|
|
1984
|
+
return upd;
|
|
1985
|
+
});
|
|
1986
|
+
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
1987
|
+
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
1988
|
+
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
1989
|
+
}
|
|
1828
1990
|
});
|
|
1829
1991
|
|
|
1830
1992
|
function isStreamerClient(client) {
|
|
@@ -1936,313 +2098,256 @@ const selectAllClientViews = createSelector(selectLocalParticipantView, selectRe
|
|
|
1936
2098
|
return [...(localParticipant ? [localParticipant] : []), ...remoteParticipants];
|
|
1937
2099
|
});
|
|
1938
2100
|
|
|
1939
|
-
const createWebRtcEmitter = (dispatch) => {
|
|
1940
|
-
return {
|
|
1941
|
-
emit: (eventName, data) => {
|
|
1942
|
-
if (eventName === "rtc_manager_created") {
|
|
1943
|
-
dispatch(doRtcManagerCreated(data));
|
|
1944
|
-
}
|
|
1945
|
-
else if (eventName === "stream_added") {
|
|
1946
|
-
dispatch(rtcEvents.streamAdded(data));
|
|
1947
|
-
}
|
|
1948
|
-
else if (eventName === "rtc_manager_destroyed") {
|
|
1949
|
-
dispatch(rtcManagerDestroyed());
|
|
1950
|
-
}
|
|
1951
|
-
else ;
|
|
1952
|
-
},
|
|
1953
|
-
};
|
|
1954
|
-
};
|
|
1955
2101
|
const initialState$4 = {
|
|
1956
|
-
|
|
1957
|
-
error: null,
|
|
1958
|
-
isCreatingDispatcher: false,
|
|
1959
|
-
reportedStreamResolutions: {},
|
|
1960
|
-
rtcManager: null,
|
|
1961
|
-
rtcManagerDispatcher: null,
|
|
1962
|
-
rtcManagerInitialized: false,
|
|
1963
|
-
status: "inactive",
|
|
1964
|
-
isAcceptingStreams: false,
|
|
2102
|
+
running: false,
|
|
1965
2103
|
};
|
|
1966
|
-
const
|
|
1967
|
-
name: "
|
|
2104
|
+
const connectionMonitorSlice = createSlice({
|
|
2105
|
+
name: "connectionMonitor",
|
|
1968
2106
|
initialState: initialState$4,
|
|
1969
2107
|
reducers: {
|
|
1970
|
-
|
|
1971
|
-
return Object.assign(Object.assign({}, state), {
|
|
1972
|
-
},
|
|
1973
|
-
resolutionReported: (state, action) => {
|
|
1974
|
-
const { streamId, width, height } = action.payload;
|
|
1975
|
-
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
2108
|
+
connectionMonitorStarted: (state, action) => {
|
|
2109
|
+
return Object.assign(Object.assign({}, state), { running: true, stopCallbackFunction: action.payload.stopIssueSubscription });
|
|
1976
2110
|
},
|
|
1977
|
-
|
|
2111
|
+
connectionMonitorStopped: () => {
|
|
1978
2112
|
return Object.assign({}, initialState$4);
|
|
1979
2113
|
},
|
|
1980
|
-
rtcDispatcherCreated: (state, action) => {
|
|
1981
|
-
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
1982
|
-
},
|
|
1983
|
-
rtcManagerCreated: (state, action) => {
|
|
1984
|
-
return Object.assign(Object.assign({}, state), { rtcManager: action.payload, status: "ready" });
|
|
1985
|
-
},
|
|
1986
|
-
rtcManagerDestroyed: (state) => {
|
|
1987
|
-
return Object.assign(Object.assign({}, state), { rtcManager: null });
|
|
1988
|
-
},
|
|
1989
|
-
rtcManagerInitialized: (state) => {
|
|
1990
|
-
return Object.assign(Object.assign({}, state), { rtcManagerInitialized: true });
|
|
1991
|
-
},
|
|
1992
|
-
},
|
|
1993
|
-
extraReducers: (builder) => {
|
|
1994
|
-
builder.addCase(socketReconnecting, (state) => {
|
|
1995
|
-
return Object.assign(Object.assign({}, state), { status: "reconnecting" });
|
|
1996
|
-
});
|
|
1997
|
-
builder.addCase(signalEvents.roomJoined, (state) => {
|
|
1998
|
-
return Object.assign(Object.assign({}, state), { status: state.status === "reconnecting" ? "ready" : state.status });
|
|
1999
|
-
});
|
|
2000
2114
|
},
|
|
2001
2115
|
});
|
|
2002
|
-
const {
|
|
2003
|
-
const
|
|
2004
|
-
|
|
2005
|
-
|
|
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
|
-
|
|
2116
|
+
const { connectionMonitorStarted, connectionMonitorStopped } = connectionMonitorSlice.actions;
|
|
2117
|
+
const doStartConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2118
|
+
setClientProvider(() => {
|
|
2119
|
+
const state = getState();
|
|
2120
|
+
const clientViews = selectAllClientViews(state).map((clientView) => {
|
|
2121
|
+
var _a, _b;
|
|
2122
|
+
return ({
|
|
2123
|
+
id: clientView.id,
|
|
2124
|
+
clientId: clientView.clientId,
|
|
2125
|
+
isLocalClient: clientView.isLocalClient,
|
|
2126
|
+
audio: {
|
|
2127
|
+
enabled: clientView.isAudioEnabled,
|
|
2128
|
+
track: (_a = clientView.stream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0],
|
|
2129
|
+
},
|
|
2130
|
+
video: {
|
|
2131
|
+
enabled: clientView.isVideoEnabled,
|
|
2132
|
+
track: (_b = clientView.stream) === null || _b === void 0 ? void 0 : _b.getVideoTracks()[0],
|
|
2133
|
+
},
|
|
2134
|
+
isPresentation: clientView.isPresentation,
|
|
2135
|
+
});
|
|
2136
|
+
});
|
|
2137
|
+
return clientViews;
|
|
2138
|
+
});
|
|
2139
|
+
const issueMonitorSubscription = subscribeIssues({
|
|
2140
|
+
onUpdatedIssues: (issuesAndMetricsByClients) => {
|
|
2141
|
+
var _a;
|
|
2142
|
+
const state = getState();
|
|
2143
|
+
const rtcManager = selectRtcManager(state);
|
|
2144
|
+
if (!rtcManager) {
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
let lossSend = 0;
|
|
2148
|
+
let lossReceive = 0;
|
|
2149
|
+
let bitrateSend = 0;
|
|
2150
|
+
let bitrateReceive = 0;
|
|
2151
|
+
Object.entries(issuesAndMetricsByClients.aggregated.metrics).forEach(([key, value]) => {
|
|
2152
|
+
if (/loc.*packetloss/.test(key))
|
|
2153
|
+
lossSend = Math.max(lossSend, value.curMax);
|
|
2154
|
+
if (/rem.*packetloss/.test(key))
|
|
2155
|
+
lossReceive = Math.max(lossReceive, value.curMax);
|
|
2156
|
+
if (/loc.*bitrate/.test(key))
|
|
2157
|
+
bitrateSend += value.curSum;
|
|
2158
|
+
if (/rem.*bitrate/.test(key))
|
|
2159
|
+
bitrateReceive += value.curSum;
|
|
2160
|
+
});
|
|
2161
|
+
rtcManager.sendStatsCustomEvent("insightsStats", {
|
|
2162
|
+
ls: Math.round(lossSend * 1000) / 1000,
|
|
2163
|
+
lr: Math.round(lossReceive * 1000) / 1000,
|
|
2164
|
+
bs: Math.round(bitrateSend),
|
|
2165
|
+
br: Math.round(bitrateReceive),
|
|
2166
|
+
cpu: (_a = issuesAndMetricsByClients.aggregated.metrics["global-cpu-pressure"]) === null || _a === void 0 ? void 0 : _a.curSum,
|
|
2167
|
+
_time: Date.now(),
|
|
2168
|
+
});
|
|
2036
2169
|
},
|
|
2037
2170
|
});
|
|
2038
|
-
dispatch(
|
|
2039
|
-
});
|
|
2040
|
-
const doDisconnectRtc = createAppThunk(() => (dispatch, getState) => {
|
|
2041
|
-
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
2042
|
-
if (rtcManager) {
|
|
2043
|
-
rtcManager.disconnectAll();
|
|
2044
|
-
}
|
|
2045
|
-
dispatch(rtcDisconnected());
|
|
2171
|
+
dispatch(connectionMonitorStarted({ stopIssueSubscription: issueMonitorSubscription.stop }));
|
|
2046
2172
|
});
|
|
2047
|
-
const
|
|
2048
|
-
var _a;
|
|
2049
|
-
dispatch(isAcceptingStreams(true));
|
|
2173
|
+
const doStopConnectionMonitor = createAppThunk(() => (dispatch, getState) => {
|
|
2050
2174
|
const state = getState();
|
|
2051
|
-
const
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
throw new Error("No rtc manager");
|
|
2055
|
-
}
|
|
2056
|
-
const activeBreakout = false;
|
|
2057
|
-
const shouldAcceptNewClients = (_a = rtcManager.shouldAcceptStreamsFromBothSides) === null || _a === void 0 ? void 0 : _a.call(rtcManager);
|
|
2058
|
-
const updates = [];
|
|
2059
|
-
for (const { clientId, streamId, state } of payload) {
|
|
2060
|
-
const participant = remoteClients.find((p) => p.id === clientId);
|
|
2061
|
-
if (!participant)
|
|
2062
|
-
continue;
|
|
2063
|
-
if (state === "to_accept" ||
|
|
2064
|
-
(state === "new_accept" && shouldAcceptNewClients) ||
|
|
2065
|
-
(state === "old_accept" && !shouldAcceptNewClients)) {
|
|
2066
|
-
const enforceTurnProtocol = participant.isDialIn ? "onlytls" : undefined;
|
|
2067
|
-
rtcManager.acceptNewStream({
|
|
2068
|
-
streamId: streamId === "0" ? clientId : streamId,
|
|
2069
|
-
clientId,
|
|
2070
|
-
shouldAddLocalVideo: streamId === "0",
|
|
2071
|
-
activeBreakout,
|
|
2072
|
-
enforceTurnProtocol,
|
|
2073
|
-
});
|
|
2074
|
-
}
|
|
2075
|
-
else if (state === "new_accept" || state === "old_accept") ;
|
|
2076
|
-
else if (state === "to_unaccept") {
|
|
2077
|
-
rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.disconnect(streamId === "0" ? clientId : streamId, activeBreakout);
|
|
2078
|
-
}
|
|
2079
|
-
else if (state !== "done_accept") {
|
|
2080
|
-
continue;
|
|
2081
|
-
}
|
|
2082
|
-
else ;
|
|
2083
|
-
updates.push({ clientId, streamId, state: state.replace(/to_|new_|old_/, "done_") });
|
|
2175
|
+
const stopCallbackFn = selectStopCallbackFunction(state);
|
|
2176
|
+
if (stopCallbackFn) {
|
|
2177
|
+
stopCallbackFn();
|
|
2084
2178
|
}
|
|
2085
|
-
dispatch(
|
|
2086
|
-
dispatch(isAcceptingStreams(false));
|
|
2179
|
+
dispatch(connectionMonitorStopped());
|
|
2087
2180
|
});
|
|
2088
|
-
const
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
if (!
|
|
2092
|
-
return;
|
|
2093
|
-
}
|
|
2094
|
-
const old = reportedStreamResolutions[streamId];
|
|
2095
|
-
if (!old || old.width !== width || old.height !== height) {
|
|
2096
|
-
rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
|
|
2181
|
+
const selectConnectionMonitorIsRunning = (state) => state.connectionMonitor.running;
|
|
2182
|
+
const selectStopCallbackFunction = (state) => state.connectionMonitor.stopCallbackFunction;
|
|
2183
|
+
const selectShouldStartConnectionMonitor = createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2184
|
+
if (!isRunning && roomConnectionStatus === "connected") {
|
|
2185
|
+
return true;
|
|
2097
2186
|
}
|
|
2098
|
-
|
|
2187
|
+
return false;
|
|
2099
2188
|
});
|
|
2100
|
-
const
|
|
2101
|
-
|
|
2102
|
-
|
|
2189
|
+
const selectShouldStopConnectionMonitor = createSelector(selectRoomConnectionStatus, selectConnectionMonitorIsRunning, (roomConnectionStatus, isRunning) => {
|
|
2190
|
+
if (isRunning && ["kicked", "left"].includes(roomConnectionStatus)) {
|
|
2191
|
+
return true;
|
|
2192
|
+
}
|
|
2193
|
+
return false;
|
|
2103
2194
|
});
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
const isCameraEnabled = selectIsCameraEnabled(getState());
|
|
2108
|
-
const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
|
|
2109
|
-
if (localMediaStream && rtcManager) {
|
|
2110
|
-
rtcManager.addNewStream("0", localMediaStream, !isMicrophoneEnabled, !isCameraEnabled);
|
|
2195
|
+
createReactor([selectShouldStartConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2196
|
+
if (shouldStartConnectionMonitor) {
|
|
2197
|
+
dispatch(doStartConnectionMonitor());
|
|
2111
2198
|
}
|
|
2112
|
-
dispatch(rtcManagerInitialized());
|
|
2113
2199
|
});
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
const selectRtcIsCreatingDispatcher = (state) => state.rtcConnection.isCreatingDispatcher;
|
|
2119
|
-
const selectRtcStatus = (state) => state.rtcConnection.status;
|
|
2120
|
-
const selectIsAcceptingStreams = (state) => state.rtcConnection.isAcceptingStreams;
|
|
2121
|
-
startAppListening({
|
|
2122
|
-
actionCreator: doSetDevice.fulfilled,
|
|
2123
|
-
effect: ({ payload }, { getState }) => {
|
|
2124
|
-
const { replacedTracks } = payload;
|
|
2125
|
-
const { rtcManager } = selectRtcConnectionRaw(getState());
|
|
2126
|
-
const stream = selectLocalMediaStream(getState());
|
|
2127
|
-
const replace = (kind, oldTrack) => {
|
|
2128
|
-
const track = stream === null || stream === void 0 ? void 0 : stream.getTracks().find((t) => t.kind === kind);
|
|
2129
|
-
return track && (rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.replaceTrack(oldTrack, track));
|
|
2130
|
-
};
|
|
2131
|
-
replacedTracks === null || replacedTracks === void 0 ? void 0 : replacedTracks.forEach((t) => {
|
|
2132
|
-
replace(t.kind, t);
|
|
2133
|
-
});
|
|
2134
|
-
},
|
|
2200
|
+
createReactor([selectShouldStopConnectionMonitor], ({ dispatch }, shouldStartConnectionMonitor) => {
|
|
2201
|
+
if (shouldStartConnectionMonitor) {
|
|
2202
|
+
dispatch(doStopConnectionMonitor());
|
|
2203
|
+
}
|
|
2135
2204
|
});
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2205
|
+
|
|
2206
|
+
const emitter = new EventEmitter();
|
|
2207
|
+
function createNotificationEvent(payload) {
|
|
2208
|
+
const notificationEvent = Object.assign(Object.assign({}, payload), { timestamp: Date.now() });
|
|
2209
|
+
return notificationEvent;
|
|
2210
|
+
}
|
|
2211
|
+
const initialNotificationsState = {
|
|
2212
|
+
emitter,
|
|
2213
|
+
events: [],
|
|
2214
|
+
};
|
|
2215
|
+
const notificationsSlice = createSlice({
|
|
2216
|
+
name: "notifications",
|
|
2217
|
+
initialState: initialNotificationsState,
|
|
2218
|
+
reducers: {
|
|
2219
|
+
addNotification: (state, action) => {
|
|
2220
|
+
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
2221
|
+
},
|
|
2222
|
+
doClearNotifications: (state) => {
|
|
2223
|
+
return Object.assign(Object.assign({}, state), { events: [] });
|
|
2224
|
+
},
|
|
2142
2225
|
},
|
|
2143
2226
|
});
|
|
2227
|
+
const { doClearNotifications } = notificationsSlice.actions;
|
|
2228
|
+
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
2229
|
+
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
2230
|
+
const state = getState();
|
|
2231
|
+
const emitter = selectNotificationsEmitter(state);
|
|
2232
|
+
emitter.emit(payload.type, payload);
|
|
2233
|
+
emitter.emit("*", payload);
|
|
2234
|
+
});
|
|
2235
|
+
const selectNotificationsRaw = (state) => state.notifications;
|
|
2236
|
+
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
2237
|
+
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
2144
2238
|
startAppListening({
|
|
2145
|
-
actionCreator:
|
|
2146
|
-
effect: (
|
|
2147
|
-
const
|
|
2148
|
-
|
|
2239
|
+
actionCreator: signalEvents.chatMessage,
|
|
2240
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2241
|
+
const state = getState();
|
|
2242
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === payload.senderId);
|
|
2243
|
+
if (!client) {
|
|
2244
|
+
console.warn("Could not find remote client that sent chat message");
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2248
|
+
type: "chatMessageReceived",
|
|
2249
|
+
message: `${client.displayName} says: ${payload.text}`,
|
|
2250
|
+
props: {
|
|
2251
|
+
client,
|
|
2252
|
+
chatMessage: {
|
|
2253
|
+
senderId: payload.senderId,
|
|
2254
|
+
timestamp: payload.timestamp,
|
|
2255
|
+
text: payload.text,
|
|
2256
|
+
},
|
|
2257
|
+
},
|
|
2258
|
+
})));
|
|
2149
2259
|
},
|
|
2150
2260
|
});
|
|
2151
2261
|
startAppListening({
|
|
2152
|
-
actionCreator:
|
|
2153
|
-
effect: ({ payload }, { getState }) => {
|
|
2154
|
-
const {
|
|
2155
|
-
const
|
|
2156
|
-
|
|
2262
|
+
actionCreator: signalEvents.audioEnableRequested,
|
|
2263
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
2264
|
+
const { enable, requestedByClientId } = payload;
|
|
2265
|
+
const state = getState();
|
|
2266
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === requestedByClientId);
|
|
2267
|
+
if (!client) {
|
|
2268
|
+
console.warn("Could not find remote client that requested a local audio change");
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2272
|
+
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
2273
|
+
message: enable
|
|
2274
|
+
? `${client.displayName} has requested for you to speak`
|
|
2275
|
+
: `${client.displayName} has muted your microphone`,
|
|
2276
|
+
props: {
|
|
2277
|
+
client,
|
|
2278
|
+
enable,
|
|
2279
|
+
},
|
|
2280
|
+
})));
|
|
2157
2281
|
},
|
|
2158
2282
|
});
|
|
2159
2283
|
startAppListening({
|
|
2160
|
-
actionCreator:
|
|
2161
|
-
effect: ({
|
|
2284
|
+
actionCreator: signalEvents.clientMetadataReceived,
|
|
2285
|
+
effect: (action, { dispatch, getOriginalState, getState }) => {
|
|
2162
2286
|
var _a;
|
|
2163
|
-
const
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2287
|
+
const { error, payload } = action.payload;
|
|
2288
|
+
if (error || !payload) {
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
const { clientId, stickyReaction } = payload;
|
|
2292
|
+
const state = getState();
|
|
2293
|
+
const canAskToSpeak = selectIsAuthorizedToAskToSpeak(state);
|
|
2294
|
+
if (!canAskToSpeak) {
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
2298
|
+
if (!client) {
|
|
2299
|
+
console.warn("Could not find remote client that provided updated metadata");
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
const previousState = getOriginalState();
|
|
2303
|
+
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
2304
|
+
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
2305
|
+
(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)) {
|
|
2306
|
+
return;
|
|
2173
2307
|
}
|
|
2308
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2309
|
+
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
2310
|
+
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
2311
|
+
props: {
|
|
2312
|
+
client,
|
|
2313
|
+
stickyReaction,
|
|
2314
|
+
},
|
|
2315
|
+
})));
|
|
2174
2316
|
},
|
|
2175
2317
|
});
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
});
|
|
2182
|
-
createReactor([selectShouldConnectRtc], ({ dispatch }, shouldConnectRtc) => {
|
|
2183
|
-
if (shouldConnectRtc) {
|
|
2184
|
-
dispatch(doConnectRtc());
|
|
2185
|
-
}
|
|
2186
|
-
});
|
|
2187
|
-
const selectShouldInitializeRtc = createSelector(selectRtcManager, selectRtcManagerInitialized, selectLocalMediaStatus, (rtcManager, rtcManagerInitialized, localMediaStatus) => {
|
|
2188
|
-
if (localMediaStatus === "started" && rtcManager && !rtcManagerInitialized) {
|
|
2189
|
-
return true;
|
|
2190
|
-
}
|
|
2191
|
-
return false;
|
|
2192
|
-
});
|
|
2193
|
-
createReactor([selectShouldInitializeRtc], ({ dispatch }, shouldInitializeRtc) => {
|
|
2194
|
-
if (shouldInitializeRtc) {
|
|
2195
|
-
dispatch(doRtcManagerInitialize());
|
|
2318
|
+
createReactor([selectSignalStatus], ({ dispatch, getState }, signalStatus) => {
|
|
2319
|
+
const state = getState();
|
|
2320
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
2321
|
+
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
2322
|
+
return;
|
|
2196
2323
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2324
|
+
if (signalStatus === "disconnected") {
|
|
2325
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2326
|
+
type: "signalTrouble",
|
|
2327
|
+
message: `Network connection lost. Trying to reconnect you...`,
|
|
2328
|
+
props: {},
|
|
2329
|
+
})));
|
|
2201
2330
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2331
|
+
else if (signalStatus === "connected") {
|
|
2332
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2333
|
+
type: "signalOk",
|
|
2334
|
+
message: `Network connection available`,
|
|
2335
|
+
props: {},
|
|
2336
|
+
})));
|
|
2207
2337
|
}
|
|
2208
2338
|
});
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
if ((streams === null || streams === void 0 ? void 0 : streams.length) > 1 && streams[1].id === "0") {
|
|
2220
|
-
if (i === 0) {
|
|
2221
|
-
streamId = streams[1].id;
|
|
2222
|
-
state = streams[1].state;
|
|
2223
|
-
}
|
|
2224
|
-
else if (i === 1) {
|
|
2225
|
-
streamId = streams[0].id;
|
|
2226
|
-
state = streams[0].state;
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
{
|
|
2230
|
-
if (state === "done_accept")
|
|
2231
|
-
continue;
|
|
2232
|
-
upd.push({
|
|
2233
|
-
clientId,
|
|
2234
|
-
streamId,
|
|
2235
|
-
state: `${newJoiner && streamId === "0" ? "new" : "to"}_accept`,
|
|
2236
|
-
});
|
|
2237
|
-
}
|
|
2339
|
+
startAppListening({
|
|
2340
|
+
actionCreator: signalEvents.clientUnableToJoin,
|
|
2341
|
+
effect: (action, { dispatch }) => {
|
|
2342
|
+
var _a;
|
|
2343
|
+
if (((_a = action.payload) === null || _a === void 0 ? void 0 : _a.error) === "room_full") {
|
|
2344
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
2345
|
+
type: "clientUnableToJoinFullRoom",
|
|
2346
|
+
message: "Someone tried to join but the room is full and at capacity.",
|
|
2347
|
+
props: {},
|
|
2348
|
+
})));
|
|
2238
2349
|
}
|
|
2239
|
-
}
|
|
2240
|
-
return upd;
|
|
2241
|
-
});
|
|
2242
|
-
createReactor([selectStreamsToAccept, selectIsAcceptingStreams], ({ dispatch }, streamsToAccept, isAcceptingStreams) => {
|
|
2243
|
-
if (0 < streamsToAccept.length && !isAcceptingStreams) {
|
|
2244
|
-
dispatch(doHandleAcceptStreams(streamsToAccept));
|
|
2245
|
-
}
|
|
2350
|
+
},
|
|
2246
2351
|
});
|
|
2247
2352
|
|
|
2248
2353
|
const rtcAnalyticsCustomEvents = {
|
|
@@ -2614,6 +2719,7 @@ const appReducer = combineReducers({
|
|
|
2614
2719
|
authorization: authorizationSlice.reducer,
|
|
2615
2720
|
chat: chatSlice.reducer,
|
|
2616
2721
|
cloudRecording: cloudRecordingSlice.reducer,
|
|
2722
|
+
connectionMonitor: connectionMonitorSlice.reducer,
|
|
2617
2723
|
deviceCredentials: deviceCredentialsSlice.reducer,
|
|
2618
2724
|
localMedia: localMediaSlice.reducer,
|
|
2619
2725
|
localParticipant: localParticipantSlice.reducer,
|
|
@@ -3677,4 +3783,4 @@ function createServices() {
|
|
|
3677
3783
|
};
|
|
3678
3784
|
}
|
|
3679
3785
|
|
|
3680
|
-
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, addSpotlight, appSlice, authorizationSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppStart, doAppStop, doClearNotifications, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doEndMeeting, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKickParticipant, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRemoveSpotlight, doRequestAudioEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSendClientMetadata, doSetDevice, doSetDisplayName, doSetLocalStickyReaction, doSetNotification, doSignalConnect, doSignalDisconnect, doSignalIdentifyDevice, doSpotlightParticipant, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doToggleLowDataMode, doUpdateDeviceList, getAudioTrack, getFakeMediaStream, getVideoTrack, hasValue, initialCloudRecordingState, initialLocalMediaState, initialNotificationsState, initialState$
|
|
3786
|
+
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, addSpotlight, appSlice, authorizationSlice, chatSlice, cloudRecordingSlice, connectionMonitorSlice, connectionMonitorStarted, connectionMonitorStopped, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppStart, doAppStop, doClearNotifications, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doEndMeeting, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKickParticipant, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRemoveSpotlight, doRequestAudioEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSendClientMetadata, doSetDevice, doSetDisplayName, doSetLocalStickyReaction, doSetNotification, doSignalConnect, doSignalDisconnect, doSignalIdentifyDevice, doSpotlightParticipant, doStartCloudRecording, doStartConnectionMonitor, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopConnectionMonitor, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doToggleLowDataMode, doUpdateDeviceList, getAudioTrack, getFakeMediaStream, getVideoTrack, hasValue, initialCloudRecordingState, initialLocalMediaState, initialNotificationsState, initialState$g as initialState, isAcceptingStreams, isClientSpotlighted, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, notificationsSlice, observeStore, organizationSlice, parseRoomUrlAndSubdomain, parseUnverifiedRoomKeyData, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, removeSpotlight, resolutionReported, roomConnectionSlice, roomSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAllClientViews, selectAppDisplayName, selectAppExternalId, selectAppInitialConfig, selectAppIsActive, selectAppIsDialIn, selectAppIsNodeSdk, selectAppRaw, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAuthorizationRoleName, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectConnectionMonitorIsRunning, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectCurrentSpeakerDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsAuthorizedToAskToSpeak, selectIsAuthorizedToEndMeeting, selectIsAuthorizedToKickClient, selectIsAuthorizedToLockRoom, selectIsAuthorizedToRequestAudioEnable, selectIsAuthorizedToSpotlight, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsLocalParticipantSpotlighted, selectIsLowDataModeEnabled, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantClientClaim, selectLocalParticipantDisplayName, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalParticipantStickyReaction, selectLocalParticipantView, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectNotificationsEmitter, selectNotificationsEvents, selectNotificationsRaw, selectNumClients, selectNumParticipants, selectOrganizationId, selectOrganizationRaw, selectRemoteClientViews, selectRemoteClients, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRoomIsLocked, selectRoomKey, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectShouldStartConnectionMonitor, selectShouldStopConnectionMonitor, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectSpotlightedClientViews, selectSpotlights, selectSpotlightsRaw, selectStopCallbackFunction, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setCurrentSpeakerDeviceId, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, signalEvents, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, spotlightsSlice, startAppListening, stopScreenshare, streamIdForClient, streamStatusUpdated, streamingSlice, toggleCameraEnabled, toggleLowDataModeEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice };
|