@whereby.com/core 1.9.2 → 1.9.4

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
@@ -1158,7 +1158,7 @@ const createReactor = (selectors, callback) => {
1158
1158
  });
1159
1159
  };
1160
1160
 
1161
- const coreVersion = "1.9.2";
1161
+ const coreVersion = "1.9.4";
1162
1162
 
1163
1163
  const initialState$1 = {
1164
1164
  displayName: null,
@@ -1728,7 +1728,7 @@ const doToggleCamera = createAppAsyncThunk("localMedia/doToggleCamera", (_1, _a)
1728
1728
  else {
1729
1729
  const constraintsOptions = selectLocalMediaConstraintsOptions(state);
1730
1730
  const cameraDeviceId = selectCurrentCameraDeviceId(state);
1731
- yield media.getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: false, videoId: cameraDeviceId || true, type: "exact" }), { replaceStream: stream });
1731
+ yield media.getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: false, videoId: cameraDeviceId, type: "exact" }), { replaceStream: stream });
1732
1732
  track = stream.getVideoTracks()[0];
1733
1733
  }
1734
1734
  }
@@ -1793,6 +1793,7 @@ const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", (_a, _b) =>
1793
1793
  }
1794
1794
  }));
1795
1795
  const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList", (_1, _a) => __awaiter(void 0, [_1, _a], void 0, function* (_, { getState, dispatch, rejectWithValue }) {
1796
+ var _b, _c, _d, _e;
1796
1797
  const state = getState();
1797
1798
  let newDevices = [];
1798
1799
  let oldDevices = [];
@@ -1808,29 +1809,19 @@ const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList",
1808
1809
  if (!shouldHandleDeviceUpdate) {
1809
1810
  return { devices: newDevices };
1810
1811
  }
1811
- const { currentCameraDeviceId, currentMicrophoneDeviceId, currentSpeakerDeviceId } = state.localMedia;
1812
- const { changedDevices, removedDevices } = media.getUpdatedDevices({
1812
+ const { changedDevices, addedDevices } = media.getUpdatedDevices({
1813
1813
  oldDevices,
1814
1814
  newDevices,
1815
- currentVideoId: currentCameraDeviceId,
1816
- currentAudioId: currentMicrophoneDeviceId,
1817
- currentSpeakerId: currentSpeakerDeviceId,
1818
1815
  });
1819
- let autoSwitchAudioId;
1820
- let autoSwitchVideoId;
1821
- if (removedDevices.audioinput) {
1822
- autoSwitchAudioId = true;
1816
+ let autoSwitchAudioId = (_b = changedDevices.audioinput) === null || _b === void 0 ? void 0 : _b.deviceId;
1817
+ let autoSwitchVideoId = (_c = changedDevices.videoinput) === null || _c === void 0 ? void 0 : _c.deviceId;
1818
+ if (autoSwitchAudioId === undefined) {
1819
+ autoSwitchAudioId = (_d = addedDevices.audioinput) === null || _d === void 0 ? void 0 : _d.deviceId;
1823
1820
  }
1824
- if (removedDevices.videoinput) {
1825
- autoSwitchVideoId = true;
1821
+ if (autoSwitchVideoId === undefined) {
1822
+ autoSwitchVideoId = (_e = addedDevices.videoinput) === null || _e === void 0 ? void 0 : _e.deviceId;
1826
1823
  }
1827
- if (!autoSwitchAudioId && changedDevices.audioinput) {
1828
- autoSwitchAudioId = changedDevices.audioinput.deviceId;
1829
- }
1830
- if (!autoSwitchVideoId && changedDevices.videoinput) {
1831
- autoSwitchVideoId = changedDevices.videoinput.deviceId;
1832
- }
1833
- if (autoSwitchAudioId || autoSwitchVideoId) {
1824
+ if (autoSwitchAudioId !== undefined || autoSwitchVideoId !== undefined) {
1834
1825
  dispatch(doSwitchLocalStream({ audioId: autoSwitchAudioId, videoId: autoSwitchVideoId }));
1835
1826
  }
1836
1827
  return { devices: newDevices };
@@ -1848,29 +1839,28 @@ const doSwitchLocalStream = createAppAsyncThunk("localMedia/doSwitchLocalStream"
1848
1839
  return;
1849
1840
  }
1850
1841
  const beforeEffectTracks = selectLocalMediaBeforeEffectTracks(state);
1851
- if (audioId && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.audio)) {
1842
+ if (audioId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.audio)) {
1852
1843
  beforeEffectTracks.audio.stop();
1853
1844
  beforeEffectTracks.audio = undefined;
1854
1845
  }
1855
- if (videoId && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.video)) {
1846
+ if (videoId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.video)) {
1856
1847
  beforeEffectTracks.video.stop();
1857
1848
  beforeEffectTracks.video = undefined;
1858
1849
  }
1859
1850
  try {
1860
- const { replacedTracks, error } = yield media.getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: audioId || false, videoId: videoId || false, type: "exact" }), { replaceStream });
1861
- if (error) {
1862
- const deviceId = audioId || videoId;
1863
- if (onlySwitchingOne && typeof deviceId === "string") {
1864
- dispatch(deviceBusy({
1865
- deviceId,
1866
- }));
1867
- }
1851
+ const { replacedTracks } = yield media.getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: audioId === undefined ? false : audioId, videoId: videoId === undefined ? false : videoId, type: "exact" }), { replaceStream });
1852
+ const deviceId = audioId || videoId;
1853
+ if (onlySwitchingOne && deviceId) {
1854
+ dispatch(deviceBusy({
1855
+ deviceId,
1856
+ }));
1868
1857
  }
