@stream-io/video-react-sdk 1.25.1 → 1.26.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.
@@ -0,0 +1 @@
1
+ export declare const AudioVolumeIndicator: () => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,6 @@
1
+ import { PropsWithChildren } from 'react';
1
2
  export type DeviceSelectorType = 'audioinput' | 'audiooutput' | 'videoinput';
2
- export declare const DeviceSelector: (props: {
3
+ export declare const DeviceSelector: (props: PropsWithChildren<{
3
4
  devices: MediaDeviceInfo[];
4
5
  icon: string;
5
6
  type: DeviceSelectorType;
@@ -7,4 +8,4 @@ export declare const DeviceSelector: (props: {
7
8
  title?: string;
8
9
  onChange?: (deviceId: string) => void;
9
10
  visualType?: "list" | "dropdown";
10
- }) => import("react/jsx-runtime").JSX.Element;
11
+ }>) => import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,9 @@
1
1
  export type DeviceSelectorAudioInputProps = {
2
2
  title?: string;
3
3
  visualType?: 'list' | 'dropdown';
4
+ volumeIndicatorVisible?: boolean;
4
5
  };
5
- export declare const DeviceSelectorAudioInput: ({ title, visualType, }: DeviceSelectorAudioInputProps) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const DeviceSelectorAudioInput: ({ title, visualType, volumeIndicatorVisible, }: DeviceSelectorAudioInputProps) => import("react/jsx-runtime").JSX.Element;
6
7
  export type DeviceSelectorAudioOutputProps = {
7
8
  title?: string;
8
9
  visualType?: 'list' | 'dropdown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-sdk",
3
- "version": "1.25.1",
3
+ "version": "1.26.0",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "module": "./dist/index.es.js",
6
6
  "types": "./dist/index.d.ts",
@@ -30,9 +30,9 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "@floating-ui/react": "^0.27.6",
33
- "@stream-io/video-client": "1.36.0",
33
+ "@stream-io/video-client": "1.36.1",
34
34
  "@stream-io/video-filters-web": "0.4.0",
35
- "@stream-io/video-react-bindings": "1.10.4",
35
+ "@stream-io/video-react-bindings": "1.11.0",
36
36
  "chart.js": "^4.4.4",
37
37
  "clsx": "^2.0.0",
38
38
  "react-chartjs-2": "^5.3.0"
@@ -46,7 +46,7 @@
46
46
  "@rollup/plugin-replace": "^6.0.2",
47
47
  "@rollup/plugin-typescript": "^12.1.4",
48
48
  "@stream-io/audio-filters-web": "^0.6.0",
49
- "@stream-io/video-styling": "^1.6.1",
49
+ "@stream-io/video-styling": "^1.7.0",
50
50
  "@types/react": "~19.1.17",
51
51
  "@types/react-dom": "~19.1.11",
52
52
  "react": "19.1.0",
@@ -0,0 +1,34 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { createSoundDetector } from '@stream-io/video-client';
3
+ import { useCallStateHooks } from '@stream-io/video-react-bindings';
4
+ import { Icon } from '../Icon';
5
+
6
+ export const AudioVolumeIndicator = () => {
7
+ const { useMicrophoneState } = useCallStateHooks();
8
+ const { isEnabled, mediaStream } = useMicrophoneState();
9
+ const [audioLevel, setAudioLevel] = useState(0);
10
+
11
+ useEffect(() => {
12
+ if (!isEnabled || !mediaStream) return;
13
+ const disposeSoundDetector = createSoundDetector(
14
+ mediaStream,
15
+ ({ audioLevel: al }) => setAudioLevel(al),
16
+ { detectionFrequencyInMs: 80, destroyStreamOnStop: false },
17
+ );
18
+ return () => {
19
+ disposeSoundDetector().catch(console.error);
20
+ };
21
+ }, [isEnabled, mediaStream]);
22
+
23
+ return (
24
+ <div className="str-video__audio-volume-indicator">
25
+ <Icon icon={isEnabled ? 'mic' : 'mic-off'} />
26
+ <div className="str-video__audio-volume-indicator__bar">
27
+ <div
28
+ className="str-video__audio-volume-indicator__bar-value"
29
+ style={{ transform: `scaleX(${audioLevel / 100})` }}
30
+ />
31
+ </div>
32
+ </div>
33
+ );
34
+ };
@@ -1,5 +1,5 @@
1
1
  import clsx from 'clsx';
2
- import { ChangeEventHandler, useCallback } from 'react';
2
+ import { ChangeEventHandler, PropsWithChildren, useCallback } from 'react';
3
3
 
4
4
  import { useDeviceList } from '../../hooks';
5
5
  import { DropDownSelect, DropDownSelectOption } from '../DropdownSelect';
@@ -51,14 +51,23 @@ const DeviceSelectorOption = ({
51
51
 
52
52
  export type DeviceSelectorType = 'audioinput' | 'audiooutput' | 'videoinput';
53
53
 
54
- const DeviceSelectorList = (props: {
55
- devices: MediaDeviceInfo[];
56
- type: DeviceSelectorType;
57
- selectedDeviceId?: string;
58
- title?: string;
59
- onChange?: (deviceId: string) => void;
60
- }) => {
61
- const { devices = [], selectedDeviceId, title, type, onChange } = props;
54
+ const DeviceSelectorList = (
55
+ props: PropsWithChildren<{
56
+ devices: MediaDeviceInfo[];
57
+ type: DeviceSelectorType;
58
+ selectedDeviceId?: string;
59
+ title?: string;
60
+ onChange?: (deviceId: string) => void;
61
+ }>,
62
+ ) => {
63
+ const {
64
+ devices = [],
65
+ selectedDeviceId,
66
+ title,
67
+ type,
68
+ onChange,
69
+ children,
70
+ } = props;
62
71
  const { close } = useMenuContext();
63
72
  const { deviceList } = useDeviceList(devices, selectedDeviceId);
64
73
 
@@ -88,6 +97,7 @@ const DeviceSelectorList = (props: {
88
97
  />
89
98
  );
90
99
  })}
100
+ {children}
91
101
  </div>
92
102
  );
93
103
  };
@@ -139,15 +149,17 @@ const DeviceSelectorDropdown = (props: {
139
149
  );
140
150
  };
141
151
 
142
- export const DeviceSelector = (props: {
143
- devices: MediaDeviceInfo[];
144
- icon: string;
145
- type: DeviceSelectorType;
146
- selectedDeviceId?: string;
147
- title?: string;
148
- onChange?: (deviceId: string) => void;
149
- visualType?: 'list' | 'dropdown';
150
- }) => {
152
+ export const DeviceSelector = (
153
+ props: PropsWithChildren<{
154
+ devices: MediaDeviceInfo[];
155
+ icon: string;
156
+ type: DeviceSelectorType;
157
+ selectedDeviceId?: string;
158
+ title?: string;
159
+ onChange?: (deviceId: string) => void;
160
+ visualType?: 'list' | 'dropdown';
161
+ }>,
162
+ ) => {
151
163
  const { visualType = 'list', icon, ...rest } = props;
152
164
 
153
165
  if (visualType === 'list') {
@@ -1,14 +1,17 @@
1
1
  import { useCallStateHooks } from '@stream-io/video-react-bindings';
2
2
  import { DeviceSelector } from './DeviceSelector';
3
+ import { AudioVolumeIndicator } from './AudioVolumeIndicator';
3
4
 
4
5
  export type DeviceSelectorAudioInputProps = {
5
6
  title?: string;
6
7
  visualType?: 'list' | 'dropdown';
8
+ volumeIndicatorVisible?: boolean;
7
9
  };
8
10
 
9
11
  export const DeviceSelectorAudioInput = ({
10
12
  title,
11
13
  visualType,
14
+ volumeIndicatorVisible = true,
12
15
  }: DeviceSelectorAudioInputProps) => {
13
16
  const { useMicrophoneState } = useCallStateHooks();
14
17
  const { microphone, selectedDevice, devices } = useMicrophoneState();
@@ -24,7 +27,14 @@ export const DeviceSelectorAudioInput = ({
24
27
  title={title}
25
28
  visualType={visualType}
26
29
  icon="mic"
27
- />
30
+ >
31
+ {volumeIndicatorVisible && (
32
+ <>
33
+ <hr className="str-video__device-settings__separator" />
34
+ <AudioVolumeIndicator />
35
+ </>
36
+ )}
37
+ </DeviceSelector>
28
38
  );
29
39
  };
30
40