@stream-io/video-react-sdk 1.12.2 → 1.12.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/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.12.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.12.3...@stream-io/video-react-sdk-1.12.4) (2025-02-28)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `@stream-io/video-client` updated to version `1.18.1`
10
+ * `@stream-io/video-react-bindings` updated to version `1.5.3`
11
+ ## [1.12.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.12.2...@stream-io/video-react-sdk-1.12.3) (2025-02-27)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * add explicit default device option to device selectors ([#1701](https://github.com/GetStream/stream-video-js/issues/1701)) ([1b8e11b](https://github.com/GetStream/stream-video-js/commit/1b8e11b65b5323d440fcb9b03a464a580bca767e))
17
+
5
18
  ## [1.12.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.12.1...@stream-io/video-react-sdk-1.12.2) (2025-02-26)
6
19
 
7
20
  ### Dependency Updates
package/dist/index.cjs.js CHANGED
@@ -303,6 +303,41 @@ const useRequestPermission = (permission) => {
303
303
  };
304
304
  };
305
305
 
306
+ /**
307
+ * Utility hook that helps render a list of devices or implement a device selector.
308
+ * Compared to someting like `useCameraState().devices`, it has some handy features:
309
+ * 1. Adds the "Default" device to the list if applicable (either the user did not
310
+ * select a device, or a previously selected device is no longer available).
311
+ * 2. Maps the device list to a format more suitable for rendering.
312
+ */
313
+ function useDeviceList(devices, selectedDeviceId) {
314
+ const { t } = videoReactBindings.useI18n();
315
+ return react.useMemo(() => {
316
+ let selectedDeviceInfo = null;
317
+ let selectedIndex = null;
318
+ const deviceList = devices.map((d, i) => {
319
+ const isSelected = d.deviceId === selectedDeviceId;
320
+ const device = { deviceId: d.deviceId, label: d.label, isSelected };
321
+ if (isSelected) {
322
+ selectedDeviceInfo = device;
323
+ selectedIndex = i;
324
+ }
325
+ return device;
326
+ });
327
+ if (selectedDeviceInfo === null || selectedIndex === null) {
328
+ const defaultDevice = {
329
+ deviceId: 'default',
330
+ label: t('Default'),
331
+ isSelected: true,
332
+ };
333
+ selectedDeviceInfo = defaultDevice;
334
+ selectedIndex = 0;
335
+ deviceList.unshift(defaultDevice);
336
+ }
337
+ return { deviceList, selectedDeviceInfo, selectedIndex };
338
+ }, [devices, selectedDeviceId, t]);
339
+ }
340
+
306
341
  exports.MenuVisualType = void 0;
307
342
  (function (MenuVisualType) {
308
343
  MenuVisualType["PORTAL"] = "portal";
@@ -1225,22 +1260,27 @@ const DeviceSelectorOption = ({ disabled, id, label, onChange, name, selected, d
1225
1260
  const DeviceSelectorList = (props) => {
1226
1261
  const { devices = [], selectedDeviceId, title, type, onChange } = props;
1227
1262
  const { close } = useMenuContext();
1228
- const { t } = videoReactBindings.useI18n();
1229
- return (jsxRuntime.jsxs("div", { className: "str-video__device-settings__device-kind", children: [title && (jsxRuntime.jsx("div", { className: "str-video__device-settings__device-selector-title", children: title })), devices.length === 0 ? (jsxRuntime.jsx(DeviceSelectorOption, { id: `${type}--default`, label: t('Default'), name: type, defaultChecked: true, value: "default" })) : (devices.map((device) => {
1263
+ const { deviceList } = useDeviceList(devices, selectedDeviceId);
1264
+ return (jsxRuntime.jsxs("div", { className: "str-video__device-settings__device-kind", children: [title && (jsxRuntime.jsx("div", { className: "str-video__device-settings__device-selector-title", children: title })), deviceList.map((device) => {
1230
1265
  return (jsxRuntime.jsx(DeviceSelectorOption, { id: `${type}--${device.deviceId}`, value: device.deviceId, label: device.label, onChange: (e) => {
1231
- onChange?.(e.target.value);
1266
+ const deviceId = e.target.value;
1267
+ if (deviceId !== 'default') {
1268
+ onChange?.(deviceId);
1269
+ }
1232
1270
  close?.();
1233
- }, name: type, selected: device.deviceId === selectedDeviceId || devices.length === 1 }, device.deviceId));
1234
- }))] }));
1271
+ }, name: type, selected: device.isSelected }, device.deviceId));
1272
+ })] }));
1235
1273
  };
1236
1274
  const DeviceSelectorDropdown = (props) => {
1237
1275
  const { devices = [], selectedDeviceId, title, onChange, icon } = props;
1238
- const { t } = videoReactBindings.useI18n();
1239
- const selectedIndex = devices.findIndex((d) => d.deviceId === selectedDeviceId);
1276
+ const { deviceList, selectedDeviceInfo, selectedIndex } = useDeviceList(devices, selectedDeviceId);
1240
1277
  const handleSelect = react.useCallback((index) => {
1241
- onChange?.(devices[index].deviceId);
1242
- }, [devices, onChange]);
1243
- return (jsxRuntime.jsxs("div", { className: "str-video__device-settings__device-kind", children: [jsxRuntime.jsx("div", { className: "str-video__device-settings__device-selector-title", children: title }), jsxRuntime.jsx(DropDownSelect, { icon: icon, defaultSelectedIndex: selectedIndex, defaultSelectedLabel: devices[selectedIndex]?.label ?? t('Default'), handleSelect: handleSelect, children: devices.length === 0 ? (jsxRuntime.jsx(DropDownSelectOption, { icon: icon, label: t('Default'), selected: true })) : (devices.map((device) => (jsxRuntime.jsx(DropDownSelectOption, { icon: icon, label: device.label, selected: device.deviceId === selectedDeviceId || devices.length === 1 }, device.deviceId)))) })] }));
1278
+ const deviceId = deviceList[index].deviceId;
1279
+ if (deviceId !== 'default') {
1280
+ onChange?.(deviceId);
1281
+ }
1282
+ }, [deviceList, onChange]);
1283
+ return (jsxRuntime.jsxs("div", { className: "str-video__device-settings__device-kind", children: [jsxRuntime.jsx("div", { className: "str-video__device-settings__device-selector-title", children: title }), jsxRuntime.jsx(DropDownSelect, { icon: icon, defaultSelectedIndex: selectedIndex, defaultSelectedLabel: selectedDeviceInfo.label, handleSelect: handleSelect, children: deviceList.map((device) => (jsxRuntime.jsx(DropDownSelectOption, { icon: icon, label: device.label, selected: device.isSelected }, device.deviceId))) })] }));
1244
1284
  };
1245
1285
  const DeviceSelector = (props) => {
1246
1286
  const { visualType = 'list', icon, placeholder, ...rest } = props;
@@ -2639,7 +2679,7 @@ const LivestreamPlayer = (props) => {
2639
2679
  return (jsxRuntime.jsx(StreamCall, { call: call, children: jsxRuntime.jsx(LivestreamLayout, { ...layoutProps }) }));
2640
2680
  };
2641
2681
 
2642
- const [major, minor, patch] = ("1.12.2").split('.');
2682
+ const [major, minor, patch] = ("1.12.4").split('.');
2643
2683
  videoClient.setSdkInfo({
2644
2684
  type: videoClient.SfuModels.SdkType.REACT,
2645
2685
  major,