1869
1858
  return { replacedTracks, beforeEffectTracks };
1870
1859
  }
1871
1860
  catch (error) {
1861
+ console.error(error);
1872
1862
  const deviceId = audioId || videoId;
1873
- if (onlySwitchingOne && typeof deviceId === "string") {
1863
+ if (onlySwitchingOne && deviceId) {
1874
1864
  dispatch(deviceBusy({
1875
1865
  deviceId,
1876
1866
  }));
@@ -2010,17 +2000,13 @@ createReactor([selectLocalMediaShouldStartWithOptions], ({ dispatch }, options)
2010
2000
  dispatch(doStartLocalMedia(options));
2011
2001
  }
2012
2002
  });
2013
- startAppListening({
2014
- predicate: (_action, currentState, previousState) => {
2015
- const oldValue = selectAppIsActive(previousState);
2016
- const newValue = selectAppIsActive(currentState);
2017
- const localMediaOptions = selectLocalMediaOptions(currentState);
2018
- const localMediaStatus = selectLocalMediaStatus(currentState);
2019
- return (oldValue === true && newValue === false) && localMediaStatus !== "inactive" && !!localMediaOptions;
2020
- },
2021
- effect: (_, { dispatch }) => {
2003
+ const selectLocalMediaShouldStop = toolkit.createSelector(selectAppIsActive, selectLocalMediaStatus, selectLocalMediaOptions, (appIsActive, localMediaStatus, localMediaOptions) => {
2004
+ return !appIsActive && localMediaStatus !== "inactive" && !!localMediaOptions;
2005
+ });
2006
+ createReactor([selectLocalMediaShouldStop], ({ dispatch }, localMediaShouldStop) => {
2007
+ if (localMediaShouldStop) {
2022
2008
  dispatch(doStopLocalMedia());
2023
- },
2009
+ }
2024
2010
  });
2025
2011
  startAppListening({
2026
2012
  predicate: (_action, currentState, previousState) => {
@@ -2061,25 +2047,10 @@ startAppListening({
2061
2047
  });
2062
2048
  startAppListening({
2063
2049
  predicate: (_action, currentState, previousState) => {
2064
- var _a, _b;
2065
- const oldDeviceId = selectCurrentCameraDeviceId(previousState);
2066
- const newDeviceId = selectCurrentCameraDeviceId(currentState);
2050
+ const oldValue = selectCurrentCameraDeviceId(previousState);
2051
+ const newValue = selectCurrentCameraDeviceId(currentState);
2067
2052
  const isReady = selectLocalMediaStatus(previousState) === "started";
2068
- const isSwitchingStream = selectLocalMediaIsSwitchingStream(currentState);
2069
- if (isSwitchingStream) {
2070
- return false;
2071
- }
2072
- if (!newDeviceId) {
2073
- return false;
2074
- }
2075
- const currentTrack = (_b = (_a = selectLocalMediaStream(currentState)) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b[0];
2076
- if (currentTrack && currentTrack.readyState === "live") {
2077
- const currentDeviceId = currentTrack.getSettings().deviceId;
2078
- if (currentDeviceId === newDeviceId) {
2079
- return false;
2080
- }
2081
- }
2082
- return isReady && oldDeviceId !== newDeviceId;
2053
+ return isReady && oldValue !== newValue;
2083
2054
  },
2084
2055
  effect: (_action, { dispatch }) => {
2085
2056
  dispatch(doSetDevice({ audio: false, video: true }));
@@ -2087,25 +2058,10 @@ startAppListening({
2087
2058
  });
2088
2059
  startAppListening({
2089
2060
  predicate: (_action, currentState, previousState) => {
2090
- var _a, _b;
2091
- const oldDeviceId = selectCurrentMicrophoneDeviceId(previousState);
2092
- const newDeviceId = selectCurrentMicrophoneDeviceId(currentState);
2061
+ const oldValue = selectCurrentMicrophoneDeviceId(previousState);
2062
+ const newValue = selectCurrentMicrophoneDeviceId(currentState);
2093
2063
  const isReady = selectLocalMediaStatus(previousState) === "started";
2094
- const isSwitchingStream = selectLocalMediaIsSwitchingStream(currentState);
2095
- if (isSwitchingStream) {
2096
- return false;
2097
- }
2098
- if (!newDeviceId) {
2099
- return false;
2100
- }
2101
- const currentTrack = (_b = (_a = selectLocalMediaStream(currentState)) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b[0];
2102
- if (currentTrack && currentTrack.readyState === "live") {
2103
- const currentDeviceId = currentTrack.getSettings().deviceId;
2104
- if (currentDeviceId === newDeviceId) {
2105
- return false;
2106
- }
2107
- }
2108
- return isReady && oldDeviceId !== newDeviceId;
2064
+ return isReady && oldValue !== newValue;
2109
2065
  },
2110
2066
  effect: (_action, { dispatch }) => {
2111
2067
  dispatch(doSetDevice({ audio: true, video: false }));
@@ -2924,6 +2880,15 @@ startAppListening({
2924
2880
  },
2925
2881
  });
2926
2882
 
2883
+ function isDeferrable({ client, breakoutCurrentId }) {
2884
+ if (!client)
2885
+ return false;
2886
+ if (!breakoutCurrentId && client.breakoutGroup)
2887
+ return true;
2888
+ if (!client.isAudioEnabled && !client.isVideoEnabled)
2889
+ return true;
2890
+ return false;
2891
+ }
2927
2892
  const createWebRtcEmitter = (dispatch) => {
2928
2893
  return {
2929
2894
  emit: (eventName, data) => {
@@ -3011,12 +2976,22 @@ const doConnectRtc = createAppThunk(() => (dispatch, getState) => {
3011
2976
  const state = getState();
3012
2977
  const socket = selectSignalConnectionRaw(state).socket;
3013
2978
  const dispatcher = selectRtcConnectionRaw(state).rtcManagerDispatcher;
2979
+ const isCameraEnabled = selectIsCameraEnabled(state);
2980
+ const isMicrophoneEnabled = selectIsMicrophoneEnabled(state);
3014
2981
  const isNodeSdk = selectAppIsNodeSdk(state);
3015
2982
  if (dispatcher || !socket) {
3016
2983
  return;
3017
2984
  }
3018
2985
  const webrtcProvider = {
3019
- getMediaConstraints: () => selectLocalMediaConstraintsOptions(state),
2986
+ getMediaConstraints: () => ({
2987
+ audio: isMicrophoneEnabled,
2988
+ video: isCameraEnabled,
2989
+ }),
2990
+ deferrable(clientId) {
2991
+ const client = selectRemoteParticipants(getState()).find((p) => p.id === clientId);
2992
+ const breakoutCurrentId = selectBreakoutCurrentId(getState()) || "";
2993
+ return isDeferrable({ client, breakoutCurrentId });
2994
+ },
3020
2995
  };
3021
2996
  const rtcManagerDispatcher = new media.RtcManagerDispatcher({
3022
2997
  emitter: createWebRtcEmitter(dispatch),
@@ -4646,10 +4621,6 @@ class LocalMediaClient extends BaseClient {
4646
4621
  }
4647
4622
  startMedia() {
4648
4623
  return __awaiter(this, arguments, void 0, function* (options = { audio: true, video: true }) {
4649
- const localMediaStatus = this.store.getState().localMedia.status;
4650
- if (["started", "starting"].includes(localMediaStatus)) {
4651
- return;
4652
- }
4653
4624
  return yield this.store.dispatch(doStartLocalMedia(options));
4654
4625
  });
4655
4626
  }
package/dist/index.d.cts CHANGED
@@ -1017,7 +1017,7 @@ declare class LocalMediaClient extends BaseClient<LocalMediaState, LocalMediaEve
1017
1017
  rejectedWithValue: true;
1018
1018
  } | ({
1019
1019
  rejectedWithValue: false;
1020
- } & {})), _reduxjs_toolkit.SerializedError> | undefined>;
1020
+ } & {})), _reduxjs_toolkit.SerializedError>>;
1021
1021
  toggleCamera(enabled?: boolean): void;
1022
1022
  toggleMicrophone(enabled?: boolean): void;
1023
1023
  toggleLowDataMode(enabled?: boolean): void;
package/dist/index.d.mts CHANGED
@@ -1017,7 +1017,7 @@ declare class LocalMediaClient extends BaseClient<LocalMediaState, LocalMediaEve
1017
1017
  rejectedWithValue: true;
1018
1018
  } | ({
1019
1019
  rejectedWithValue: false;
1020
- } & {})), _reduxjs_toolkit.SerializedError> | undefined>;
1020
+ } & {})), _reduxjs_toolkit.SerializedError>>;
1021
1021
  toggleCamera(enabled?: boolean): void;
1022
1022
  toggleMicrophone(enabled?: boolean): void;
1023
1023
  toggleLowDataMode(enabled?: boolean): void;
package/dist/index.d.ts CHANGED
@@ -1017,7 +1017,7 @@ declare class LocalMediaClient extends BaseClient<LocalMediaState, LocalMediaEve
1017
1017
  rejectedWithValue: true;
1018
1018
  } | ({
1019
1019
  rejectedWithValue: false;
1020
- } & {})), _reduxjs_toolkit.SerializedError> | undefined>;
1020
+ } & {})), _reduxjs_toolkit.SerializedError>>;
1021
1021
  toggleCamera(enabled?: boolean): void;
1022
1022
  toggleMicrophone(enabled?: boolean): void;
1023
1023
  toggleLowDataMode(enabled?: boolean): void;
package/dist/index.mjs CHANGED
@@ -1156,7 +1156,7 @@ const createReactor = (selectors, callback) => {
1156
1156
  });
1157
1157
  };
1158
1158
 
1159
- const coreVersion = "1.9.2";
1159
+ const coreVersion = "1.9.4";
1160
1160
 
1161
1161
  const initialState$1 = {
1162
1162
  displayName: null,
@@ -1726,7 +1726,7 @@ const doToggleCamera = createAppAsyncThunk("localMedia/doToggleCamera", (_1, _a)
1726
1726
  else {
1727
1727
  const constraintsOptions = selectLocalMediaConstraintsOptions(state);
1728
1728
  const cameraDeviceId = selectCurrentCameraDeviceId(state);
1729
- yield getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: false, videoId: cameraDeviceId || true, type: "exact" }), { replaceStream: stream });
1729
+ yield getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: false, videoId: cameraDeviceId, type: "exact" }), { replaceStream: stream });
1730
1730
  track = stream.getVideoTracks()[0];
