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