@whereby.com/core 0.15.2 → 0.16.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 +520 -170
- package/dist/index.d.cts +2434 -263
- package/dist/index.d.mts +2434 -263
- package/dist/index.d.ts +2434 -263
- package/dist/index.mjs +491 -169
- package/package.json +2 -5
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createAsyncThunk, createListenerMiddleware, addListener, createSlice, createAction, createSelector, isAnyOf, combineReducers, configureStore } from '@reduxjs/toolkit';
|
|
2
2
|
import { ServerSocket, getDeviceData, getStream, getUpdatedDevices, RtcManagerDispatcher, assert, fromLocation } from '@whereby.com/media';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
3
4
|
import { Chrome111 } from 'mediasoup-client/lib/handlers/Chrome111.js';
|
|
4
5
|
import nodeBtoa from 'btoa';
|
|
5
6
|
import axios from 'axios';
|
|
6
|
-
import EventEmitter from 'events';
|
|
7
7
|
|
|
8
8
|
function createAppAsyncThunk(typePrefix, payloadCreator) {
|
|
9
9
|
return createAsyncThunk(typePrefix, payloadCreator);
|
|
@@ -43,9 +43,9 @@ const createReactor = (selectors, callback) => {
|
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
const coreVersion = "0.
|
|
46
|
+
const coreVersion = "0.16.0";
|
|
47
47
|
|
|
48
|
-
const initialState$
|
|
48
|
+
const initialState$f = {
|
|
49
49
|
isNodeSdk: false,
|
|
50
50
|
isActive: false,
|
|
51
51
|
roomName: null,
|
|
@@ -56,7 +56,7 @@ const initialState$e = {
|
|
|
56
56
|
};
|
|
57
57
|
const appSlice = createSlice({
|
|
58
58
|
name: "app",
|
|
59
|
-
initialState: initialState$
|
|
59
|
+
initialState: initialState$f,
|
|
60
60
|
reducers: {
|
|
61
61
|
doAppStart: (state, action) => {
|
|
62
62
|
const url = new URL(action.payload.roomUrl);
|
|
@@ -101,6 +101,8 @@ const signalEvents = {
|
|
|
101
101
|
roomSessionEnded: createSignalEventAction("roomSessionEnded"),
|
|
102
102
|
screenshareStarted: createSignalEventAction("screenshareStarted"),
|
|
103
103
|
screenshareStopped: createSignalEventAction("screenshareStopped"),
|
|
104
|
+
spotlightAdded: createSignalEventAction("spotlightAdded"),
|
|
105
|
+
spotlightRemoved: createSignalEventAction("spotlightRemoved"),
|
|
104
106
|
streamingStopped: createSignalEventAction("streamingStopped"),
|
|
105
107
|
videoEnabled: createSignalEventAction("videoEnabled"),
|
|
106
108
|
};
|
|
@@ -110,14 +112,16 @@ const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
|
|
|
110
112
|
canRequestAudioEnable: ["host"],
|
|
111
113
|
canKickClient: ["host"],
|
|
112
114
|
canEndMeeting: ["host"],
|
|
115
|
+
canAskToSpeak: ["host"],
|
|
116
|
+
canSpotlight: ["host"],
|
|
113
117
|
};
|
|
114
|
-
const initialState$
|
|
118
|
+
const initialState$e = {
|
|
115
119
|
roomKey: null,
|
|
116
120
|
roleName: "none",
|
|
117
121
|
};
|
|
118
122
|
const authorizationSlice = createSlice({
|
|
119
123
|
name: "authorization",
|
|
120
|
-
initialState: initialState$
|
|
124
|
+
initialState: initialState$e,
|
|
121
125
|
reducers: {
|
|
122
126
|
setRoomKey: (state, action) => {
|
|
123
127
|
return Object.assign(Object.assign({}, state), { roomKey: action.payload });
|
|
@@ -141,6 +145,8 @@ const selectIsAuthorizedToLockRoom = createSelector(selectAuthorizationRoleName,
|
|
|
141
145
|
const selectIsAuthorizedToRequestAudioEnable = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
|
|
142
146
|
const selectIsAuthorizedToKickClient = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canKickClient.includes(localParticipantRole));
|
|
143
147
|
const selectIsAuthorizedToEndMeeting = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canEndMeeting.includes(localParticipantRole));
|
|
148
|
+
const selectIsAuthorizedToAskToSpeak = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canAskToSpeak.includes(localParticipantRole));
|
|
149
|
+
const selectIsAuthorizedToSpotlight = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canSpotlight.includes(localParticipantRole));
|
|
144
150
|
|
|
145
151
|
/******************************************************************************
|
|
146
152
|
Copyright (c) Microsoft Corporation.
|
|
@@ -186,13 +192,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
186
192
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
187
193
|
};
|
|
188
194
|
|
|
189
|
-
const initialState$
|
|
195
|
+
const initialState$d = {
|
|
190
196
|
isFetching: false,
|
|
191
197
|
data: null,
|
|
192
198
|
};
|
|
193
199
|
const deviceCredentialsSlice = createSlice({
|
|
194
200
|
name: "deviceCredentials",
|
|
195
|
-
initialState: initialState$
|
|
201
|
+
initialState: initialState$d,
|
|
196
202
|
reducers: {},
|
|
197
203
|
extraReducers: (builder) => {
|
|
198
204
|
builder.addCase(doGetDeviceCredentials.pending, (state) => {
|
|
@@ -252,6 +258,8 @@ function forwardSocketEvents(socket, dispatch) {
|
|
|
252
258
|
socket.on("cloud_recording_started", (payload) => dispatch(signalEvents.cloudRecordingStarted(payload)));
|
|
253
259
|
socket.on("cloud_recording_stopped", () => dispatch(signalEvents.cloudRecordingStopped()));
|
|
254
260
|
socket.on("streaming_stopped", () => dispatch(signalEvents.streamingStopped()));
|
|
261
|
+
socket.on("spotlight_added", (payload) => dispatch(signalEvents.spotlightAdded(payload)));
|
|
262
|
+
socket.on("spotlight_removed", (payload) => dispatch(signalEvents.spotlightRemoved(payload)));
|
|
255
263
|
}
|
|
256
264
|
const SIGNAL_BASE_URL = "wss://signal.appearin.net" ;
|
|
257
265
|
function createSocket() {
|
|
@@ -262,7 +270,7 @@ function createSocket() {
|
|
|
262
270
|
};
|
|
263
271
|
return new ServerSocket(socketHost, socketOverrides);
|
|
264
272
|
}
|
|
265
|
-
const initialState$
|
|
273
|
+
const initialState$c = {
|
|
266
274
|
deviceIdentified: false,
|
|
267
275
|
isIdentifyingDevice: false,
|
|
268
276
|
status: "ready",
|
|
@@ -270,7 +278,7 @@ const initialState$b = {
|
|
|
270
278
|
};
|
|
271
279
|
const signalConnectionSlice = createSlice({
|
|
272
280
|
name: "signalConnection",
|
|
273
|
-
initialState: initialState$
|
|
281
|
+
initialState: initialState$c,
|
|
274
282
|
reducers: {
|
|
275
283
|
socketConnecting: (state) => {
|
|
276
284
|
return Object.assign(Object.assign({}, state), { status: "connecting" });
|
|
@@ -374,12 +382,12 @@ startAppListening({
|
|
|
374
382
|
},
|
|
375
383
|
});
|
|
376
384
|
|
|
377
|
-
const initialState$
|
|
385
|
+
const initialState$b = {
|
|
378
386
|
chatMessages: [],
|
|
379
387
|
};
|
|
380
388
|
const chatSlice = createSlice({
|
|
381
389
|
name: "chat",
|
|
382
|
-
initialState: initialState$
|
|
390
|
+
initialState: initialState$b,
|
|
383
391
|
reducers: {},
|
|
384
392
|
extraReducers(builder) {
|
|
385
393
|
builder.addCase(signalEvents.chatMessage, (state, action) => {
|
|
@@ -591,9 +599,11 @@ function parseUnverifiedRoomKeyData(roomKey) {
|
|
|
591
599
|
const initialLocalMediaState = {
|
|
592
600
|
busyDeviceIds: [],
|
|
593
601
|
cameraEnabled: false,
|
|
602
|
+
currentSpeakerDeviceId: "default",
|
|
594
603
|
devices: [],
|
|
595
604
|
isSettingCameraDevice: false,
|
|
596
605
|
isSettingMicrophoneDevice: false,
|
|
606
|
+
isSettingSpeakerDevice: false,
|
|
597
607
|
isTogglingCamera: false,
|
|
598
608
|
lowDataMode: false,
|
|
599
609
|
microphoneEnabled: false,
|
|
@@ -625,6 +635,10 @@ const localMediaSlice = createSlice({
|
|
|
625
635
|
setCurrentMicrophoneDeviceId(state, action) {
|
|
626
636
|
return Object.assign(Object.assign({}, state), { currentMicrophoneDeviceId: action.payload.deviceId });
|
|
627
637
|
},
|
|
638
|
+
setCurrentSpeakerDeviceId(state, action) {
|
|
639
|
+
var _a;
|
|
640
|
+
return Object.assign(Object.assign({}, state), { currentSpeakerDeviceId: (_a = action.payload.deviceId) !== null && _a !== void 0 ? _a : "default" });
|
|
641
|
+
},
|
|
628
642
|
toggleLowDataModeEnabled(state, action) {
|
|
629
643
|
var _a;
|
|
630
644
|
return Object.assign(Object.assign({}, state), { lowDataMode: (_a = action.payload.enabled) !== null && _a !== void 0 ? _a : !state.lowDataMode });
|
|
@@ -707,7 +721,7 @@ const localMediaSlice = createSlice({
|
|
|
707
721
|
});
|
|
708
722
|
},
|
|
709
723
|
});
|
|
710
|
-
const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, toggleLowDataModeEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
|
|
724
|
+
const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setCurrentSpeakerDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, toggleLowDataModeEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
|
|
711
725
|
const doToggleCamera = createAppAsyncThunk("localMedia/doToggleCamera", (_, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
712
726
|
const state = getState();
|
|
713
727
|
const stream = selectLocalMediaStream(state);
|
|
@@ -897,6 +911,7 @@ const selectBusyDeviceIds = (state) => state.localMedia.busyDeviceIds;
|
|
|
897
911
|
const selectCameraDeviceError = (state) => state.localMedia.cameraDeviceError;
|
|
898
912
|
const selectCurrentCameraDeviceId = (state) => state.localMedia.currentCameraDeviceId;
|
|
899
913
|
const selectCurrentMicrophoneDeviceId = (state) => state.localMedia.currentMicrophoneDeviceId;
|
|
914
|
+
const selectCurrentSpeakerDeviceId = (state) => state.localMedia.currentSpeakerDeviceId;
|
|
900
915
|
const selectIsCameraEnabled = (state) => state.localMedia.cameraEnabled;
|
|
901
916
|
const selectIsMicrophoneEnabled = (state) => state.localMedia.microphoneEnabled;
|
|
902
917
|
const selectIsLowDataModeEnabled = (state) => state.localMedia.lowDataMode;
|
|
@@ -1033,7 +1048,7 @@ startAppListening({
|
|
|
1033
1048
|
},
|
|
1034
1049
|
});
|
|
1035
1050
|
|
|
1036
|
-
const initialState$
|
|
1051
|
+
const initialState$a = {
|
|
1037
1052
|
displayName: "",
|
|
1038
1053
|
id: "",
|
|
1039
1054
|
isAudioEnabled: true,
|
|
@@ -1043,34 +1058,14 @@ const initialState$9 = {
|
|
|
1043
1058
|
isScreenSharing: false,
|
|
1044
1059
|
roleName: "none",
|
|
1045
1060
|
clientClaim: undefined,
|
|
1061
|
+
stickyReaction: undefined,
|
|
1046
1062
|
};
|
|
1047
|
-
const doEnableAudio = createAppAsyncThunk("localParticipant/doEnableAudio", (payload, { getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1048
|
-
const state = getState();
|
|
1049
|
-
const socket = selectSignalConnectionRaw(state).socket;
|
|
1050
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("enable_audio", { enabled: payload.enabled });
|
|
1051
|
-
return payload.enabled;
|
|
1052
|
-
}));
|
|
1053
|
-
const doEnableVideo = createAppAsyncThunk("localParticipant/doEnableVideo", (payload, { getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1054
|
-
const state = getState();
|
|
1055
|
-
const socket = selectSignalConnectionRaw(state).socket;
|
|
1056
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("enable_video", { enabled: payload.enabled });
|
|
1057
|
-
return payload.enabled;
|
|
1058
|
-
}));
|
|
1059
|
-
const doSetDisplayName = createAppAsyncThunk("localParticipant/doSetDisplayName", (payload, { getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1060
|
-
const state = getState();
|
|
1061
|
-
const socket = selectSignalConnectionRaw(state).socket;
|
|
1062
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("send_client_metadata", {
|
|
1063
|
-
type: "UserData",
|
|
1064
|
-
payload,
|
|
1065
|
-
});
|
|
1066
|
-
return payload.displayName;
|
|
1067
|
-
}));
|
|
1068
1063
|
const localParticipantSlice = createSlice({
|
|
1069
1064
|
name: "localParticipant",
|
|
1070
|
-
initialState: initialState$
|
|
1065
|
+
initialState: initialState$a,
|
|
1071
1066
|
reducers: {
|
|
1072
|
-
|
|
1073
|
-
return Object.assign(Object.assign({}, state), action.payload);
|
|
1067
|
+
doSetDisplayName: (state, action) => {
|
|
1068
|
+
return Object.assign(Object.assign({}, state), { displayName: action.payload.displayName });
|
|
1074
1069
|
},
|
|
1075
1070
|
},
|
|
1076
1071
|
extraReducers: (builder) => {
|
|
@@ -1083,8 +1078,8 @@ const localParticipantSlice = createSlice({
|
|
|
1083
1078
|
builder.addCase(doEnableVideo.fulfilled, (state, action) => {
|
|
1084
1079
|
return Object.assign(Object.assign({}, state), { isVideoEnabled: action.payload });
|
|
1085
1080
|
});
|
|
1086
|
-
builder.addCase(
|
|
1087
|
-
return Object.assign(Object.assign({}, state), {
|
|
1081
|
+
builder.addCase(doSetLocalStickyReaction.fulfilled, (state, action) => {
|
|
1082
|
+
return Object.assign(Object.assign({}, state), { stickyReaction: action.payload });
|
|
1088
1083
|
});
|
|
1089
1084
|
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1090
1085
|
var _a, _b;
|
|
@@ -1093,11 +1088,64 @@ const localParticipantSlice = createSlice({
|
|
|
1093
1088
|
});
|
|
1094
1089
|
},
|
|
1095
1090
|
});
|
|
1096
|
-
const {
|
|
1091
|
+
const { doSetDisplayName } = localParticipantSlice.actions;
|
|
1092
|
+
const doEnableAudio = createAppAsyncThunk("localParticipant/doEnableAudio", (payload, { dispatch, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1093
|
+
const state = getState();
|
|
1094
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1095
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("enable_audio", { enabled: payload.enabled });
|
|
1096
|
+
if (payload.enabled) {
|
|
1097
|
+
dispatch(doSetLocalStickyReaction({ enabled: false }));
|
|
1098
|
+
}
|
|
1099
|
+
return payload.enabled;
|
|
1100
|
+
}));
|
|
1101
|
+
const doEnableVideo = createAppAsyncThunk("localParticipant/doEnableVideo", (payload, { getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1102
|
+
const state = getState();
|
|
1103
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1104
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("enable_video", { enabled: payload.enabled });
|
|
1105
|
+
return payload.enabled;
|
|
1106
|
+
}));
|
|
1107
|
+
const doSetLocalStickyReaction = createAppAsyncThunk("localParticipant/doSetLocalStickyReaction", (payload, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1108
|
+
var _a;
|
|
1109
|
+
const state = getState();
|
|
1110
|
+
const currentStickyReaction = selectLocalParticipantStickyReaction(state);
|
|
1111
|
+
const stickyReactionCurrentlyEnabled = Boolean(currentStickyReaction);
|
|
1112
|
+
const enabled = (_a = payload.enabled) !== null && _a !== void 0 ? _a : !stickyReactionCurrentlyEnabled;
|
|
1113
|
+
if (enabled === stickyReactionCurrentlyEnabled) {
|
|
1114
|
+
return rejectWithValue(currentStickyReaction);
|
|
1115
|
+
}
|
|
1116
|
+
const stickyReaction = enabled ? { reaction: "✋", timestamp: new Date().toISOString() } : null;
|
|
1117
|
+
return stickyReaction;
|
|
1118
|
+
}));
|
|
1119
|
+
const doSendClientMetadata = createAppThunk(() => (_, getState) => {
|
|
1120
|
+
const state = getState();
|
|
1121
|
+
const socket = selectSignalConnectionRaw(state).socket;
|
|
1122
|
+
const payload = {
|
|
1123
|
+
displayName: selectLocalParticipantDisplayName(state),
|
|
1124
|
+
stickyReaction: selectLocalParticipantStickyReaction(state),
|
|
1125
|
+
};
|
|
1126
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("send_client_metadata", {
|
|
1127
|
+
type: "UserData",
|
|
1128
|
+
payload,
|
|
1129
|
+
});
|
|
1130
|
+
});
|
|
1097
1131
|
const selectLocalParticipantRaw = (state) => state.localParticipant;
|
|
1098
1132
|
const selectSelfId = (state) => state.localParticipant.id;
|
|
1133
|
+
const selectLocalParticipantDisplayName = (state) => state.localParticipant.displayName;
|
|
1099
1134
|
const selectLocalParticipantClientClaim = (state) => state.localParticipant.clientClaim;
|
|
1100
1135
|
const selectLocalParticipantIsScreenSharing = (state) => state.localParticipant.isScreenSharing;
|
|
1136
|
+
const selectLocalParticipantStickyReaction = (state) => state.localParticipant.stickyReaction;
|
|
1137
|
+
const selectLocalParticipantView = createSelector(selectLocalParticipantRaw, selectLocalMediaStream, (participant, localStream) => {
|
|
1138
|
+
const clientView = {
|
|
1139
|
+
id: participant.id,
|
|
1140
|
+
clientId: participant.id,
|
|
1141
|
+
displayName: participant.displayName,
|
|
1142
|
+
stream: localStream,
|
|
1143
|
+
isLocalClient: true,
|
|
1144
|
+
isAudioEnabled: participant.isAudioEnabled,
|
|
1145
|
+
isVideoEnabled: participant.isVideoEnabled,
|
|
1146
|
+
};
|
|
1147
|
+
return clientView;
|
|
1148
|
+
});
|
|
1101
1149
|
startAppListening({
|
|
1102
1150
|
actionCreator: toggleCameraEnabled,
|
|
1103
1151
|
effect: ({ payload }, { dispatch, getState }) => {
|
|
@@ -1114,15 +1162,18 @@ startAppListening({
|
|
|
1114
1162
|
dispatch(doEnableAudio({ enabled: enabled || !isAudioEnabled }));
|
|
1115
1163
|
},
|
|
1116
1164
|
});
|
|
1165
|
+
createReactor([selectLocalParticipantDisplayName, selectLocalParticipantStickyReaction], ({ dispatch }) => {
|
|
1166
|
+
dispatch(doSendClientMetadata());
|
|
1167
|
+
});
|
|
1117
1168
|
|
|
1118
|
-
const initialState$
|
|
1169
|
+
const initialState$9 = {
|
|
1119
1170
|
status: "inactive",
|
|
1120
1171
|
stream: null,
|
|
1121
1172
|
error: null,
|
|
1122
1173
|
};
|
|
1123
1174
|
const localScreenshareSlice = createSlice({
|
|
1124
1175
|
name: "localScreenshare",
|
|
1125
|
-
initialState: initialState$
|
|
1176
|
+
initialState: initialState$9,
|
|
1126
1177
|
reducers: {
|
|
1127
1178
|
stopScreenshare(state, action) {
|
|
1128
1179
|
return Object.assign(Object.assign({}, state), { status: "inactive", stream: null });
|
|
@@ -1191,60 +1242,6 @@ startAppListening({
|
|
|
1191
1242
|
},
|
|
1192
1243
|
});
|
|
1193
1244
|
|
|
1194
|
-
const initialState$7 = {
|
|
1195
|
-
data: null,
|
|
1196
|
-
isFetching: false,
|
|
1197
|
-
error: null,
|
|
1198
|
-
};
|
|
1199
|
-
const organizationSlice = createSlice({
|
|
1200
|
-
initialState: initialState$7,
|
|
1201
|
-
name: "organization",
|
|
1202
|
-
reducers: {},
|
|
1203
|
-
extraReducers: (builder) => {
|
|
1204
|
-
builder.addCase(doOrganizationFetch.pending, (state) => {
|
|
1205
|
-
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1206
|
-
});
|
|
1207
|
-
builder.addCase(doOrganizationFetch.fulfilled, (state, action) => {
|
|
1208
|
-
if (!action.payload)
|
|
1209
|
-
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1210
|
-
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
1211
|
-
});
|
|
1212
|
-
builder.addCase(doOrganizationFetch.rejected, (state) => {
|
|
1213
|
-
return Object.assign(Object.assign({}, state), { isFetching: false, error: true });
|
|
1214
|
-
});
|
|
1215
|
-
},
|
|
1216
|
-
});
|
|
1217
|
-
const doOrganizationFetch = createAppAsyncThunk("organization/doOrganizationFetch", (_, { extra, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1218
|
-
try {
|
|
1219
|
-
const roomUrl = selectAppRoomUrl(getState());
|
|
1220
|
-
const organization = yield extra.services.fetchOrganizationFromRoomUrl(roomUrl || "");
|
|
1221
|
-
if (!organization) {
|
|
1222
|
-
throw new Error("Invalid room url");
|
|
1223
|
-
}
|
|
1224
|
-
return organization;
|
|
1225
|
-
}
|
|
1226
|
-
catch (error) {
|
|
1227
|
-
console.error(error);
|
|
1228
|
-
}
|
|
1229
|
-
}));
|
|
1230
|
-
const selectOrganizationRaw = (state) => state.organization;
|
|
1231
|
-
const selectOrganizationId = (state) => { var _a; return (_a = state.organization.data) === null || _a === void 0 ? void 0 : _a.organizationId; };
|
|
1232
|
-
const selectShouldFetchOrganization = createSelector(selectAppIsActive, selectOrganizationRaw, selectDeviceCredentialsRaw, (appIsActive, organization, deviceCredentials) => {
|
|
1233
|
-
if (appIsActive &&
|
|
1234
|
-
!organization.data &&
|
|
1235
|
-
!organization.isFetching &&
|
|
1236
|
-
!organization.error &&
|
|
1237
|
-
!deviceCredentials.isFetching) {
|
|
1238
|
-
return true;
|
|
1239
|
-
}
|
|
1240
|
-
return false;
|
|
1241
|
-
});
|
|
1242
|
-
createReactor([selectShouldFetchOrganization], ({ dispatch }, shouldFetchOrganization) => {
|
|
1243
|
-
if (shouldFetchOrganization) {
|
|
1244
|
-
dispatch(doOrganizationFetch());
|
|
1245
|
-
}
|
|
1246
|
-
});
|
|
1247
|
-
|
|
1248
1245
|
function createRtcEventAction(name) {
|
|
1249
1246
|
return createAction(`rtcConnection/event/${name}`);
|
|
1250
1247
|
}
|
|
@@ -1346,12 +1343,12 @@ function addStream(state, payload) {
|
|
|
1346
1343
|
presentationStream: stream,
|
|
1347
1344
|
});
|
|
1348
1345
|
}
|
|
1349
|
-
const initialState$
|
|
1346
|
+
const initialState$8 = {
|
|
1350
1347
|
remoteParticipants: [],
|
|
1351
1348
|
};
|
|
1352
1349
|
const remoteParticipantsSlice = createSlice({
|
|
1353
1350
|
name: "remoteParticipants",
|
|
1354
|
-
initialState: initialState$
|
|
1351
|
+
initialState: initialState$8,
|
|
1355
1352
|
reducers: {
|
|
1356
1353
|
streamStatusUpdated: (state, action) => {
|
|
1357
1354
|
let newState = state;
|
|
@@ -1415,9 +1412,10 @@ const remoteParticipantsSlice = createSlice({
|
|
|
1415
1412
|
console.warn(error || "Client metadata error received");
|
|
1416
1413
|
return state;
|
|
1417
1414
|
}
|
|
1418
|
-
const { clientId, displayName } = payload;
|
|
1415
|
+
const { clientId, displayName, stickyReaction } = payload;
|
|
1419
1416
|
return updateParticipant(state, clientId, {
|
|
1420
1417
|
displayName,
|
|
1418
|
+
stickyReaction,
|
|
1421
1419
|
});
|
|
1422
1420
|
});
|
|
1423
1421
|
builder.addCase(signalEvents.screenshareStarted, (state, action) => {
|
|
@@ -1433,87 +1431,79 @@ const remoteParticipantsSlice = createSlice({
|
|
|
1433
1431
|
const { participantStreamAdded, participantStreamIdAdded, streamStatusUpdated } = remoteParticipantsSlice.actions;
|
|
1434
1432
|
const doRequestAudioEnable = createAppAuthorizedThunk((state) => selectIsAuthorizedToRequestAudioEnable(state), (payload) => (_, getState) => {
|
|
1435
1433
|
const state = getState();
|
|
1434
|
+
const canEnableRemoteAudio = selectIsAuthorizedToAskToSpeak(state);
|
|
1435
|
+
if (payload.enable && !canEnableRemoteAudio) {
|
|
1436
|
+
console.warn("Not authorized to perform this action");
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1436
1439
|
const socket = selectSignalConnectionRaw(state).socket;
|
|
1437
1440
|
socket === null || socket === void 0 ? void 0 : socket.emit("request_audio_enable", payload);
|
|
1438
1441
|
});
|
|
1439
1442
|
const selectRemoteParticipantsRaw = (state) => state.remoteParticipants;
|
|
1440
1443
|
const selectRemoteParticipants = (state) => state.remoteParticipants.remoteParticipants;
|
|
1441
|
-
const
|
|
1442
|
-
const screenshares = [];
|
|
1443
|
-
if (localScreenshareStream) {
|
|
1444
|
-
screenshares.push({
|
|
1445
|
-
id: localScreenshareStream.id || "local-screenshare",
|
|
1446
|
-
participantId: "local",
|
|
1447
|
-
hasAudioTrack: localScreenshareStream.getTracks().some((track) => track.kind === "audio"),
|
|
1448
|
-
stream: localScreenshareStream,
|
|
1449
|
-
isLocal: true,
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
for (const participant of remoteParticipants) {
|
|
1453
|
-
if (participant.presentationStream) {
|
|
1454
|
-
screenshares.push({
|
|
1455
|
-
id: participant.presentationStream.id || `pres-${participant.id}`,
|
|
1456
|
-
participantId: participant.id,
|
|
1457
|
-
hasAudioTrack: participant.presentationStream.getTracks().some((track) => track.kind === "audio"),
|
|
1458
|
-
stream: participant.presentationStream,
|
|
1459
|
-
isLocal: false,
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
return screenshares;
|
|
1464
|
-
});
|
|
1444
|
+
const selectNumParticipants = createSelector(selectRemoteParticipants, (clients) => clients.filter((c) => !NON_PERSON_ROLES.includes(c.roleName)).length + 1);
|
|
1465
1445
|
|
|
1466
|
-
const initialState$
|
|
1467
|
-
|
|
1446
|
+
const initialState$7 = {
|
|
1447
|
+
data: null,
|
|
1448
|
+
isFetching: false,
|
|
1449
|
+
error: null,
|
|
1468
1450
|
};
|
|
1469
|
-
const
|
|
1470
|
-
|
|
1471
|
-
|
|
1451
|
+
const organizationSlice = createSlice({
|
|
1452
|
+
initialState: initialState$7,
|
|
1453
|
+
name: "organization",
|
|
1472
1454
|
reducers: {},
|
|
1473
1455
|
extraReducers: (builder) => {
|
|
1474
|
-
builder.addCase(
|
|
1475
|
-
|
|
1476
|
-
if (error) {
|
|
1477
|
-
return state;
|
|
1478
|
-
}
|
|
1479
|
-
return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
|
|
1456
|
+
builder.addCase(doOrganizationFetch.pending, (state) => {
|
|
1457
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1480
1458
|
});
|
|
1481
|
-
builder.addCase(
|
|
1482
|
-
|
|
1483
|
-
|
|
1459
|
+
builder.addCase(doOrganizationFetch.fulfilled, (state, action) => {
|
|
1460
|
+
if (!action.payload)
|
|
1461
|
+
return Object.assign(Object.assign({}, state), { isFetching: true });
|
|
1462
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, data: action.payload });
|
|
1463
|
+
});
|
|
1464
|
+
builder.addCase(doOrganizationFetch.rejected, (state) => {
|
|
1465
|
+
return Object.assign(Object.assign({}, state), { isFetching: false, error: true });
|
|
1484
1466
|
});
|
|
1485
1467
|
},
|
|
1486
1468
|
});
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientId: payload.clientId, reasonId: "kick" });
|
|
1496
|
-
});
|
|
1497
|
-
const doEndMeeting = createAppAuthorizedThunk((state) => selectIsAuthorizedToEndMeeting(state), (payload) => (dispatch, getState) => {
|
|
1498
|
-
const state = getState();
|
|
1499
|
-
const clientsToKick = selectRemoteParticipants(state).map((c) => c.id);
|
|
1500
|
-
if (clientsToKick.length) {
|
|
1501
|
-
const { socket } = selectSignalConnectionRaw(state);
|
|
1502
|
-
socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientIds: clientsToKick, reasonId: "end-meeting" });
|
|
1469
|
+
const doOrganizationFetch = createAppAsyncThunk("organization/doOrganizationFetch", (_, { extra, getState }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1470
|
+
try {
|
|
1471
|
+
const roomUrl = selectAppRoomUrl(getState());
|
|
1472
|
+
const organization = yield extra.services.fetchOrganizationFromRoomUrl(roomUrl || "");
|
|
1473
|
+
if (!organization) {
|
|
1474
|
+
throw new Error("Invalid room url");
|
|
1475
|
+
}
|
|
1476
|
+
return organization;
|
|
1503
1477
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1478
|
+
catch (error) {
|
|
1479
|
+
console.error(error);
|
|
1480
|
+
}
|
|
1481
|
+
}));
|
|
1482
|
+
const selectOrganizationRaw = (state) => state.organization;
|
|
1483
|
+
const selectOrganizationId = (state) => { var _a; return (_a = state.organization.data) === null || _a === void 0 ? void 0 : _a.organizationId; };
|
|
1484
|
+
const selectShouldFetchOrganization = createSelector(selectAppIsActive, selectOrganizationRaw, selectDeviceCredentialsRaw, (appIsActive, organization, deviceCredentials) => {
|
|
1485
|
+
if (appIsActive &&
|
|
1486
|
+
!organization.data &&
|
|
1487
|
+
!organization.isFetching &&
|
|
1488
|
+
!organization.error &&
|
|
1489
|
+
!deviceCredentials.isFetching) {
|
|
1490
|
+
return true;
|
|
1491
|
+
}
|
|
1492
|
+
return false;
|
|
1493
|
+
});
|
|
1494
|
+
createReactor([selectShouldFetchOrganization], ({ dispatch }, shouldFetchOrganization) => {
|
|
1495
|
+
if (shouldFetchOrganization) {
|
|
1496
|
+
dispatch(doOrganizationFetch());
|
|
1506
1497
|
}
|
|
1507
1498
|
});
|
|
1508
|
-
const selectRoomIsLocked = (state) => state.room.isLocked;
|
|
1509
1499
|
|
|
1510
|
-
const initialState$
|
|
1500
|
+
const initialState$6 = {
|
|
1511
1501
|
session: null,
|
|
1512
1502
|
status: "ready",
|
|
1513
1503
|
error: null,
|
|
1514
1504
|
};
|
|
1515
1505
|
const roomConnectionSlice = createSlice({
|
|
1516
|
-
initialState: initialState$
|
|
1506
|
+
initialState: initialState$6,
|
|
1517
1507
|
name: "roomConnection",
|
|
1518
1508
|
reducers: {
|
|
1519
1509
|
connectionStatusChanged: (state, action) => {
|
|
@@ -1672,6 +1662,249 @@ startAppListening({
|
|
|
1672
1662
|
},
|
|
1673
1663
|
});
|
|
1674
1664
|
|
|
1665
|
+
const emitter = new EventEmitter();
|
|
1666
|
+
function createNotificationEvent(payload) {
|
|
1667
|
+
const notificationEvent = Object.assign(Object.assign({}, payload), { timestamp: Date.now() });
|
|
1668
|
+
return notificationEvent;
|
|
1669
|
+
}
|
|
1670
|
+
const initialNotificationsState = {
|
|
1671
|
+
emitter,
|
|
1672
|
+
events: [],
|
|
1673
|
+
};
|
|
1674
|
+
const notificationsSlice = createSlice({
|
|
1675
|
+
name: "notifications",
|
|
1676
|
+
initialState: initialNotificationsState,
|
|
1677
|
+
reducers: {
|
|
1678
|
+
addNotification: (state, action) => {
|
|
1679
|
+
return Object.assign(Object.assign({}, state), { events: [...state.events, Object.assign({}, action.payload)] });
|
|
1680
|
+
},
|
|
1681
|
+
doClearNotifications: (state) => {
|
|
1682
|
+
return Object.assign(Object.assign({}, state), { events: [] });
|
|
1683
|
+
},
|
|
1684
|
+
},
|
|
1685
|
+
});
|
|
1686
|
+
const { doClearNotifications } = notificationsSlice.actions;
|
|
1687
|
+
const doSetNotification = createAppThunk((payload) => (dispatch, getState) => {
|
|
1688
|
+
dispatch(notificationsSlice.actions.addNotification(payload));
|
|
1689
|
+
const state = getState();
|
|
1690
|
+
const emitter = selectNotificationsEmitter(state);
|
|
1691
|
+
emitter.emit(payload.type, payload);
|
|
1692
|
+
emitter.emit("*", payload);
|
|
1693
|
+
});
|
|
1694
|
+
const selectNotificationsRaw = (state) => state.notifications;
|
|
1695
|
+
const selectNotificationsEvents = (state) => state.notifications.events;
|
|
1696
|
+
const selectNotificationsEmitter = (state) => state.notifications.emitter;
|
|
1697
|
+
startAppListening({
|
|
1698
|
+
actionCreator: signalEvents.chatMessage,
|
|
1699
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
1700
|
+
const state = getState();
|
|
1701
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === payload.senderId);
|
|
1702
|
+
if (!client) {
|
|
1703
|
+
console.warn("Could not find remote client that sent chat message");
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
1707
|
+
type: "chatMessageReceived",
|
|
1708
|
+
message: `${client.displayName} says: ${payload.text}`,
|
|
1709
|
+
props: {
|
|
1710
|
+
client,
|
|
1711
|
+
chatMessage: {
|
|
1712
|
+
senderId: payload.senderId,
|
|
1713
|
+
timestamp: payload.timestamp,
|
|
1714
|
+
text: payload.text,
|
|
1715
|
+
},
|
|
1716
|
+
},
|
|
1717
|
+
})));
|
|
1718
|
+
},
|
|
1719
|
+
});
|
|
1720
|
+
startAppListening({
|
|
1721
|
+
actionCreator: signalEvents.audioEnableRequested,
|
|
1722
|
+
effect: ({ payload }, { dispatch, getState }) => {
|
|
1723
|
+
const { enable, requestedByClientId } = payload;
|
|
1724
|
+
const state = getState();
|
|
1725
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === requestedByClientId);
|
|
1726
|
+
if (!client) {
|
|
1727
|
+
console.warn("Could not find remote client that requested a local audio change");
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
1731
|
+
type: enable ? "requestAudioEnable" : "requestAudioDisable",
|
|
1732
|
+
message: enable
|
|
1733
|
+
? `${client.displayName} has requested for you to speak`
|
|
1734
|
+
: `${client.displayName} has muted your microphone`,
|
|
1735
|
+
props: {
|
|
1736
|
+
client,
|
|
1737
|
+
enable,
|
|
1738
|
+
},
|
|
1739
|
+
})));
|
|
1740
|
+
},
|
|
1741
|
+
});
|
|
1742
|
+
startAppListening({
|
|
1743
|
+
actionCreator: signalEvents.clientMetadataReceived,
|
|
1744
|
+
effect: (action, { dispatch, getOriginalState, getState }) => {
|
|
1745
|
+
var _a;
|
|
1746
|
+
const { error, payload } = action.payload;
|
|
1747
|
+
if (error || !payload) {
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
const { clientId, stickyReaction } = payload;
|
|
1751
|
+
const state = getState();
|
|
1752
|
+
const canAskToSpeak = selectIsAuthorizedToAskToSpeak(state);
|
|
1753
|
+
if (!canAskToSpeak) {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
const client = selectRemoteParticipants(state).find(({ id }) => id === clientId);
|
|
1757
|
+
if (!client) {
|
|
1758
|
+
console.warn("Could not find remote client that provided updated metadata");
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
const previousState = getOriginalState();
|
|
1762
|
+
const previousClient = selectRemoteParticipants(previousState).find(({ id }) => id === clientId);
|
|
1763
|
+
if ((!stickyReaction && !(previousClient === null || previousClient === void 0 ? void 0 : previousClient.stickyReaction)) ||
|
|
1764
|
+
(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)) {
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
1768
|
+
type: stickyReaction ? "remoteHandRaised" : "remoteHandLowered",
|
|
1769
|
+
message: `${client.displayName} ${stickyReaction ? "raised" : "lowered"} their hand`,
|
|
1770
|
+
props: {
|
|
1771
|
+
client,
|
|
1772
|
+
stickyReaction,
|
|
1773
|
+
},
|
|
1774
|
+
})));
|
|
1775
|
+
},
|
|
1776
|
+
});
|
|
1777
|
+
createReactor([selectSignalStatus], ({ dispatch, getState }, signalStatus) => {
|
|
1778
|
+
const state = getState();
|
|
1779
|
+
const roomConnectionStatus = selectRoomConnectionStatus(state);
|
|
1780
|
+
if (["left", "kicked"].includes(roomConnectionStatus)) {
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
if (signalStatus === "disconnected") {
|
|
1784
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
1785
|
+
type: "signalTrouble",
|
|
1786
|
+
message: `Network connection lost. Trying to reconnect you...`,
|
|
1787
|
+
props: {},
|
|
1788
|
+
})));
|
|
1789
|
+
}
|
|
1790
|
+
else if (signalStatus === "connected") {
|
|
1791
|
+
dispatch(doSetNotification(createNotificationEvent({
|
|
1792
|
+
type: "signalOk",
|
|
1793
|
+
message: `Network connection available`,
|
|
1794
|
+
props: {},
|
|
1795
|
+
})));
|
|
1796
|
+
}
|
|
1797
|
+
});
|
|
1798
|
+
|
|
1799
|
+
function isStreamerClient(client) {
|
|
1800
|
+
return client.roleName === "streamer";
|
|
1801
|
+
}
|
|
1802
|
+
function isRecorderClient(client) {
|
|
1803
|
+
return client.roleName === "recorder";
|
|
1804
|
+
}
|
|
1805
|
+
const initialState$5 = {
|
|
1806
|
+
isLocked: false,
|
|
1807
|
+
};
|
|
1808
|
+
const roomSlice = createSlice({
|
|
1809
|
+
name: "room",
|
|
1810
|
+
initialState: initialState$5,
|
|
1811
|
+
reducers: {},
|
|
1812
|
+
extraReducers: (builder) => {
|
|
1813
|
+
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
1814
|
+
const { error, isLocked } = action.payload;
|
|
1815
|
+
if (error) {
|
|
1816
|
+
return state;
|
|
1817
|
+
}
|
|
1818
|
+
return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
|
|
1819
|
+
});
|
|
1820
|
+
builder.addCase(signalEvents.roomLocked, (state, action) => {
|
|
1821
|
+
const { isLocked } = action.payload;
|
|
1822
|
+
return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
|
|
1823
|
+
});
|
|
1824
|
+
},
|
|
1825
|
+
});
|
|
1826
|
+
const doLockRoom = createAppAuthorizedThunk((state) => selectIsAuthorizedToLockRoom(state), (payload) => (_, getState) => {
|
|
1827
|
+
const state = getState();
|
|
1828
|
+
const { socket } = selectSignalConnectionRaw(state);
|
|
1829
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("set_lock", { locked: payload.locked });
|
|
1830
|
+
});
|
|
1831
|
+
const doKickParticipant = createAppAuthorizedThunk((state) => selectIsAuthorizedToKickClient(state), (payload) => (_, getState) => {
|
|
1832
|
+
const state = getState();
|
|
1833
|
+
const { socket } = selectSignalConnectionRaw(state);
|
|
1834
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientId: payload.clientId, reasonId: "kick" });
|
|
1835
|
+
});
|
|
1836
|
+
const doEndMeeting = createAppAuthorizedThunk((state) => selectIsAuthorizedToEndMeeting(state), (payload) => (dispatch, getState) => {
|
|
1837
|
+
const state = getState();
|
|
1838
|
+
const clientsToKick = selectRemoteParticipants(state).map((c) => c.id);
|
|
1839
|
+
if (clientsToKick.length) {
|
|
1840
|
+
const { socket } = selectSignalConnectionRaw(state);
|
|
1841
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientIds: clientsToKick, reasonId: "end-meeting" });
|
|
1842
|
+
}
|
|
1843
|
+
if (!payload.stayBehind) {
|
|
1844
|
+
dispatch(doAppStop());
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
const selectRoomIsLocked = (state) => state.room.isLocked;
|
|
1848
|
+
const selectScreenshares = createSelector(selectLocalScreenshareStream, selectRemoteParticipants, (localScreenshareStream, remoteParticipants) => {
|
|
1849
|
+
const screenshares = [];
|
|
1850
|
+
if (localScreenshareStream) {
|
|
1851
|
+
screenshares.push({
|
|
1852
|
+
id: localScreenshareStream.id || "local-screenshare",
|
|
1853
|
+
participantId: "local",
|
|
1854
|
+
hasAudioTrack: localScreenshareStream.getTracks().some((track) => track.kind === "audio"),
|
|
1855
|
+
stream: localScreenshareStream,
|
|
1856
|
+
isLocal: true,
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
for (const participant of remoteParticipants) {
|
|
1860
|
+
if (participant.presentationStream) {
|
|
1861
|
+
screenshares.push({
|
|
1862
|
+
id: participant.presentationStream.id || `pres-${participant.id}`,
|
|
1863
|
+
participantId: participant.id,
|
|
1864
|
+
hasAudioTrack: participant.presentationStream.getTracks().some((track) => track.kind === "audio"),
|
|
1865
|
+
stream: participant.presentationStream,
|
|
1866
|
+
isLocal: false,
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
return screenshares;
|
|
1871
|
+
});
|
|
1872
|
+
const selectRemoteClientViews = createSelector(selectLocalScreenshareStream, selectLocalParticipantRaw, selectRemoteParticipants, (localScreenshareStream, localParticipant, remoteParticipants) => {
|
|
1873
|
+
const views = [];
|
|
1874
|
+
if (localScreenshareStream) {
|
|
1875
|
+
const isScreenshareAudioEnabled = !!localScreenshareStream.getAudioTracks().length;
|
|
1876
|
+
views.push({
|
|
1877
|
+
clientId: localParticipant.id,
|
|
1878
|
+
displayName: "Your screenshare",
|
|
1879
|
+
id: "local-screenshare",
|
|
1880
|
+
isAudioEnabled: isScreenshareAudioEnabled,
|
|
1881
|
+
isLocalClient: true,
|
|
1882
|
+
isPresentation: true,
|
|
1883
|
+
isVideoEnabled: true,
|
|
1884
|
+
stream: localScreenshareStream,
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
for (const c of remoteParticipants) {
|
|
1888
|
+
if (isStreamerClient(c) || isRecorderClient(c)) {
|
|
1889
|
+
continue;
|
|
1890
|
+
}
|
|
1891
|
+
const { presentationStream } = c, clientView = __rest(c, ["presentationStream"]);
|
|
1892
|
+
const displayName = c.displayName || "Guest";
|
|
1893
|
+
const isPresentationActive = presentationStream && presentationStream.active;
|
|
1894
|
+
const presentationId = "pres-" + c.id;
|
|
1895
|
+
const isStreamActive = c.stream && c.stream.active;
|
|
1896
|
+
const isVideoEnabled = c.isVideoEnabled;
|
|
1897
|
+
views.push(Object.assign(Object.assign(Object.assign({}, clientView), { clientId: c.id, displayName, hasActivePresentation: !!isPresentationActive }), (c.isVideoEnabled ? { isVideoEnabled } : {})));
|
|
1898
|
+
if (isPresentationActive) {
|
|
1899
|
+
views.push(Object.assign(Object.assign(Object.assign({}, clientView), { clientId: c.id, stream: c.presentationStream, displayName: `Screenshare (${displayName})`, id: presentationId, isPresentation: true, isVideoEnabled: true }), (isStreamActive && { isRecording: null })));
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
return views;
|
|
1903
|
+
});
|
|
1904
|
+
const selectAllClientViews = createSelector(selectLocalParticipantView, selectRemoteClientViews, (localParticipant, remoteParticipants) => {
|
|
1905
|
+
return [localParticipant, ...remoteParticipants];
|
|
1906
|
+
});
|
|
1907
|
+
|
|
1675
1908
|
const createWebRtcEmitter = (dispatch) => {
|
|
1676
1909
|
return {
|
|
1677
1910
|
emit: (eventName, data) => {
|
|
@@ -1688,7 +1921,7 @@ const createWebRtcEmitter = (dispatch) => {
|
|
|
1688
1921
|
},
|
|
1689
1922
|
};
|
|
1690
1923
|
};
|
|
1691
|
-
const initialState$
|
|
1924
|
+
const initialState$4 = {
|
|
1692
1925
|
dispatcherCreated: false,
|
|
1693
1926
|
error: null,
|
|
1694
1927
|
isCreatingDispatcher: false,
|
|
@@ -1701,7 +1934,7 @@ const initialState$3 = {
|
|
|
1701
1934
|
};
|
|
1702
1935
|
const rtcConnectionSlice = createSlice({
|
|
1703
1936
|
name: "rtcConnection",
|
|
1704
|
-
initialState: initialState$
|
|
1937
|
+
initialState: initialState$4,
|
|
1705
1938
|
reducers: {
|
|
1706
1939
|
isAcceptingStreams: (state, action) => {
|
|
1707
1940
|
return Object.assign(Object.assign({}, state), { isAcceptingStreams: action.payload });
|
|
@@ -1711,7 +1944,7 @@ const rtcConnectionSlice = createSlice({
|
|
|
1711
1944
|
return Object.assign(Object.assign({}, state), { reportedStreamResolutions: Object.assign(Object.assign({}, state.reportedStreamResolutions), { [streamId]: { width, height } }) });
|
|
1712
1945
|
},
|
|
1713
1946
|
rtcDisconnected: () => {
|
|
1714
|
-
return Object.assign({}, initialState$
|
|
1947
|
+
return Object.assign({}, initialState$4);
|
|
1715
1948
|
},
|
|
1716
1949
|
rtcDispatcherCreated: (state, action) => {
|
|
1717
1950
|
return Object.assign(Object.assign({}, state), { dispatcherCreated: true, rtcManagerDispatcher: action.payload });
|
|
@@ -2009,7 +2242,7 @@ const rtcAnalyticsCustomEvents = {
|
|
|
2009
2242
|
getOutput: () => ({}),
|
|
2010
2243
|
},
|
|
2011
2244
|
displayName: {
|
|
2012
|
-
actions: [doSetDisplayName
|
|
2245
|
+
actions: [doSetDisplayName],
|
|
2013
2246
|
rtcEventName: "displayName",
|
|
2014
2247
|
getValue: (state) => selectAppDisplayName(state),
|
|
2015
2248
|
getOutput: (value) => ({ displayName: value }),
|
|
@@ -2076,11 +2309,11 @@ const makeComparable = (value) => {
|
|
|
2076
2309
|
return JSON.stringify(value);
|
|
2077
2310
|
return value;
|
|
2078
2311
|
};
|
|
2079
|
-
const initialState$
|
|
2312
|
+
const initialState$3 = {
|
|
2080
2313
|
reportedValues: {},
|
|
2081
2314
|
};
|
|
2082
2315
|
const rtcAnalyticsSlice = createSlice({
|
|
2083
|
-
initialState: initialState$
|
|
2316
|
+
initialState: initialState$3,
|
|
2084
2317
|
name: "rtcAnalytics",
|
|
2085
2318
|
reducers: {
|
|
2086
2319
|
updateReportedValues(state, action) {
|
|
@@ -2140,6 +2373,92 @@ createReactor([selectRtcManagerInitialized], ({ dispatch }, selectRtcManagerInit
|
|
|
2140
2373
|
}
|
|
2141
2374
|
});
|
|
2142
2375
|
|
|
2376
|
+
function streamIdForClient({ isPresentation, stream }) {
|
|
2377
|
+
var _a, _b;
|
|
2378
|
+
return isPresentation ? (_b = (_a = stream === null || stream === void 0 ? void 0 : stream.outboundId) !== null && _a !== void 0 ? _a : stream === null || stream === void 0 ? void 0 : stream.inboundId) !== null && _b !== void 0 ? _b : stream === null || stream === void 0 ? void 0 : stream.id : "0";
|
|
2379
|
+
}
|
|
2380
|
+
function isClientSpotlighted({ spotlights, isPresentation, clientId, stream, }) {
|
|
2381
|
+
return !!spotlights.find((s) => {
|
|
2382
|
+
const streamId = streamIdForClient({ isPresentation, stream });
|
|
2383
|
+
return s.clientId === clientId && s.streamId === streamId;
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
function mergeSpotlight(spotlights, spotlight) {
|
|
2387
|
+
const found = spotlights.find((s) => s.clientId === spotlight.clientId && s.streamId === spotlight.streamId);
|
|
2388
|
+
if (found) {
|
|
2389
|
+
return spotlights;
|
|
2390
|
+
}
|
|
2391
|
+
return spotlights.concat(spotlight);
|
|
2392
|
+
}
|
|
2393
|
+
function mapSpotlightsToClientViews(spotlights, clientViews) {
|
|
2394
|
+
return spotlights.reduce((acc, s) => {
|
|
2395
|
+
const clientView = clientViews.find((c) => s.clientId === c.clientId && s.streamId === streamIdForClient(c));
|
|
2396
|
+
if (clientView && !acc.includes(clientView)) {
|
|
2397
|
+
acc.push(clientView);
|
|
2398
|
+
}
|
|
2399
|
+
return acc;
|
|
2400
|
+
}, []);
|
|
2401
|
+
}
|
|
2402
|
+
const initialState$2 = {
|
|
2403
|
+
sorted: [],
|
|
2404
|
+
};
|
|
2405
|
+
const spotlightsSlice = createSlice({
|
|
2406
|
+
name: "spotlights",
|
|
2407
|
+
initialState: initialState$2,
|
|
2408
|
+
reducers: {},
|
|
2409
|
+
extraReducers: (builder) => {
|
|
2410
|
+
builder.addCase(signalEvents.roomJoined, (state, action) => {
|
|
2411
|
+
if (!action.payload.room) {
|
|
2412
|
+
return state;
|
|
2413
|
+
}
|
|
2414
|
+
const { spotlights } = action.payload.room;
|
|
2415
|
+
return Object.assign(Object.assign({}, state), { sorted: spotlights });
|
|
2416
|
+
});
|
|
2417
|
+
builder.addCase(signalEvents.spotlightAdded, (state, action) => {
|
|
2418
|
+
const { clientId, streamId } = action.payload;
|
|
2419
|
+
return Object.assign(Object.assign({}, state), { sorted: mergeSpotlight(state.sorted, { clientId, streamId }) });
|
|
2420
|
+
});
|
|
2421
|
+
builder.addCase(signalEvents.spotlightRemoved, (state, action) => {
|
|
2422
|
+
const { clientId, streamId } = action.payload;
|
|
2423
|
+
return Object.assign(Object.assign({}, state), { sorted: state.sorted.filter((s) => !(s.clientId === clientId && s.streamId === streamId)) });
|
|
2424
|
+
});
|
|
2425
|
+
builder.addMatcher(isAnyOf(signalEvents.clientKicked, signalEvents.clientLeft), (state, action) => {
|
|
2426
|
+
const { clientId } = action.payload;
|
|
2427
|
+
return Object.assign(Object.assign({}, state), { sorted: state.sorted.filter((s) => s.clientId !== clientId) });
|
|
2428
|
+
});
|
|
2429
|
+
},
|
|
2430
|
+
});
|
|
2431
|
+
const doSpotlightParticipant = createAppAuthorizedThunk((state) => selectIsAuthorizedToSpotlight(state), ({ id }) => (_, getState) => {
|
|
2432
|
+
const state = getState();
|
|
2433
|
+
const clientView = selectAllClientViews(state).find((c) => c.clientId === id);
|
|
2434
|
+
if (!clientView) {
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
const { socket } = selectSignalConnectionRaw(state);
|
|
2438
|
+
const streamId = streamIdForClient(clientView);
|
|
2439
|
+
const payload = { clientId: clientView.id, streamId: streamId !== null && streamId !== void 0 ? streamId : "0" };
|
|
2440
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("add_spotlight", payload);
|
|
2441
|
+
});
|
|
2442
|
+
const doRemoveSpotlight = createAppAuthorizedThunk((state) => selectIsAuthorizedToSpotlight(state), ({ id }) => (_, getState) => {
|
|
2443
|
+
const state = getState();
|
|
2444
|
+
const clientView = selectAllClientViews(state).find((c) => c.clientId === id);
|
|
2445
|
+
if (!clientView) {
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
const { socket } = selectSignalConnectionRaw(state);
|
|
2449
|
+
const streamId = streamIdForClient(clientView);
|
|
2450
|
+
const payload = { clientId: clientView.id, streamId: streamId !== null && streamId !== void 0 ? streamId : "0" };
|
|
2451
|
+
socket === null || socket === void 0 ? void 0 : socket.emit("remove_spotlight", payload);
|
|
2452
|
+
});
|
|
2453
|
+
const selectSpotlightsRaw = (state) => state.spotlights;
|
|
2454
|
+
const selectSpotlights = (state) => state.spotlights.sorted;
|
|
2455
|
+
const selectIsLocalParticipantSpotlighted = createSelector(selectLocalParticipantRaw, selectSpotlights, (localParticipant, spotlights) => {
|
|
2456
|
+
return isClientSpotlighted({ clientId: localParticipant.id, stream: localParticipant.stream, spotlights });
|
|
2457
|
+
});
|
|
2458
|
+
const selectSpotlightedClientViews = createSelector(selectAllClientViews, selectSpotlights, (clientViews, spotlights) => {
|
|
2459
|
+
return mapSpotlightsToClientViews(spotlights, clientViews);
|
|
2460
|
+
});
|
|
2461
|
+
|
|
2143
2462
|
const initialState$1 = {
|
|
2144
2463
|
isStreaming: false,
|
|
2145
2464
|
error: null,
|
|
@@ -2224,6 +2543,7 @@ const appReducer = combineReducers({
|
|
|
2224
2543
|
localMedia: localMediaSlice.reducer,
|
|
2225
2544
|
localParticipant: localParticipantSlice.reducer,
|
|
2226
2545
|
localScreenshare: localScreenshareSlice.reducer,
|
|
2546
|
+
notifications: notificationsSlice.reducer,
|
|
2227
2547
|
organization: organizationSlice.reducer,
|
|
2228
2548
|
remoteParticipants: remoteParticipantsSlice.reducer,
|
|
2229
2549
|
room: roomSlice.reducer,
|
|
@@ -2231,6 +2551,7 @@ const appReducer = combineReducers({
|
|
|
2231
2551
|
rtcAnalytics: rtcAnalyticsSlice.reducer,
|
|
2232
2552
|
rtcConnection: rtcConnectionSlice.reducer,
|
|
2233
2553
|
signalConnection: signalConnectionSlice.reducer,
|
|
2554
|
+
spotlights: spotlightsSlice.reducer,
|
|
2234
2555
|
streaming: streamingSlice.reducer,
|
|
2235
2556
|
waitingParticipants: waitingParticipantsSlice.reducer,
|
|
2236
2557
|
});
|
|
@@ -3238,18 +3559,19 @@ class RoomService {
|
|
|
3238
3559
|
}
|
|
3239
3560
|
|
|
3240
3561
|
class RoomParticipant {
|
|
3241
|
-
constructor({ displayName, id, stream, isAudioEnabled, isVideoEnabled }) {
|
|
3562
|
+
constructor({ displayName, id, stream, isAudioEnabled, isVideoEnabled, stickyReaction }) {
|
|
3242
3563
|
this.isLocalParticipant = false;
|
|
3243
3564
|
this.displayName = displayName;
|
|
3244
3565
|
this.id = id;
|
|
3245
3566
|
this.stream = stream;
|
|
3246
3567
|
this.isAudioEnabled = isAudioEnabled;
|
|
3247
3568
|
this.isVideoEnabled = isVideoEnabled;
|
|
3569
|
+
this.stickyReaction = stickyReaction;
|
|
3248
3570
|
}
|
|
3249
3571
|
}
|
|
3250
3572
|
class LocalParticipant extends RoomParticipant {
|
|
3251
|
-
constructor({ displayName, id, stream, isAudioEnabled, isVideoEnabled }) {
|
|
3252
|
-
super({ displayName, id, stream, isAudioEnabled, isVideoEnabled });
|
|
3573
|
+
constructor({ displayName, id, stream, isAudioEnabled, isVideoEnabled, stickyReaction }) {
|
|
3574
|
+
super({ displayName, id, stream, isAudioEnabled, isVideoEnabled, stickyReaction });
|
|
3253
3575
|
this.isLocalParticipant = true;
|
|
3254
3576
|
}
|
|
3255
3577
|
}
|
|
@@ -3279,4 +3601,4 @@ function createServices() {
|
|
|
3279
3601
|
};
|
|
3280
3602
|
}
|
|
3281
3603
|
|
|
3282
|
-
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, appSlice, authorizationSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppStart, doAppStop, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doEndMeeting, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKickParticipant, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRequestAudioEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName,
|
|
3604
|
+
export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, 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, isAcceptingStreams, isClientSpotlighted, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, notificationsSlice, observeStore, organizationSlice, parseRoomUrlAndSubdomain, parseUnverifiedRoomKeyData, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, roomSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAllClientViews, selectAppDisplayName, selectAppExternalId, selectAppInitialConfig, selectAppIsActive, selectAppIsNodeSdk, selectAppRaw, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAuthorizationRoleName, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, 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, selectNumParticipants, selectOrganizationId, selectOrganizationRaw, selectRemoteClientViews, 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, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectSpotlightedClientViews, selectSpotlights, selectSpotlightsRaw, 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 };
|