1731
1731
  }
1732
1732
  }
@@ -1791,6 +1791,7 @@ const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", (_a, _b) =>
1791
1791
  }
1792
1792
  }));
1793
1793
  const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList", (_1, _a) => __awaiter(void 0, [_1, _a], void 0, function* (_, { getState, dispatch, rejectWithValue }) {
1794
+ var _b, _c, _d, _e;
1794
1795
  const state = getState();
1795
1796
  let newDevices = [];
1796
1797
  let oldDevices = [];
@@ -1806,29 +1807,19 @@ const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList",
1806
1807
  if (!shouldHandleDeviceUpdate) {
1807
1808
  return { devices: newDevices };
1808
1809
  }
1809
- const { currentCameraDeviceId, currentMicrophoneDeviceId, currentSpeakerDeviceId } = state.localMedia;
1810
- const { changedDevices, removedDevices } = getUpdatedDevices({
1810
+ const { changedDevices, addedDevices } = getUpdatedDevices({
1811
1811
  oldDevices,
1812
1812
  newDevices,
1813
- currentVideoId: currentCameraDeviceId,
1814
- currentAudioId: currentMicrophoneDeviceId,
1815
- currentSpeakerId: currentSpeakerDeviceId,
1816
1813
  });
1817
- let autoSwitchAudioId;
1818
- let autoSwitchVideoId;
1819
- if (removedDevices.audioinput) {
1820
- autoSwitchAudioId = true;
1814
+ let autoSwitchAudioId = (_b = changedDevices.audioinput) === null || _b === void 0 ? void 0 : _b.deviceId;
1815
+ let autoSwitchVideoId = (_c = changedDevices.videoinput) === null || _c === void 0 ? void 0 : _c.deviceId;
1816
+ if (autoSwitchAudioId === undefined) {
1817
+ autoSwitchAudioId = (_d = addedDevices.audioinput) === null || _d === void 0 ? void 0 : _d.deviceId;
1821
1818
  }
1822
- if (removedDevices.videoinput) {
1823
- autoSwitchVideoId = true;
1819
+ if (autoSwitchVideoId === undefined) {
1820
+ autoSwitchVideoId = (_e = addedDevices.videoinput) === null || _e === void 0 ? void 0 : _e.deviceId;
1824
1821
  }
1825
- if (!autoSwitchAudioId && changedDevices.audioinput) {
1826
- autoSwitchAudioId = changedDevices.audioinput.deviceId;
1827
- }
1828
- if (!autoSwitchVideoId && changedDevices.videoinput) {
1829
- autoSwitchVideoId = changedDevices.videoinput.deviceId;
1830
- }
1831
- if (autoSwitchAudioId || autoSwitchVideoId) {
1822
+ if (autoSwitchAudioId !== undefined || autoSwitchVideoId !== undefined) {
1832
1823
  dispatch(doSwitchLocalStream({ audioId: autoSwitchAudioId, videoId: autoSwitchVideoId }));
1833
1824
  }
1834
1825
  return { devices: newDevices };
@@ -1846,29 +1837,28 @@ const doSwitchLocalStream = createAppAsyncThunk("localMedia/doSwitchLocalStream"
1846
1837
  return;
1847
1838
  }
1848
1839
  const beforeEffectTracks = selectLocalMediaBeforeEffectTracks(state);
1849
- if (audioId && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.audio)) {
1840
+ if (audioId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.audio)) {
1850
1841
  beforeEffectTracks.audio.stop();
1851
1842
  beforeEffectTracks.audio = undefined;
1852
1843
  }
1853
- if (videoId && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.video)) {
1844
+ if (videoId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.video)) {
1854
1845
  beforeEffectTracks.video.stop();
1855
1846
  beforeEffectTracks.video = undefined;
1856
1847
  }
1857
1848
  try {
1858
- const { replacedTracks, error } = yield getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: audioId || false, videoId: videoId || false, type: "exact" }), { replaceStream });
1859
- if (error) {
1860
- const deviceId = audioId || videoId;
1861
- if (onlySwitchingOne && typeof deviceId === "string") {
1862
- dispatch(deviceBusy({
1863
- deviceId,
1864
- }));
1865
- }
1849
+ const { replacedTracks } = yield getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: audioId === undefined ? false : audioId, videoId: videoId === undefined ? false : videoId, type: "exact" }), { replaceStream });
1850
+ const deviceId = audioId || videoId;
1851
+ if (onlySwitchingOne && deviceId) {
1852
+ dispatch(deviceBusy({
1853
+ deviceId,
1854
+ }));
1866
1855
  }
