@whereby.com/core 0.12.0 → 0.13.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 CHANGED
@@ -45,9 +45,9 @@ const createReactor = (selectors, callback) => {
45
45
  });
46
46
  };
47
47
 
48
- const coreVersion = "0.12.0";
48
+ const coreVersion = "0.13.0";
49
49
 
50
- const initialState$d = {
50
+ const initialState$e = {
51
51
  isNodeSdk: false,
52
52
  wantsToJoin: false,
53
53
  roomName: null,
@@ -58,7 +58,7 @@ const initialState$d = {
58
58
  };
59
59
  const appSlice = toolkit.createSlice({
60
60
  name: "app",
61
- initialState: initialState$d,
61
+ initialState: initialState$e,
62
62
  reducers: {
63
63
  doAppJoin: (state, action) => {
64
64
  const url = new URL(action.payload.roomUrl);
@@ -105,6 +105,43 @@ const signalEvents = {
105
105
  videoEnabled: createSignalEventAction("videoEnabled"),
106
106
  };
107
107
 
108
+ const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
109
+ canLockRoom: ["host"],
110
+ canRequestAudioEnable: ["host"],
111
+ canKickClient: ["host"],
112
+ canEndMeeting: ["host"],
113
+ };
114
+ const initialState$d = {
115
+ roomKey: null,
116
+ roleName: "none",
117
+ };
118
+ const authorizationSlice = toolkit.createSlice({
119
+ name: "authorization",
120
+ initialState: initialState$d,
121
+ reducers: {
122
+ setRoomKey: (state, action) => {
123
+ return Object.assign(Object.assign({}, state), { roomKey: action.payload });
124
+ },
125
+ },
126
+ extraReducers: (builder) => {
127
+ builder.addCase(doAppJoin, (state, action) => {
128
+ return Object.assign(Object.assign({}, state), { roomKey: action.payload.roomKey });
129
+ });
130
+ builder.addCase(signalEvents.roomJoined, (state, action) => {
131
+ var _a, _b;
132
+ const client = (_b = (_a = action.payload) === null || _a === void 0 ? void 0 : _a.room) === null || _b === void 0 ? void 0 : _b.clients.find((c) => { var _a; return c.id === ((_a = action.payload) === null || _a === void 0 ? void 0 : _a.selfId); });
133
+ return Object.assign(Object.assign({}, state), { roleName: (client === null || client === void 0 ? void 0 : client.role.roleName) || "none" });
134
+ });
135
+ },
136
+ });
137
+ const { setRoomKey } = authorizationSlice.actions;
138
+ const selectRoomKey = (state) => state.authorization.roomKey;
139
+ const selectAuthorizationRoleName = (state) => state.authorization.roleName;
140
+ const selectIsAuthorizedToLockRoom = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canLockRoom.includes(localParticipantRole));
141
+ const selectIsAuthorizedToRequestAudioEnable = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
142
+ const selectIsAuthorizedToKickClient = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canKickClient.includes(localParticipantRole));
143
+ const selectIsAuthorizedToEndMeeting = toolkit.createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canEndMeeting.includes(localParticipantRole));
144
+
108
145
  /******************************************************************************
109
146
  Copyright (c) Microsoft Corporation.
110
147
 
@@ -327,6 +364,92 @@ createReactor([selectShouldIdentifyDevice, selectDeviceCredentialsRaw], ({ dispa
327
364
  }
328
365
  });
329
366
 
367
+ const initialState$a = {
368
+ chatMessages: [],
369
+ };
370
+ const chatSlice = toolkit.createSlice({
371
+ name: "chat",
372
+ initialState: initialState$a,
373
+ reducers: {},
374
+ extraReducers(builder) {
375
+ builder.addCase(signalEvents.chatMessage, (state, action) => {
376
+ const message = {
377
+ senderId: action.payload.senderId,
378
+ timestamp: action.payload.timestamp,
379
+ text: action.payload.text,
380
+ };
381
+ return Object.assign(Object.assign({}, state), { chatMessages: [...state.chatMessages, message] });
382
+ });
383
+ },
384
+ });
385
+ const doSendChatMessage = createAppThunk((payload) => (_, getState) => {
386
+ const state = getState();
387
+ const socket = selectSignalConnectionRaw(state).socket;
388
+ socket === null || socket === void 0 ? void 0 : socket.emit("chat_message", { text: payload.text });
389
+ });
390
+ const selectChatRaw = (state) => state.chat;
391
+ const selectChatMessages = (state) => state.chat.chatMessages;
392
+
393
+ const initialCloudRecordingState = {
394
+ isRecording: false,
395
+ error: null,
396
+ startedAt: undefined,
397
+ };
398
+ const cloudRecordingSlice = toolkit.createSlice({
399
+ name: "cloudRecording",
400
+ initialState: initialCloudRecordingState,
401
+ reducers: {
402
+ recordingRequestStarted: (state) => {
403
+ return Object.assign(Object.assign({}, state), { status: "requested" });
404
+ },
405
+ },
406
+ extraReducers: (builder) => {
407
+ builder.addCase(signalEvents.cloudRecordingStopped, (state) => {
408
+ return Object.assign(Object.assign({}, state), { isRecording: false, status: undefined });
409
+ });
410
+ builder.addCase(signalEvents.cloudRecordingStarted, (state, action) => {
411
+ const { payload } = action;
412
+ if (!payload.error) {
413
+ return state;
414
+ }
415
+ return Object.assign(Object.assign({}, state), { isRecording: false, status: "error", error: payload.error });
416
+ });
417
+ builder.addCase(signalEvents.newClient, (state, { payload }) => {
418
+ var _a;
419
+ const { client } = payload;
420
+ if (((_a = client.role) === null || _a === void 0 ? void 0 : _a.roleName) === "recorder") {
421
+ return Object.assign(Object.assign({}, state), { isRecording: true, status: "recording", startedAt: client.startedCloudRecordingAt
422
+ ? new Date(client.startedCloudRecordingAt).getTime()
423
+ : new Date().getTime() });
424
+ }
425
+ return state;
426
+ });
427
+ },
428
+ });
429
+ const { recordingRequestStarted } = cloudRecordingSlice.actions;
430
+ const doStartCloudRecording = createAppThunk(() => (dispatch, getState) => {
431
+ const state = getState();
432
+ const socket = selectSignalConnectionRaw(state).socket;
433
+ const status = selectCloudRecordingStatus(state);
434
+ if (status && ["recording", "requested"].includes(status)) {
435
+ return;
436
+ }
437
+ socket === null || socket === void 0 ? void 0 : socket.emit("start_recording", {
438
+ recording: "cloud",
439
+ });
440
+ dispatch(recordingRequestStarted());
441
+ });
442
+ const doStopCloudRecording = createAppThunk(() => (dispatch, getState) => {
443
+ const state = getState();
444
+ const socket = selectSignalConnectionRaw(state).socket;
445
+ socket === null || socket === void 0 ? void 0 : socket.emit("stop_recording");
446
+ });
447
+ const selectCloudRecordingRaw = (state) => state.cloudRecording;
448
+ const selectCloudRecordingStatus = (state) => state.cloudRecording.status;
449
+ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
450
+ const selectCloudRecordingError = (state) => state.cloudRecording.error;
451
+ const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
452
+
330
453
  function fakeAudioStream() {
331
454
  const audioCtx = new AudioContext();
332
455
  const oscillator = audioCtx.createOscillator();
@@ -457,6 +580,7 @@ const initialLocalMediaState = {
457
580
  isSettingCameraDevice: false,
458
581
  isSettingMicrophoneDevice: false,
459
582
  isTogglingCamera: false,
583
+ lowDataMode: false,
460
584
  microphoneEnabled: false,
461
585
  status: "",
462
586
  isSwitchingStream: false,
@@ -485,6 +609,10 @@ const localMediaSlice = toolkit.createSlice({
485
609
  setCurrentMicrophoneDeviceId(state, action) {
486
610
  return Object.assign(Object.assign({}, state), { currentMicrophoneDeviceId: action.payload.deviceId });
487
611
  },
612
+ toggleLowDataModeEnabled(state, action) {
613
+ var _a;
614
+ return Object.assign(Object.assign({}, state), { lowDataMode: (_a = action.payload.enabled) !== null && _a !== void 0 ? _a : !state.lowDataMode });
615
+ },
488
616
  setDevices(state, action) {
489
617
  return Object.assign(Object.assign({}, state), { devices: action.payload.devices });
490
618
  },
@@ -563,7 +691,7 @@ const localMediaSlice = toolkit.createSlice({
563
691
  });
564
692
  },
565
693
  });
566
- const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
694
+ const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, toggleLowDataModeEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
567
695
  const doToggleCamera = createAppAsyncThunk("localMedia/doToggleCamera", (_, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
568
696
  const state = getState();
569
697
  const stream = selectLocalMediaStream(state);
@@ -612,6 +740,16 @@ const doToggleMicrophone = createAppAsyncThunk("localMedia/doToggleMicrophone",
612
740
  }
613
741
  audioTrack.enabled = enabled;
614
742
  });
743
+ const doToggleLowDataMode = createAppThunk(() => (dispatch, getState) => {
744
+ const state = getState();
745
+ const stream = selectLocalMediaStream(state);
746
+ if (!stream) {
747
+ return;
748
+ }
749
+ const videoId = selectCurrentCameraDeviceId(state);
750
+ const audioId = selectCurrentMicrophoneDeviceId(state);
751
+ dispatch(doSwitchLocalStream({ audioId, videoId }));
752
+ });
615
753
  const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", ({ audio, video }, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
616
754
  try {
617
755
  const state = getState();
@@ -635,12 +773,11 @@ const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", ({ audio, v
635
773
  }
636
774
  }));
637
775
  const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList", (_, { getState, dispatch, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
638
- var _a, _b;
776
+ var _a, _b, _c, _d;
639
777
  const state = getState();
640
778
  let newDevices = [];
641
779
  let oldDevices = [];
642
780
  const stream = selectLocalMediaStream(state);
643
- const busy = selectBusyDeviceIds(state);
644
781
  try {
645
782
  newDevices = yield navigator.mediaDevices.enumerateDevices();
646
783
  oldDevices = selectLocalMediaDevices(state);
@@ -652,39 +789,17 @@ const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList",
652
789
  if (!shouldHandleDeviceUpdate) {
653
790
  return { devices: newDevices };
654
791
  }
655
- const { changedDevices } = media.getUpdatedDevices({
792
+ const { changedDevices, addedDevices } = media.getUpdatedDevices({
656
793
  oldDevices,
657
794
  newDevices,
658
- currentAudioId: selectCurrentMicrophoneDeviceId(state),
659
- currentVideoId: selectCurrentCameraDeviceId(state),
660
795
  });
661
796
  let autoSwitchAudioId = (_a = changedDevices.audioinput) === null || _a === void 0 ? void 0 : _a.deviceId;
662
797
  let autoSwitchVideoId = (_b = changedDevices.videoinput) === null || _b === void 0 ? void 0 : _b.deviceId;
663
- function nextId(devices, id) {
664
- const curIdx = id ? devices.findIndex((d) => d.deviceId === id) : 0;
665
- return (devices[(curIdx + 1) % devices.length] || {}).deviceId;
666
- }
667
- if (autoSwitchVideoId !== undefined) {
668
- const videoDevices = selectLocalMediaDevices(state).filter((d) => d.kind === "videoinput");
669
- const videoId = selectCurrentCameraDeviceId(state);
670
- let nextVideoId = nextId(videoDevices.filter((d) => !busy.includes(d.deviceId)), videoId);
671
- if (!nextVideoId || videoId === nextVideoId) {
672
- nextVideoId = nextId(videoDevices, videoId);
673
- }
674
- if (videoId !== nextVideoId) {
675
- autoSwitchVideoId = nextVideoId;
676
- }
798
+ if (autoSwitchAudioId === undefined) {
799
+ autoSwitchAudioId = (_c = addedDevices.audioinput) === null || _c === void 0 ? void 0 : _c.deviceId;
677
800
  }
678
- if (autoSwitchAudioId !== undefined) {
679
- const audioDevices = selectLocalMediaDevices(state).filter((d) => d.kind === "audioinput");
680
- const audioId = selectCurrentMicrophoneDeviceId(state);
681
- let nextAudioId = nextId(audioDevices.filter((d) => !busy.includes(d.deviceId)), audioId);
682
- if (!nextAudioId || audioId === nextAudioId) {
683
- nextAudioId = nextId(audioDevices, audioId);
684
- }
685
- if (audioId !== nextAudioId) {
686
- autoSwitchAudioId = nextAudioId;
687
- }
801
+ if (autoSwitchVideoId === undefined) {
802
+ autoSwitchVideoId = (_d = addedDevices.videoinput) === null || _d === void 0 ? void 0 : _d.deviceId;
688
803
  }
689
804
  if (autoSwitchAudioId !== undefined || autoSwitchVideoId !== undefined) {
690
805
  dispatch(doSwitchLocalStream({ audioId: autoSwitchAudioId, videoId: autoSwitchVideoId }));
@@ -768,6 +883,7 @@ const selectCurrentCameraDeviceId = (state) => state.localMedia.currentCameraDev
768
883
  const selectCurrentMicrophoneDeviceId = (state) => state.localMedia.currentMicrophoneDeviceId;
769
884
  const selectIsCameraEnabled = (state) => state.localMedia.cameraEnabled;
770
885
  const selectIsMicrophoneEnabled = (state) => state.localMedia.microphoneEnabled;
886
+ const selectIsLowDataModeEnabled = (state) => state.localMedia.lowDataMode;
771
887
  const selectIsSettingCameraDevice = (state) => state.localMedia.isSettingCameraDevice;
772
888
  const selectIsSettingMicrophoneDevice = (state) => state.localMedia.isSettingMicrophoneDevice;
773
889
  const selectIsToggleCamera = (state) => state.localMedia.isTogglingCamera;
@@ -780,14 +896,16 @@ const selectLocalMediaStream = (state) => state.localMedia.stream;
780
896
  const selectMicrophoneDeviceError = (state) => state.localMedia.microphoneDeviceError;
781
897
  const selectLocalMediaStartError = (state) => state.localMedia.startError;
782
898
  const selectLocalMediaIsSwitchingStream = (state) => state.localMedia.isSwitchingStream;
783
- const selectLocalMediaConstraintsOptions = toolkit.createSelector(selectLocalMediaDevices, (devices) => ({
899
+ const selectLocalMediaConstraintsOptions = toolkit.createSelector(selectLocalMediaDevices, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectIsLowDataModeEnabled, (devices, videoId, audioId, lowDataMode) => ({
784
900
  devices,
901
+ videoId,
902
+ audioId,
785
903
  options: {
786
904
  disableAEC: false,
787
905
  disableAGC: false,
788
906
  hd: true,
789
907
  lax: false,
790
- lowDataMode: false,
908
+ lowDataMode,
791
909
  simulcast: true,
792
910
  widescreen: true,
793
911
  },
@@ -825,6 +943,17 @@ startAppListening({
825
943
  dispatch(doToggleMicrophone());
826
944
  },
827
945
  });
946
+ startAppListening({
947
+ predicate: (_action, currentState, previousState) => {
948
+ const oldValue = selectIsLowDataModeEnabled(previousState);
949
+ const newValue = selectIsLowDataModeEnabled(currentState);
950
+ const isReady = selectLocalMediaStatus(previousState) === "started";
951
+ return isReady && oldValue !== newValue;
952
+ },
953
+ effect: (_action, { dispatch }) => {
954
+ dispatch(doToggleLowDataMode());
955
+ },
956
+ });
828
957
  startAppListening({
829
958
  predicate: (_action, currentState, previousState) => {
830
959
  const isToggling = selectIsToggleCamera(currentState);
@@ -888,7 +1017,7 @@ startAppListening({
888
1017
  },
889
1018
  });
890
1019
 
891
- const initialState$a = {
1020
+ const initialState$9 = {
892
1021
  displayName: "",
893
1022
  id: "",
894
1023
  isAudioEnabled: true,
@@ -922,7 +1051,7 @@ const doSetDisplayName = createAppAsyncThunk("localParticipant/doSetDisplayName"
922
1051
  }));
923
1052
  const localParticipantSlice = toolkit.createSlice({
924
1053
  name: "localParticipant",
925
- initialState: initialState$a,
1054
+ initialState: initialState$9,
926
1055
  reducers: {
927
1056
  doSetLocalParticipant: (state, action) => {
928
1057
  return Object.assign(Object.assign({}, state), action.payload);
@@ -952,7 +1081,6 @@ const { doSetLocalParticipant } = localParticipantSlice.actions;
952
1081
  const selectLocalParticipantRaw = (state) => state.localParticipant;
953
1082
  const selectSelfId = (state) => state.localParticipant.id;
954
1083
  const selectLocalParticipantClientClaim = (state) => state.localParticipant.clientClaim;
955
- const selectLocalParticipantRole = (state) => state.localParticipant.roleName;
956
1084
  const selectLocalParticipantIsScreenSharing = (state) => state.localParticipant.isScreenSharing;
957
1085
  startAppListening({
958
1086
  actionCreator: toggleCameraEnabled,
@@ -971,144 +1099,14 @@ startAppListening({
971
1099
  },
972
1100
  });
973
1101
 
974
- const ACTION_PERMISSIONS_BY_ROLE = {
975
- canLockRoom: ["host"],
976
- canRequestAudioEnable: ["host"],
977
- };
978
- const initialState$9 = {
979
- roomKey: null,
980
- roomLocked: false,
981
- };
982
- const authorizationSlice = toolkit.createSlice({
983
- name: "authorization",
984
- initialState: initialState$9,
985
- reducers: {
986
- setRoomKey: (state, action) => {
987
- return Object.assign(Object.assign({}, state), { roomKey: action.payload });
988
- },
989
- },
990
- extraReducers: (builder) => {
991
- builder.addCase(doAppJoin, (state, action) => {
992
- return Object.assign(Object.assign({}, state), { roomKey: action.payload.roomKey });
993
- });
994
- builder.addCase(signalEvents.roomJoined, (state, action) => {
995
- const { error, isLocked } = action.payload;
996
- if (error) {
997
- return state;
998
- }
999
- return Object.assign(Object.assign({}, state), { roomLocked: isLocked });
1000
- });
1001
- builder.addCase(signalEvents.roomLocked, (state, action) => {
1002
- const { isLocked } = action.payload;
1003
- return Object.assign(Object.assign({}, state), { roomLocked: isLocked });
1004
- });
1005
- },
1006
- });
1007
- const { setRoomKey } = authorizationSlice.actions;
1008
- const doLockRoom = createAppAuthorizedThunk((state) => selectIsAuthorizedToLockRoom(state), (payload) => (_, getState) => {
1009
- const state = getState();
1010
- const { socket } = selectSignalConnectionRaw(state);
1011
- socket === null || socket === void 0 ? void 0 : socket.emit("set_lock", { locked: payload.locked });
1012
- });
1013
- const selectAuthorizationRoomKey = (state) => state.authorization.roomKey;
1014
- const selectAuthorizationRoomLocked = (state) => state.authorization.roomLocked;
1015
- const selectIsAuthorizedToLockRoom = toolkit.createSelector(selectLocalParticipantRole, (localParticipantRole) => ACTION_PERMISSIONS_BY_ROLE.canLockRoom.includes(localParticipantRole));
1016
- const selectIsAuthorizedToRequestAudioEnable = toolkit.createSelector(selectLocalParticipantRole, (localParticipantRole) => ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
1017
-
1018
1102
  const initialState$8 = {
1019
- chatMessages: [],
1020
- };
1021
- const chatSlice = toolkit.createSlice({
1022
- name: "chat",
1023
- initialState: initialState$8,
1024
- reducers: {},
1025
- extraReducers(builder) {
1026
- builder.addCase(signalEvents.chatMessage, (state, action) => {
1027
- const message = {
1028
- senderId: action.payload.senderId,
1029
- timestamp: action.payload.timestamp,
1030
- text: action.payload.text,
1031
- };
1032
- return Object.assign(Object.assign({}, state), { chatMessages: [...state.chatMessages, message] });
1033
- });
1034
- },
1035
- });
1036
- const doSendChatMessage = createAppThunk((payload) => (_, getState) => {
1037
- const state = getState();
1038
- const socket = selectSignalConnectionRaw(state).socket;
1039
- socket === null || socket === void 0 ? void 0 : socket.emit("chat_message", { text: payload.text });
1040
- });
1041
- const selectChatRaw = (state) => state.chat;
1042
- const selectChatMessages = (state) => state.chat.chatMessages;
1043
-
1044
- const initialCloudRecordingState = {
1045
- isRecording: false,
1046
- error: null,
1047
- startedAt: undefined,
1048
- };
1049
- const cloudRecordingSlice = toolkit.createSlice({
1050
- name: "cloudRecording",
1051
- initialState: initialCloudRecordingState,
1052
- reducers: {
1053
- recordingRequestStarted: (state) => {
1054
- return Object.assign(Object.assign({}, state), { status: "requested" });
1055
- },
1056
- },
1057
- extraReducers: (builder) => {
1058
- builder.addCase(signalEvents.cloudRecordingStopped, (state) => {
1059
- return Object.assign(Object.assign({}, state), { isRecording: false, status: undefined });
1060
- });
1061
- builder.addCase(signalEvents.cloudRecordingStarted, (state, action) => {
1062
- const { payload } = action;
1063
- if (!payload.error) {
1064
- return state;
1065
- }
1066
- return Object.assign(Object.assign({}, state), { isRecording: false, status: "error", error: payload.error });
1067
- });
1068
- builder.addCase(signalEvents.newClient, (state, { payload }) => {
1069
- var _a;
1070
- const { client } = payload;
1071
- if (((_a = client.role) === null || _a === void 0 ? void 0 : _a.roleName) === "recorder") {
1072
- return Object.assign(Object.assign({}, state), { isRecording: true, status: "recording", startedAt: client.startedCloudRecordingAt
1073
- ? new Date(client.startedCloudRecordingAt).getTime()
1074
- : new Date().getTime() });
1075
- }
1076
- return state;
1077
- });
1078
- },
1079
- });
1080
- const { recordingRequestStarted } = cloudRecordingSlice.actions;
1081
- const doStartCloudRecording = createAppThunk(() => (dispatch, getState) => {
1082
- const state = getState();
1083
- const socket = selectSignalConnectionRaw(state).socket;
1084
- const status = selectCloudRecordingStatus(state);
1085
- if (status && ["recording", "requested"].includes(status)) {
1086
- return;
1087
- }
1088
- socket === null || socket === void 0 ? void 0 : socket.emit("start_recording", {
1089
- recording: "cloud",
1090
- });
1091
- dispatch(recordingRequestStarted());
1092
- });
1093
- const doStopCloudRecording = createAppThunk(() => (dispatch, getState) => {
1094
- const state = getState();
1095
- const socket = selectSignalConnectionRaw(state).socket;
1096
- socket === null || socket === void 0 ? void 0 : socket.emit("stop_recording");
1097
- });
1098
- const selectCloudRecordingRaw = (state) => state.cloudRecording;
1099
- const selectCloudRecordingStatus = (state) => state.cloudRecording.status;
1100
- const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
1101
- const selectCloudRecordingError = (state) => state.cloudRecording.error;
1102
- const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
1103
-
1104
- const initialState$7 = {
1105
1103
  status: "",
1106
1104
  stream: null,
1107
1105
  error: null,
1108
1106
  };
1109
1107
  const localScreenshareSlice = toolkit.createSlice({
1110
1108
  name: "localScreenshare",
1111
- initialState: initialState$7,
1109
+ initialState: initialState$8,
1112
1110
  reducers: {
1113
1111
  stopScreenshare(state, action) {
1114
1112
  return Object.assign(Object.assign({}, state), { status: "", stream: null });
@@ -1177,13 +1175,13 @@ startAppListening({
1177
1175
  },
1178
1176
  });
1179
1177
 
1180
- const initialState$6 = {
1178
+ const initialState$7 = {
1181
1179
  data: null,
1182
1180
  isFetching: false,
1183
1181
  error: null,
1184
1182
  };
1185
1183
  const organizationSlice = toolkit.createSlice({
1186
- initialState: initialState$6,
1184
+ initialState: initialState$7,
1187
1185
  name: "organization",
1188
1186
  reducers: {},
1189
1187
  extraReducers: (builder) => {
@@ -1332,12 +1330,12 @@ function addStream(state, payload) {
1332
1330
  presentationStream: stream,
1333
1331
  });
1334
1332
  }
1335
- const initialState$5 = {
1333
+ const initialState$6 = {
1336
1334
  remoteParticipants: [],
1337
1335
  };
1338
1336
  const remoteParticipantsSlice = toolkit.createSlice({
1339
1337
  name: "remoteParticipants",
1340
- initialState: initialState$5,
1338
+ initialState: initialState$6,
1341
1339
  reducers: {
1342
1340
  streamStatusUpdated: (state, action) => {
1343
1341
  let newState = state;
@@ -1444,6 +1442,47 @@ const selectScreenshares = toolkit.createSelector(selectLocalScreenshareStream,
1444
1442
  return screenshares;
1445
1443
  });
1446
1444
 
1445
+ const initialState$5 = {
1446
+ isLocked: false,
1447
+ };
1448
+ const roomSlice = toolkit.createSlice({
1449
+ name: "room",
1450
+ initialState: initialState$5,
1451
+ reducers: {},
1452
+ extraReducers: (builder) => {
1453
+ builder.addCase(signalEvents.roomJoined, (state, action) => {
1454
+ const { error, isLocked } = action.payload;
1455
+ if (error) {
1456
+ return state;
1457
+ }
1458
+ return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
1459
+ });
1460
+ builder.addCase(signalEvents.roomLocked, (state, action) => {
1461
+ const { isLocked } = action.payload;
1462
+ return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
1463
+ });
1464
+ },
1465
+ });
1466
+ const doLockRoom = createAppAuthorizedThunk((state) => selectIsAuthorizedToLockRoom(state), (payload) => (_, getState) => {
1467
+ const state = getState();
1468
+ const { socket } = selectSignalConnectionRaw(state);
1469
+ socket === null || socket === void 0 ? void 0 : socket.emit("set_lock", { locked: payload.locked });
1470
+ });
1471
+ const doKickParticipant = createAppAuthorizedThunk((state) => selectIsAuthorizedToKickClient(state), (payload) => (_, getState) => {
1472
+ const state = getState();
1473
+ const { socket } = selectSignalConnectionRaw(state);
1474
+ socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientId: payload.clientId, reasonId: "kick" });
1475
+ });
1476
+ const doEndMeeting = createAppAuthorizedThunk((state) => selectIsAuthorizedToEndMeeting(state), () => (_, getState) => {
1477
+ const state = getState();
1478
+ const clientsToKick = selectRemoteParticipants(state).map((c) => c.id);
1479
+ if (clientsToKick.length) {
1480
+ const { socket } = selectSignalConnectionRaw(state);
1481
+ socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientIds: clientsToKick, reasonId: "end-meeting" });
1482
+ }
1483
+ });
1484
+ const selectRoomIsLocked = (state) => state.room.isLocked;
1485
+
1447
1486
  const initialState$4 = {
1448
1487
  session: null,
1449
1488
  status: "initializing",
@@ -1496,7 +1535,7 @@ const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
1496
1535
  const state = getState();
1497
1536
  const socket = selectSignalConnectionRaw(state).socket;
1498
1537
  const roomName = selectAppRoomName(state);
1499
- const roomKey = selectAuthorizationRoomKey(state);
1538
+ const roomKey = selectRoomKey(state);
1500
1539
  const displayName = selectAppDisplayName(state);
1501
1540
  const userAgent = selectAppUserAgent(state);
1502
1541
  const externalId = selectAppExternalId(state);
@@ -1515,7 +1554,6 @@ const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
1515
1554
  organizationId,
1516
1555
  roomKey,
1517
1556
  roomName,
1518
- selfId: "",
1519
1557
  userAgent,
1520
1558
  externalId,
1521
1559
  });
@@ -1525,23 +1563,22 @@ const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
1525
1563
  const state = getState();
1526
1564
  const socket = selectSignalConnectionRaw(state).socket;
1527
1565
  const roomName = selectAppRoomName(state);
1528
- const roomKey = selectAuthorizationRoomKey(state);
1566
+ const roomKey = selectRoomKey(state);
1529
1567
  const displayName = selectAppDisplayName(state);
1530
1568
  const userAgent = selectAppUserAgent(state);
1531
1569
  const externalId = selectAppExternalId(state);
1532
1570
  const organizationId = selectOrganizationId(state);
1533
1571
  const isCameraEnabled = selectIsCameraEnabled(getState());
1534
1572
  const isMicrophoneEnabled = selectIsMicrophoneEnabled(getState());
1535
- const selfId = selectSelfId(getState());
1536
1573
  const clientClaim = selectLocalParticipantClientClaim(getState());
1537
- socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign(Object.assign({ avatarUrl: null, config: {
1574
+ socket === null || socket === void 0 ? void 0 : socket.emit("join_room", Object.assign({ avatarUrl: null, config: {
1538
1575
  isAudioEnabled: isMicrophoneEnabled,
1539
1576
  isVideoEnabled: isCameraEnabled,
1540
1577
  }, deviceCapabilities: { canScreenshare: true }, displayName, isCoLocated: false, isDevicePermissionDenied: false, kickFromOtherRooms: false, organizationId,
1541
1578
  roomKey,
1542
1579
  roomName,
1543
- selfId }, (!!clientClaim && { clientClaim })), { userAgent,
1544
- externalId }));
1580
+ userAgent,
1581
+ externalId }, (clientClaim && { clientClaim })));
1545
1582
  dispatch(connectionStatusChanged("connecting"));
1546
1583
  });
1547
1584
  const selectRoomConnectionRaw = (state) => state.roomConnection;
@@ -1798,6 +1835,23 @@ startAppListening({
1798
1835
  rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.removeStream(stream.id, stream, null);
1799
1836
  },
1800
1837
  });
1838
+ startAppListening({
1839
+ actionCreator: doSwitchLocalStream.fulfilled,
1840
+ effect: ({ payload }, { getState }) => {
1841
+ var _a;
1842
+ const stream = selectLocalMediaStream(getState());
1843
+ const { rtcManager } = selectRtcConnectionRaw(getState());
1844
+ if (stream && rtcManager) {
1845
+ const replace = (kind, oldTrack) => {
1846
+ const track = stream.getTracks().find((t) => t.kind === kind);
1847
+ return track && rtcManager.replaceTrack(oldTrack, track);
1848
+ };
1849
+ (_a = payload === null || payload === void 0 ? void 0 : payload.replacedTracks) === null || _a === void 0 ? void 0 : _a.forEach((t) => {
1850
+ replace(t.kind, t);
1851
+ });
1852
+ }
1853
+ },
1854
+ });
1801
1855
  const selectShouldConnectRtc = toolkit.createSelector(selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectSignalConnectionSocket, (dispatcherCreated, isCreatingDispatcher, signalSocket) => {
1802
1856
  if (!dispatcherCreated && !isCreatingDispatcher && signalSocket) {
1803
1857
  return true;
@@ -1963,7 +2017,7 @@ const rtcAnalyticsCustomEvents = {
1963
2017
  userRole: {
1964
2018
  actions: null,
1965
2019
  rtcEventName: "userRole",
1966
- getValue: (state) => selectLocalParticipantRole(state),
2020
+ getValue: (state) => selectAuthorizationRoleName(state),
1967
2021
  getOutput: (value) => ({ userRole: value }),
1968
2022
  },
1969
2023
  };
@@ -2125,6 +2179,7 @@ const rootReducer = toolkit.combineReducers({
2125
2179
  localScreenshare: localScreenshareSlice.reducer,
2126
2180
  organization: organizationSlice.reducer,
2127
2181
  remoteParticipants: remoteParticipantsSlice.reducer,
2182
+ room: roomSlice.reducer,
2128
2183
  roomConnection: roomConnectionSlice.reducer,
2129
2184
  rtcAnalytics: rtcAnalyticsSlice.reducer,
2130
2185
  rtcConnection: rtcConnectionSlice.reducer,
@@ -3199,10 +3254,12 @@ exports.doConnectRtc = doConnectRtc;
3199
3254
  exports.doDisconnectRtc = doDisconnectRtc;
3200
3255
  exports.doEnableAudio = doEnableAudio;
3201
3256
  exports.doEnableVideo = doEnableVideo;
3257
+ exports.doEndMeeting = doEndMeeting;
3202
3258
  exports.doGetDeviceCredentials = doGetDeviceCredentials;
3203
3259
  exports.doHandleAcceptStreams = doHandleAcceptStreams;
3204
3260
  exports.doHandleStreamingStarted = doHandleStreamingStarted;
3205
3261
  exports.doHandleStreamingStopped = doHandleStreamingStopped;
3262
+ exports.doKickParticipant = doKickParticipant;
3206
3263
  exports.doKnockRoom = doKnockRoom;
3207
3264
  exports.doLockRoom = doLockRoom;
3208
3265
  exports.doOrganizationFetch = doOrganizationFetch;
@@ -3227,6 +3284,7 @@ exports.doStopLocalMedia = doStopLocalMedia;
3227
3284
  exports.doStopScreenshare = doStopScreenshare;
3228
3285
  exports.doSwitchLocalStream = doSwitchLocalStream;
3229
3286
  exports.doToggleCamera = doToggleCamera;
3287
+ exports.doToggleLowDataMode = doToggleLowDataMode;
3230
3288
  exports.doUpdateDeviceList = doUpdateDeviceList;
3231
3289
  exports.fakeAudioStream = fakeAudioStream;
3232
3290
  exports.fakeWebcamFrame = fakeWebcamFrame;
@@ -3249,6 +3307,7 @@ exports.recordingRequestStarted = recordingRequestStarted;
3249
3307
  exports.remoteParticipantsSlice = remoteParticipantsSlice;
3250
3308
  exports.resolutionReported = resolutionReported;
3251
3309
  exports.roomConnectionSlice = roomConnectionSlice;
3310
+ exports.roomSlice = roomSlice;
3252
3311
  exports.rootReducer = rootReducer;
3253
3312
  exports.rtcAnalyticsCustomEvents = rtcAnalyticsCustomEvents;
3254
3313
  exports.rtcAnalyticsSlice = rtcAnalyticsSlice;
@@ -3266,8 +3325,7 @@ exports.selectAppRoomName = selectAppRoomName;
3266
3325
  exports.selectAppRoomUrl = selectAppRoomUrl;
3267
3326
  exports.selectAppUserAgent = selectAppUserAgent;
3268
3327
  exports.selectAppWantsToJoin = selectAppWantsToJoin;
3269
- exports.selectAuthorizationRoomKey = selectAuthorizationRoomKey;
3270
- exports.selectAuthorizationRoomLocked = selectAuthorizationRoomLocked;
3328
+ exports.selectAuthorizationRoleName = selectAuthorizationRoleName;
3271
3329
  exports.selectBusyDeviceIds = selectBusyDeviceIds;
3272
3330
  exports.selectCameraDeviceError = selectCameraDeviceError;
3273
3331
  exports.selectCameraDevices = selectCameraDevices;
@@ -3283,11 +3341,14 @@ exports.selectDeviceCredentialsRaw = selectDeviceCredentialsRaw;
3283
3341
  exports.selectDeviceId = selectDeviceId;
3284
3342
  exports.selectHasFetchedDeviceCredentials = selectHasFetchedDeviceCredentials;
3285
3343
  exports.selectIsAcceptingStreams = selectIsAcceptingStreams;
3344
+ exports.selectIsAuthorizedToEndMeeting = selectIsAuthorizedToEndMeeting;
3345
+ exports.selectIsAuthorizedToKickClient = selectIsAuthorizedToKickClient;
3286
3346
  exports.selectIsAuthorizedToLockRoom = selectIsAuthorizedToLockRoom;
3287
3347
  exports.selectIsAuthorizedToRequestAudioEnable = selectIsAuthorizedToRequestAudioEnable;
3288
3348
  exports.selectIsCameraEnabled = selectIsCameraEnabled;
3289
3349
  exports.selectIsCloudRecording = selectIsCloudRecording;
3290
3350
  exports.selectIsLocalMediaStarting = selectIsLocalMediaStarting;
3351
+ exports.selectIsLowDataModeEnabled = selectIsLowDataModeEnabled;
3291
3352
  exports.selectIsMicrophoneEnabled = selectIsMicrophoneEnabled;
3292
3353
  exports.selectIsSettingCameraDevice = selectIsSettingCameraDevice;
3293
3354
  exports.selectIsSettingMicrophoneDevice = selectIsSettingMicrophoneDevice;
@@ -3306,7 +3367,6 @@ exports.selectLocalMediaStream = selectLocalMediaStream;
3306
3367
  exports.selectLocalParticipantClientClaim = selectLocalParticipantClientClaim;
3307
3368
  exports.selectLocalParticipantIsScreenSharing = selectLocalParticipantIsScreenSharing;
3308
3369
  exports.selectLocalParticipantRaw = selectLocalParticipantRaw;
3309
- exports.selectLocalParticipantRole = selectLocalParticipantRole;
3310
3370
  exports.selectLocalScreenshareRaw = selectLocalScreenshareRaw;
3311
3371
  exports.selectLocalScreenshareStatus = selectLocalScreenshareStatus;
3312
3372
  exports.selectLocalScreenshareStream = selectLocalScreenshareStream;
@@ -3321,6 +3381,8 @@ exports.selectRoomConnectionRaw = selectRoomConnectionRaw;
3321
3381
  exports.selectRoomConnectionSession = selectRoomConnectionSession;
3322
3382
  exports.selectRoomConnectionSessionId = selectRoomConnectionSessionId;
3323
3383
  exports.selectRoomConnectionStatus = selectRoomConnectionStatus;
3384
+ exports.selectRoomIsLocked = selectRoomIsLocked;
3385
+ exports.selectRoomKey = selectRoomKey;
3324
3386
  exports.selectRtcConnectionRaw = selectRtcConnectionRaw;
3325
3387
  exports.selectRtcDispatcherCreated = selectRtcDispatcherCreated;
3326
3388
  exports.selectRtcIsCreatingDispatcher = selectRtcIsCreatingDispatcher;
@@ -3362,6 +3424,7 @@ exports.stopScreenshare = stopScreenshare;
3362
3424
  exports.streamStatusUpdated = streamStatusUpdated;
3363
3425
  exports.streamingSlice = streamingSlice;
3364
3426
  exports.toggleCameraEnabled = toggleCameraEnabled;
3427
+ exports.toggleLowDataModeEnabled = toggleLowDataModeEnabled;
3365
3428
  exports.toggleMicrophoneEnabled = toggleMicrophoneEnabled;
3366
3429
  exports.updateReportedValues = updateReportedValues;
3367
3430
  exports.waitingParticipantsSlice = waitingParticipantsSlice;