@stream-io/video-react-sdk 1.36.1 → 1.37.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/CHANGELOG.md +13 -0
- package/dist/css/embedded.css +6 -0
- package/dist/css/embedded.css.map +1 -1
- package/dist/css/styles.css +6 -0
- package/dist/css/styles.css.map +1 -1
- package/dist/embedded.cjs.js +40 -24
- package/dist/embedded.cjs.js.map +1 -1
- package/dist/embedded.es.js +41 -25
- package/dist/embedded.es.js.map +1 -1
- package/dist/index.cjs.js +41 -25
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +41 -25
- package/dist/index.es.js.map +1 -1
- package/dist/src/core/hooks/useTrackElementVisibility.d.ts +2 -3
- package/dist/src/translations/index.d.ts +2 -0
- package/package.json +5 -5
- package/src/components/CallControls/ToggleAudioButton.tsx +32 -5
- package/src/components/CallControls/ToggleVideoButton.tsx +36 -5
- package/src/core/components/CallLayout/PaginatedGridLayout.tsx +1 -1
- package/src/core/components/CallLayout/SpeakerLayout.tsx +1 -1
- package/src/core/components/ParticipantView/ParticipantView.tsx +0 -1
- package/src/core/hooks/useTrackElementVisibility.ts +4 -14
- package/src/translations/en.json +2 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const useTrackElementVisibility: <T extends HTMLElement>({ trackedElement,
|
|
1
|
+
import { VideoTrackType } from '@stream-io/video-client';
|
|
2
|
+
export declare const useTrackElementVisibility: <T extends HTMLElement>({ trackedElement, sessionId, trackType, }: {
|
|
3
3
|
trackedElement: T | null;
|
|
4
4
|
sessionId: string;
|
|
5
|
-
dynascaleManager?: DynascaleManager;
|
|
6
5
|
trackType: VideoTrackType | "none";
|
|
7
6
|
}) => void;
|
|
@@ -56,8 +56,10 @@ export declare const translations: {
|
|
|
56
56
|
Dismiss: string;
|
|
57
57
|
"Microphone on": string;
|
|
58
58
|
"Microphone off": string;
|
|
59
|
+
"Microphone is paused by your system": string;
|
|
59
60
|
"Camera on": string;
|
|
60
61
|
"Camera off": string;
|
|
62
|
+
"Camera is paused by your system": string;
|
|
61
63
|
"No camera found": string;
|
|
62
64
|
"Video is disabled": string;
|
|
63
65
|
Pinned: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.0",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"module": "./dist/index.es.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@floating-ui/react": "^0.27.6",
|
|
48
|
-
"@stream-io/video-client": "1.
|
|
48
|
+
"@stream-io/video-client": "1.50.0",
|
|
49
49
|
"@stream-io/video-filters-web": "0.7.4",
|
|
50
|
-
"@stream-io/video-react-bindings": "1.
|
|
50
|
+
"@stream-io/video-react-bindings": "1.16.0",
|
|
51
51
|
"chart.js": "^4.4.4",
|
|
52
52
|
"clsx": "^2.0.0",
|
|
53
53
|
"react-chartjs-2": "^5.3.0"
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"@rollup/plugin-json": "^6.1.0",
|
|
61
61
|
"@rollup/plugin-replace": "^6.0.2",
|
|
62
62
|
"@rollup/plugin-typescript": "^12.1.4",
|
|
63
|
-
"@stream-io/audio-filters-web": "^0.
|
|
64
|
-
"@stream-io/video-styling": "^1.
|
|
63
|
+
"@stream-io/audio-filters-web": "^0.8.0",
|
|
64
|
+
"@stream-io/video-styling": "^1.14.0",
|
|
65
65
|
"@types/react": "~19.1.17",
|
|
66
66
|
"@types/react-dom": "~19.1.11",
|
|
67
67
|
"react": "19.1.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OwnCapability } from '@stream-io/video-client';
|
|
1
|
+
import { OwnCapability, SfuModels } from '@stream-io/video-client';
|
|
2
2
|
import {
|
|
3
3
|
Restricted,
|
|
4
4
|
useCallStateHooks,
|
|
@@ -38,7 +38,7 @@ export const ToggleAudioPreviewButton = (
|
|
|
38
38
|
...restCompositeButtonProps
|
|
39
39
|
} = props;
|
|
40
40
|
const { t } = useI18n();
|
|
41
|
-
const { useMicrophoneState } = useCallStateHooks();
|
|
41
|
+
const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();
|
|
42
42
|
const {
|
|
43
43
|
microphone,
|
|
44
44
|
hasBrowserPermission,
|
|
@@ -46,6 +46,10 @@ export const ToggleAudioPreviewButton = (
|
|
|
46
46
|
optionsAwareIsMute,
|
|
47
47
|
isTogglePending,
|
|
48
48
|
} = useMicrophoneState({ optimisticUpdates });
|
|
49
|
+
const localParticipant = useLocalParticipant();
|
|
50
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(
|
|
51
|
+
SfuModels.TrackType.AUDIO,
|
|
52
|
+
);
|
|
49
53
|
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
50
54
|
const handleClick = createCallControlHandler(props, () =>
|
|
51
55
|
microphone.toggle(),
|
|
@@ -56,7 +60,9 @@ export const ToggleAudioPreviewButton = (
|
|
|
56
60
|
title={
|
|
57
61
|
!hasBrowserPermission
|
|
58
62
|
? t('Check your browser audio permissions')
|
|
59
|
-
:
|
|
63
|
+
: isSystemMuted
|
|
64
|
+
? t('Microphone is paused by your system')
|
|
65
|
+
: (caption ?? t('Mic'))
|
|
60
66
|
}
|
|
61
67
|
tooltipDisabled={tooltipDisabled}
|
|
62
68
|
>
|
|
@@ -99,6 +105,13 @@ export const ToggleAudioPreviewButton = (
|
|
|
99
105
|
children="?"
|
|
100
106
|
/>
|
|
101
107
|
)}
|
|
108
|
+
{isSystemMuted && hasBrowserPermission && (
|
|
109
|
+
<span
|
|
110
|
+
className="str-video__system-muted"
|
|
111
|
+
title={t('Microphone is paused by your system')}
|
|
112
|
+
children="!"
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
102
115
|
</CompositeButton>
|
|
103
116
|
</WithTooltip>
|
|
104
117
|
);
|
|
@@ -128,7 +141,7 @@ export const ToggleAudioPublishingButton = (
|
|
|
128
141
|
const { hasPermission, requestPermission, isAwaitingPermission } =
|
|
129
142
|
useRequestPermission(OwnCapability.SEND_AUDIO);
|
|
130
143
|
|
|
131
|
-
const { useMicrophoneState } = useCallStateHooks();
|
|
144
|
+
const { useMicrophoneState, useLocalParticipant } = useCallStateHooks();
|
|
132
145
|
const {
|
|
133
146
|
microphone,
|
|
134
147
|
hasBrowserPermission,
|
|
@@ -136,6 +149,10 @@ export const ToggleAudioPublishingButton = (
|
|
|
136
149
|
isTogglePending,
|
|
137
150
|
optionsAwareIsMute,
|
|
138
151
|
} = useMicrophoneState({ optimisticUpdates });
|
|
152
|
+
const localParticipant = useLocalParticipant();
|
|
153
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(
|
|
154
|
+
SfuModels.TrackType.AUDIO,
|
|
155
|
+
);
|
|
139
156
|
|
|
140
157
|
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
141
158
|
const handleClick = createCallControlHandler(props, async () => {
|
|
@@ -161,7 +178,9 @@ export const ToggleAudioPublishingButton = (
|
|
|
161
178
|
? t('You have no permission to share your audio')
|
|
162
179
|
: !hasBrowserPermission
|
|
163
180
|
? t('Check your browser mic permissions')
|
|
164
|
-
:
|
|
181
|
+
: isSystemMuted
|
|
182
|
+
? t('Microphone is paused by your system')
|
|
183
|
+
: (caption ?? t('Mic'))
|
|
165
184
|
}
|
|
166
185
|
tooltipDisabled={tooltipDisabled}
|
|
167
186
|
>
|
|
@@ -200,6 +219,14 @@ export const ToggleAudioPublishingButton = (
|
|
|
200
219
|
?
|
|
201
220
|
</span>
|
|
202
221
|
)}
|
|
222
|
+
{isSystemMuted && hasBrowserPermission && hasPermission && (
|
|
223
|
+
<span
|
|
224
|
+
className="str-video__system-muted"
|
|
225
|
+
title={t('Microphone is paused by your system')}
|
|
226
|
+
>
|
|
227
|
+
!
|
|
228
|
+
</span>
|
|
229
|
+
)}
|
|
203
230
|
</CompositeButton>
|
|
204
231
|
</WithTooltip>
|
|
205
232
|
</PermissionNotification>
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
UseInputMediaDeviceOptions,
|
|
6
6
|
} from '@stream-io/video-react-bindings';
|
|
7
7
|
import clsx from 'clsx';
|
|
8
|
-
import { OwnCapability } from '@stream-io/video-client';
|
|
8
|
+
import { OwnCapability, SfuModels } from '@stream-io/video-client';
|
|
9
9
|
import { CompositeButton, IconButtonWithMenuProps } from '../Button/';
|
|
10
10
|
import { DeviceSelectorVideo } from '../DeviceSettings';
|
|
11
11
|
import { PermissionNotification } from '../Notification';
|
|
@@ -38,7 +38,7 @@ export const ToggleVideoPreviewButton = (
|
|
|
38
38
|
...restCompositeButtonProps
|
|
39
39
|
} = props;
|
|
40
40
|
const { t } = useI18n();
|
|
41
|
-
const { useCameraState } = useCallStateHooks();
|
|
41
|
+
const { useCameraState, useLocalParticipant } = useCallStateHooks();
|
|
42
42
|
const {
|
|
43
43
|
camera,
|
|
44
44
|
hasBrowserPermission,
|
|
@@ -46,6 +46,10 @@ export const ToggleVideoPreviewButton = (
|
|
|
46
46
|
isTogglePending,
|
|
47
47
|
optionsAwareIsMute,
|
|
48
48
|
} = useCameraState({ optimisticUpdates });
|
|
49
|
+
const localParticipant = useLocalParticipant();
|
|
50
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(
|
|
51
|
+
SfuModels.TrackType.VIDEO,
|
|
52
|
+
);
|
|
49
53
|
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
50
54
|
const handleClick = createCallControlHandler(props, () => camera.toggle());
|
|
51
55
|
|
|
@@ -54,7 +58,9 @@ export const ToggleVideoPreviewButton = (
|
|
|
54
58
|
title={
|
|
55
59
|
!hasBrowserPermission
|
|
56
60
|
? t('Check your browser video permissions')
|
|
57
|
-
:
|
|
61
|
+
: isSystemMuted
|
|
62
|
+
? t('Camera is paused by your system')
|
|
63
|
+
: (caption ?? t('Video'))
|
|
58
64
|
}
|
|
59
65
|
tooltipDisabled={tooltipDisabled}
|
|
60
66
|
>
|
|
@@ -97,6 +103,13 @@ export const ToggleVideoPreviewButton = (
|
|
|
97
103
|
children="?"
|
|
98
104
|
/>
|
|
99
105
|
)}
|
|
106
|
+
{isSystemMuted && hasBrowserPermission && (
|
|
107
|
+
<span
|
|
108
|
+
className="str-video__system-muted"
|
|
109
|
+
title={t('Camera is paused by your system')}
|
|
110
|
+
children="!"
|
|
111
|
+
/>
|
|
112
|
+
)}
|
|
100
113
|
</CompositeButton>
|
|
101
114
|
</WithTooltip>
|
|
102
115
|
);
|
|
@@ -126,7 +139,8 @@ export const ToggleVideoPublishingButton = (
|
|
|
126
139
|
const { hasPermission, requestPermission, isAwaitingPermission } =
|
|
127
140
|
useRequestPermission(OwnCapability.SEND_VIDEO);
|
|
128
141
|
|
|
129
|
-
const { useCameraState, useCallSettings } =
|
|
142
|
+
const { useCameraState, useCallSettings, useLocalParticipant } =
|
|
143
|
+
useCallStateHooks();
|
|
130
144
|
const {
|
|
131
145
|
camera,
|
|
132
146
|
optionsAwareIsMute,
|
|
@@ -134,6 +148,10 @@ export const ToggleVideoPublishingButton = (
|
|
|
134
148
|
isPromptingPermission,
|
|
135
149
|
isTogglePending,
|
|
136
150
|
} = useCameraState({ optimisticUpdates });
|
|
151
|
+
const localParticipant = useLocalParticipant();
|
|
152
|
+
const isSystemMuted = !!localParticipant?.interruptedTracks?.includes(
|
|
153
|
+
SfuModels.TrackType.VIDEO,
|
|
154
|
+
);
|
|
137
155
|
const callSettings = useCallSettings();
|
|
138
156
|
const isPublishingVideoAllowed = callSettings?.video.enabled;
|
|
139
157
|
const [tooltipDisabled, setTooltipDisabled] = useState(false);
|
|
@@ -164,7 +182,9 @@ export const ToggleVideoPublishingButton = (
|
|
|
164
182
|
? t('Check your browser video permissions')
|
|
165
183
|
: !isPublishingVideoAllowed
|
|
166
184
|
? t('Video publishing is disabled by the system')
|
|
167
|
-
:
|
|
185
|
+
: isSystemMuted
|
|
186
|
+
? t('Camera is paused by your system')
|
|
187
|
+
: caption || t('Video')
|
|
168
188
|
}
|
|
169
189
|
tooltipDisabled={tooltipDisabled}
|
|
170
190
|
>
|
|
@@ -205,6 +225,17 @@ export const ToggleVideoPublishingButton = (
|
|
|
205
225
|
?
|
|
206
226
|
</span>
|
|
207
227
|
)}
|
|
228
|
+
{isSystemMuted &&
|
|
229
|
+
hasBrowserPermission &&
|
|
230
|
+
hasPermission &&
|
|
231
|
+
isPublishingVideoAllowed && (
|
|
232
|
+
<span
|
|
233
|
+
className="str-video__system-muted"
|
|
234
|
+
title={t('Camera is paused by your system')}
|
|
235
|
+
>
|
|
236
|
+
!
|
|
237
|
+
</span>
|
|
238
|
+
)}
|
|
208
239
|
</CompositeButton>
|
|
209
240
|
</WithTooltip>
|
|
210
241
|
</PermissionNotification>
|
|
@@ -152,7 +152,7 @@ export const PaginatedGridLayout = (props: PaginatedGridLayoutProps) => {
|
|
|
152
152
|
|
|
153
153
|
const cleanup = call.setViewport(paginatedGridLayoutWrapperElement);
|
|
154
154
|
|
|
155
|
-
return () => cleanup();
|
|
155
|
+
return () => cleanup?.();
|
|
156
156
|
}, [paginatedGridLayoutWrapperElement, call]);
|
|
157
157
|
|
|
158
158
|
// only used to render video elements
|
|
@@ -149,7 +149,7 @@ export const SpeakerLayout = ({
|
|
|
149
149
|
|
|
150
150
|
const cleanup = call.setViewport(participantsBarWrapperElement);
|
|
151
151
|
|
|
152
|
-
return () => cleanup();
|
|
152
|
+
return () => cleanup?.();
|
|
153
153
|
}, [participantsBarWrapperElement, call]);
|
|
154
154
|
|
|
155
155
|
const isOneOnOneCall = allParticipants.length === 2;
|
|
@@ -102,7 +102,6 @@ export const ParticipantView = forwardRef<HTMLDivElement, ParticipantViewProps>(
|
|
|
102
102
|
const [contextVideoPlaceholderElement, setContextVideoPlaceholderElement] =
|
|
103
103
|
useState<HTMLDivElement | null>(null);
|
|
104
104
|
|
|
105
|
-
// TODO: allow to pass custom ViewportTracker instance from props
|
|
106
105
|
useTrackElementVisibility({
|
|
107
106
|
sessionId,
|
|
108
107
|
trackedElement,
|
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { VideoTrackType } from '@stream-io/video-client';
|
|
3
3
|
import { useCall } from '@stream-io/video-react-bindings';
|
|
4
4
|
|
|
5
5
|
export const useTrackElementVisibility = <T extends HTMLElement>({
|
|
6
6
|
trackedElement,
|
|
7
|
-
dynascaleManager: propsDynascaleManager,
|
|
8
7
|
sessionId,
|
|
9
8
|
trackType,
|
|
10
9
|
}: {
|
|
11
10
|
trackedElement: T | null;
|
|
12
11
|
sessionId: string;
|
|
13
|
-
dynascaleManager?: DynascaleManager;
|
|
14
12
|
trackType: VideoTrackType | 'none';
|
|
15
13
|
}) => {
|
|
16
14
|
const call = useCall();
|
|
17
|
-
const manager = propsDynascaleManager ?? call?.dynascaleManager;
|
|
18
15
|
useEffect(() => {
|
|
19
|
-
if (!trackedElement || !
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
sessionId,
|
|
23
|
-
trackType,
|
|
24
|
-
);
|
|
25
|
-
return () => {
|
|
26
|
-
unobserve();
|
|
27
|
-
};
|
|
28
|
-
}, [trackedElement, manager, call, sessionId, trackType]);
|
|
16
|
+
if (!trackedElement || !call || trackType === 'none') return;
|
|
17
|
+
return call.trackElementVisibility(trackedElement, sessionId, trackType);
|
|
18
|
+
}, [trackedElement, call, sessionId, trackType]);
|
|
29
19
|
};
|
package/src/translations/en.json
CHANGED
|
@@ -60,8 +60,10 @@
|
|
|
60
60
|
|
|
61
61
|
"Microphone on": "Microphone on",
|
|
62
62
|
"Microphone off": "Microphone off",
|
|
63
|
+
"Microphone is paused by your system": "Microphone is paused by your system",
|
|
63
64
|
"Camera on": "Camera on",
|
|
64
65
|
"Camera off": "Camera off",
|
|
66
|
+
"Camera is paused by your system": "Camera is paused by your system",
|
|
65
67
|
"No camera found": "No camera found",
|
|
66
68
|
"Video is disabled": "Video is disabled",
|
|
67
69
|
"Pinned": "Pinned",
|