1867
1856
  return { replacedTracks, beforeEffectTracks };
1868
1857
  }
1869
1858
  catch (error) {
1859
+ console.error(error);
1870
1860
  const deviceId = audioId || videoId;
1871
- if (onlySwitchingOne && typeof deviceId === "string") {
1861
+ if (onlySwitchingOne && deviceId) {
1872
1862
  dispatch(deviceBusy({
1873
1863
  deviceId,
1874
1864
  }));
@@ -2008,17 +1998,13 @@ createReactor([selectLocalMediaShouldStartWithOptions], ({ dispatch }, options)
2008
1998
  dispatch(doStartLocalMedia(options));
2009
1999
  }
2010
2000
  });
2011
- startAppListening({
2012
- predicate: (_action, currentState, previousState) => {
2013
- const oldValue = selectAppIsActive(previousState);
2014
- const newValue = selectAppIsActive(currentState);
2015
- const localMediaOptions = selectLocalMediaOptions(currentState);
2016
- const localMediaStatus = selectLocalMediaStatus(currentState);
2017
- return (oldValue === true && newValue === false) && localMediaStatus !== "inactive" && !!localMediaOptions;
2018
- },
2019
- effect: (_, { dispatch }) => {
2001
+ const selectLocalMediaShouldStop = createSelector(selectAppIsActive, selectLocalMediaStatus, selectLocalMediaOptions, (appIsActive, localMediaStatus, localMediaOptions) => {
2002
+ return !appIsActive && localMediaStatus !== "inactive" && !!localMediaOptions;
2003
+ });
2004
+ createReactor([selectLocalMediaShouldStop], ({ dispatch }, localMediaShouldStop) => {
2005
+ if (localMediaShouldStop) {
2020
2006
  dispatch(doStopLocalMedia());
2021
- },
2007
+ }
2022
2008
  });
2023
2009
  startAppListening({
2024
2010
  predicate: (_action, currentState, previousState) => {
@@ -2059,25 +2045,10 @@ startAppListening({
2059
2045
  });
2060
2046
  startAppListening({
2061
2047
  predicate: (_action, currentState, previousState) => {
2062
- var _a, _b;
2063
- const oldDeviceId = selectCurrentCameraDeviceId(previousState);
2064
- const newDeviceId = selectCurrentCameraDeviceId(currentState);
2048
+ const oldValue = selectCurrentCameraDeviceId(previousState);
2049
+ const newValue = selectCurrentCameraDeviceId(currentState);
2065
2050
  const isReady = selectLocalMediaStatus(previousState) === "started";
2066
- const isSwitchingStream = selectLocalMediaIsSwitchingStream(currentState);
2067
- if (isSwitchingStream) {
2068
- return false;
2069
- }
2070
- if (!newDeviceId) {
2071
- return false;
2072
- }
2073
- const currentTrack = (_b = (_a = selectLocalMediaStream(currentState)) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b[0];
2074
- if (currentTrack && currentTrack.readyState === "live") {
2075
- const currentDeviceId = currentTrack.getSettings().deviceId;
2076
- if (currentDeviceId === newDeviceId) {
2077
- return false;
2078
- }
2079
- }
2080
- return isReady && oldDeviceId !== newDeviceId;
2051
+ return isReady && oldValue !== newValue;
2081
2052
  },
2082
2053
  effect: (_action, { dispatch }) => {
2083
2054
  dispatch(doSetDevice({ audio: false, video: true }));
@@ -2085,25 +2056,10 @@ startAppListening({
2085
2056
  });
2086
2057
  startAppListening({
2087
2058
  predicate: (_action, currentState, previousState) => {
2088
- var _a, _b;
2089
- const oldDeviceId = selectCurrentMicrophoneDeviceId(previousState);
2090
- const newDeviceId = selectCurrentMicrophoneDeviceId(currentState);
2059
+ const oldValue = selectCurrentMicrophoneDeviceId(previousState);
2060
+ const newValue = selectCurrentMicrophoneDeviceId(currentState);
2091
2061
  const isReady = selectLocalMediaStatus(previousState) === "started";
2092
- const isSwitchingStream = selectLocalMediaIsSwitchingStream(currentState);
2093
- if (isSwitchingStream) {
2094
- return false;
2095
- }
2096
- if (!newDeviceId) {
2097
- return false;
2098
- }
2099
- const currentTrack = (_b = (_a = selectLocalMediaStream(currentState)) === null || _a === void 0 ? void 0 : _a.getVideoTracks()) === null || _b === void 0 ? void 0 : _b[0];
2100
- if (currentTrack && currentTrack.readyState === "live") {
2101
- const currentDeviceId = currentTrack.getSettings().deviceId;
2102
- if (currentDeviceId === newDeviceId) {
2103
- return false;
2104
- }
2105
- }
2106
- return isReady && oldDeviceId !== newDeviceId;
2062
+ return isReady && oldValue !== newValue;
2107
2063
  },
2108
2064
  effect: (_action, { dispatch }) => {
2109
2065
  dispatch(doSetDevice({ audio: true, video: false }));
@@ -2922,6 +2878,15 @@ startAppListening({
2922
2878
  },
2923
2879
  });
2924
2880
 
2881
+ function isDeferrable({ client, breakoutCurrentId }) {
2882
+ if (!client)
2883
+ return false;
2884
+ if (!breakoutCurrentId && client.breakoutGroup)
2885
+ return true;
2886
+ if (!client.isAudioEnabled && !client.isVideoEnabled)
2887
+ return true;
2888
+ return false;
2889
+ }
2925
2890
  const createWebRtcEmitter = (dispatch) => {
2926
2891
  return {
2927
2892
  emit: (eventName, data) => {
@@ -3009,12 +2974,22 @@ const doConnectRtc = createAppThunk(() => (dispatch, getState) => {
3009
2974
  const state = getState();
3010
2975
  const socket = selectSignalConnectionRaw(state).socket;
3011
2976
  const dispatcher = selectRtcConnectionRaw(state).rtcManagerDispatcher;
2977
+ const isCameraEnabled = selectIsCameraEnabled(state);
2978
+ const isMicrophoneEnabled = selectIsMicrophoneEnabled(state);
3012
2979
  const isNodeSdk = selectAppIsNodeSdk(state);
3013
2980
  if (dispatcher || !socket) {
3014
2981
  return;
3015
2982
  }
3016
2983
  const webrtcProvider = {
3017
- getMediaConstraints: () => selectLocalMediaConstraintsOptions(state),
2984
+ getMediaConstraints: () => ({
2985
+ audio: isMicrophoneEnabled,
2986
+ video: isCameraEnabled,
2987
+ }),
2988
+ deferrable(clientId) {
2989
+ const client = selectRemoteParticipants(getState()).find((p) => p.id === clientId);
2990
+ const breakoutCurrentId = selectBreakoutCurrentId(getState()) || "";
2991
+ return isDeferrable({ client, breakoutCurrentId });
2992
+ },
3018
2993
  };
3019
2994
  const rtcManagerDispatcher = new RtcManagerDispatcher({
3020
2995
  emitter: createWebRtcEmitter(dispatch),
@@ -4644,10 +4619,6 @@ class LocalMediaClient extends BaseClient {
4644
4619
  }
4645
4620
  startMedia() {
4646
4621
  return __awaiter(this, arguments, void 0, function* (options = { audio: true, video: true }) {
4647
- const localMediaStatus = this.store.getState().localMedia.status;
4648
- if (["started", "starting"].includes(localMediaStatus)) {
4649
- return;
4650
- }
4651
4622
  return yield this.store.dispatch(doStartLocalMedia(options));
4652
4623
  });
4653
4624
  }