@stream-io/video-react-sdk 0.0.33 → 0.0.35
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 +19 -0
- package/dist/src/core/components/CallLayout/SpeakerLayout.js +1 -1
- package/dist/src/core/components/ParticipantView/DefaultParticipantViewUI.js +2 -2
- package/dist/src/core/components/ParticipantView/ParticipantView.d.ts +7 -7
- package/dist/src/core/components/ParticipantView/ParticipantView.js +4 -4
- package/dist/src/core/components/Video/Video.d.ts +1 -1
- package/dist/src/core/components/Video/Video.js +11 -5
- package/dist/src/core/components/Video/Video.js.map +1 -1
- package/package.json +4 -4
- package/src/core/components/CallLayout/SpeakerLayout.tsx +1 -1
- package/src/core/components/ParticipantView/DefaultParticipantViewUI.tsx +2 -2
- package/src/core/components/ParticipantView/ParticipantView.tsx +8 -8
- package/src/core/components/Video/Video.tsx +16 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [0.0.35](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-0.0.34...@stream-io/video-react-sdk-0.0.35) (2023-06-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* Rename videoKind prop to videoMode ([#661](https://github.com/GetStream/stream-video-js/issues/661)) ([781e908](https://github.com/GetStream/stream-video-js/commit/781e9081fd43f2a433f9c4c7b32a549d77fb26c1))
|
|
11
|
+
|
|
12
|
+
### [0.0.34](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-0.0.33...@stream-io/video-react-sdk-0.0.34) (2023-06-16)
|
|
13
|
+
|
|
14
|
+
### Dependency Updates
|
|
15
|
+
|
|
16
|
+
* `@stream-io/i18n` updated to version `0.0.5`
|
|
17
|
+
* `@stream-io/video-client` updated to version `0.0.1`
|
|
18
|
+
* `@stream-io/video-react-bindings` updated to version `0.0.17`
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
* **react-sdk:** Runtime layout switching guide ([#642](https://github.com/GetStream/stream-video-js/issues/642)) ([1557168](https://github.com/GetStream/stream-video-js/commit/1557168da69660b71a0a420a94a0c354466681a7))
|
|
23
|
+
|
|
5
24
|
### [0.0.33](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-0.0.32...@stream-io/video-react-sdk-0.0.33) (2023-06-16)
|
|
6
25
|
|
|
7
26
|
### Dependency Updates
|
|
@@ -39,7 +39,7 @@ export const SpeakerLayout = ({ ParticipantViewUIBar = DefaultParticipantViewUIB
|
|
|
39
39
|
return null;
|
|
40
40
|
const isSpeakerScreenSharing = hasScreenShare(participantInSpotlight);
|
|
41
41
|
return (_jsx("div", Object.assign({ className: "str-video__speaker-layout__wrapper" }, { children: _jsxs("div", Object.assign({ className: clsx('str-video__speaker-layout', participantsBarPosition &&
|
|
42
|
-
`str-video__speaker-layout--variant-${participantsBarPosition}`) }, { children: [_jsx("div", Object.assign({ className: "str-video__speaker-layout__spotlight" }, { children: participantInSpotlight && (_jsx(ParticipantView, { participant: participantInSpotlight, muteAudio: isSpeakerScreenSharing,
|
|
42
|
+
`str-video__speaker-layout--variant-${participantsBarPosition}`) }, { children: [_jsx("div", Object.assign({ className: "str-video__speaker-layout__spotlight" }, { children: participantInSpotlight && (_jsx(ParticipantView, { participant: participantInSpotlight, muteAudio: isSpeakerScreenSharing, videoMode: isSpeakerScreenSharing ? 'screen' : 'video', ParticipantViewUI: ParticipantViewUISpotlight, VideoPlaceholder: VideoPlaceholder })) })), otherParticipants.length > 0 && participantsBarPosition && (_jsxs("div", Object.assign({ className: "str-video__speaker-layout__participants-bar-buttons-wrapper" }, { children: [_jsx("div", Object.assign({ className: "str-video__speaker-layout__participants-bar-wrapper", ref: setScrollWrapper }, { children: _jsxs("div", Object.assign({ className: "str-video__speaker-layout__participants-bar" }, { children: [isSpeakerScreenSharing && (_jsx("div", Object.assign({ className: "str-video__speaker-layout__participant-tile" }, { children: _jsx(ParticipantView, { participant: participantInSpotlight, ParticipantViewUI: ParticipantViewUIBar, VideoPlaceholder: VideoPlaceholder }) }), participantInSpotlight.sessionId)), otherParticipants.map((participant) => (_jsx("div", Object.assign({ className: "str-video__speaker-layout__participant-tile" }, { children: _jsx(ParticipantView, { participant: participant, ParticipantViewUI: ParticipantViewUIBar, VideoPlaceholder: VideoPlaceholder }) }), participant.sessionId)))] })) })), (participantsBarPosition === 'left' ||
|
|
43
43
|
participantsBarPosition === 'right') && (_jsx(VerticalScrollButtons, { scrollWrapper: scrollWrapper })), (participantsBarPosition === 'top' ||
|
|
44
44
|
participantsBarPosition === 'bottom') && (_jsx(HorizontalScrollButtons, { scrollWrapper: scrollWrapper }))] })))] })) })));
|
|
45
45
|
};
|
|
@@ -21,12 +21,12 @@ export const DefaultScreenShareOverlay = () => {
|
|
|
21
21
|
};
|
|
22
22
|
export const DefaultParticipantViewUI = ({ indicatorsVisible = true, menuPlacement = 'bottom-end', showMenuButton = true, }) => {
|
|
23
23
|
const call = useCall();
|
|
24
|
-
const { participant, participantViewElement,
|
|
24
|
+
const { participant, participantViewElement, videoMode, videoElement } = useParticipantViewContext();
|
|
25
25
|
const { reaction, sessionId, publishedTracks } = participant;
|
|
26
26
|
const hasScreenShare = publishedTracks.includes(SfuModels.TrackType.SCREEN_SHARE);
|
|
27
27
|
if (participant.isLocalParticipant &&
|
|
28
28
|
hasScreenShare &&
|
|
29
|
-
|
|
29
|
+
videoMode === 'screen')
|
|
30
30
|
return (_jsxs(_Fragment, { children: [_jsx(DefaultScreenShareOverlay, {}), _jsx(ParticipantDetails, { indicatorsVisible: indicatorsVisible })] }));
|
|
31
31
|
return (_jsxs(_Fragment, { children: [showMenuButton && (_jsx(MenuToggle, Object.assign({ strategy: "fixed", placement: menuPlacement, ToggleButton: ToggleButton }, { children: _jsx(ParticipantActionsContextMenu, { participantViewElement: participantViewElement, participant: participant, videoElement: videoElement }) }))), reaction && (_jsx(Reaction, { reaction: reaction, sessionId: sessionId, call: call })), _jsx(ParticipantDetails, { indicatorsVisible: indicatorsVisible })] }));
|
|
32
32
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ComponentType, ReactElement } from 'react';
|
|
2
2
|
import { StreamVideoLocalParticipant, StreamVideoParticipant } from '@stream-io/video-client';
|
|
3
3
|
import { VideoProps } from '../Video';
|
|
4
|
-
export type ParticipantViewContextValue = Required<Pick<ParticipantViewProps, 'participant' | '
|
|
4
|
+
export type ParticipantViewContextValue = Required<Pick<ParticipantViewProps, 'participant' | 'videoMode'>> & {
|
|
5
5
|
participantViewElement: HTMLDivElement | null;
|
|
6
6
|
videoElement: HTMLVideoElement | null;
|
|
7
7
|
videoPlaceholderElement: HTMLDivElement | null;
|
|
@@ -19,11 +19,11 @@ export type ParticipantViewProps = {
|
|
|
19
19
|
*/
|
|
20
20
|
ParticipantViewUI?: ComponentType | ReactElement | null;
|
|
21
21
|
/**
|
|
22
|
-
* The kind of video stream to play for the given participant.
|
|
22
|
+
* The kind of video stream to play for the given participant. The default value is `video`. You can use `none` if you're building an audio-only call.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
videoMode?: 'video' | 'screen' | 'none';
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* This prop is only useful for advanced use-cases (for example building your own paginated layout). When set to `true` it will mute the give participant's audio stream on the client side. The local participant is always muted.
|
|
27
27
|
*/
|
|
28
28
|
muteAudio?: boolean;
|
|
29
29
|
/**
|
|
@@ -50,11 +50,11 @@ export declare const ParticipantView: import("react").ForwardRefExoticComponent<
|
|
|
50
50
|
*/
|
|
51
51
|
ParticipantViewUI?: ReactElement<any, string | import("react").JSXElementConstructor<any>> | ComponentType<{}> | null | undefined;
|
|
52
52
|
/**
|
|
53
|
-
* The kind of video stream to play for the given participant.
|
|
53
|
+
* The kind of video stream to play for the given participant. The default value is `video`. You can use `none` if you're building an audio-only call.
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
videoMode?: "video" | "none" | "screen" | undefined;
|
|
56
56
|
/**
|
|
57
|
-
*
|
|
57
|
+
* This prop is only useful for advanced use-cases (for example building your own paginated layout). When set to `true` it will mute the give participant's audio stream on the client side. The local participant is always muted.
|
|
58
58
|
*/
|
|
59
59
|
muteAudio?: boolean | undefined;
|
|
60
60
|
/**
|
|
@@ -11,7 +11,7 @@ import { isComponentType, applyElementToRef } from '../../../utilities';
|
|
|
11
11
|
import { useLocalParticipant } from '@stream-io/video-react-bindings';
|
|
12
12
|
const ParticipantViewContext = createContext(undefined);
|
|
13
13
|
export const useParticipantViewContext = () => useContext(ParticipantViewContext);
|
|
14
|
-
export const ParticipantView = forwardRef(({ participant,
|
|
14
|
+
export const ParticipantView = forwardRef(({ participant, videoMode = 'video', muteAudio, refs: { setVideoElement, setVideoPlaceholderElement } = {}, className, VideoPlaceholder, ParticipantViewUI = DefaultParticipantViewUI, }, ref) => {
|
|
15
15
|
const { audioStream, isLocalParticipant, isSpeaking, publishedTracks, sessionId, } = participant;
|
|
16
16
|
const localParticipant = useLocalParticipant();
|
|
17
17
|
const hasAudio = publishedTracks.includes(SfuModels.TrackType.AUDIO);
|
|
@@ -29,13 +29,13 @@ export const ParticipantView = forwardRef(({ participant, videoKind = 'video', m
|
|
|
29
29
|
participantViewElement: trackedElement,
|
|
30
30
|
videoElement: contextVideoElement,
|
|
31
31
|
videoPlaceholderElement: contextVideoPlaceholderElement,
|
|
32
|
-
|
|
32
|
+
videoMode,
|
|
33
33
|
}), [
|
|
34
34
|
contextVideoElement,
|
|
35
35
|
contextVideoPlaceholderElement,
|
|
36
36
|
participant,
|
|
37
37
|
trackedElement,
|
|
38
|
-
|
|
38
|
+
videoMode,
|
|
39
39
|
]);
|
|
40
40
|
const videoRefs = useMemo(() => ({
|
|
41
41
|
setVideoElement: (element) => {
|
|
@@ -54,6 +54,6 @@ export const ParticipantView = forwardRef(({ participant, videoKind = 'video', m
|
|
|
54
54
|
// mute the local participant, as we don't want to hear ourselves
|
|
55
55
|
, {
|
|
56
56
|
// mute the local participant, as we don't want to hear ourselves
|
|
57
|
-
muted: isLocalParticipant || muteAudio, sinkId: localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.audioOutputDeviceId, audioStream: audioStream }), _jsx(Video, { VideoPlaceholder: VideoPlaceholder, participant: participant, kind:
|
|
57
|
+
muted: isLocalParticipant || muteAudio, sinkId: localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.audioOutputDeviceId, audioStream: audioStream }), _jsx(Video, { VideoPlaceholder: VideoPlaceholder, participant: participant, kind: videoMode, refs: videoRefs, autoPlay: true }), isComponentType(ParticipantViewUI) ? (_jsx(ParticipantViewUI, {})) : (ParticipantViewUI)] })) })));
|
|
58
58
|
});
|
|
59
59
|
//# sourceMappingURL=ParticipantView.js.map
|
|
@@ -2,7 +2,7 @@ import { ComponentPropsWithoutRef, ComponentType } from 'react';
|
|
|
2
2
|
import { StreamVideoParticipant } from '@stream-io/video-client';
|
|
3
3
|
import { VideoPlaceholderProps } from './DefaultVideoPlaceholder';
|
|
4
4
|
export type VideoProps = ComponentPropsWithoutRef<'video'> & {
|
|
5
|
-
kind: 'video' | 'screen';
|
|
5
|
+
kind: 'video' | 'screen' | 'none';
|
|
6
6
|
participant: StreamVideoParticipant;
|
|
7
7
|
/**
|
|
8
8
|
* Override the default UI that's visible when a participant turned off their video.
|
|
@@ -24,7 +24,11 @@ export const Video = (_a) => {
|
|
|
24
24
|
// const [videoTrackMuted, setVideoTrackMuted] = useState(false);
|
|
25
25
|
const [videoPlaying, setVideoPlaying] = useState(false);
|
|
26
26
|
const viewportVisibilityRef = useRef(viewportVisibilityState);
|
|
27
|
-
const stream = kind === '
|
|
27
|
+
const stream = kind === 'none'
|
|
28
|
+
? undefined
|
|
29
|
+
: kind === 'video'
|
|
30
|
+
? videoStream
|
|
31
|
+
: screenShareStream;
|
|
28
32
|
// TODO: handle track muting
|
|
29
33
|
// useEffect(() => {
|
|
30
34
|
// if (!stream) return;
|
|
@@ -43,16 +47,18 @@ export const Video = (_a) => {
|
|
|
43
47
|
// track.removeEventListener('unmute', handleUnmute);
|
|
44
48
|
// };
|
|
45
49
|
// }, [stream]);
|
|
46
|
-
const isPublishingTrack =
|
|
47
|
-
?
|
|
48
|
-
:
|
|
50
|
+
const isPublishingTrack = kind === 'none'
|
|
51
|
+
? false
|
|
52
|
+
: publishedTracks.includes(kind === 'video'
|
|
53
|
+
? SfuModels.TrackType.VIDEO
|
|
54
|
+
: SfuModels.TrackType.SCREEN_SHARE);
|
|
49
55
|
const displayPlaceholder = !isPublishingTrack ||
|
|
50
56
|
(viewportVisibilityState === VisibilityState.INVISIBLE &&
|
|
51
57
|
!screenShareStream) ||
|
|
52
58
|
!videoPlaying;
|
|
53
59
|
const lastDimensionRef = useRef();
|
|
54
60
|
const updateSubscription = useCallback((dimension, type = DebounceType.SLOW) => {
|
|
55
|
-
if (!call)
|
|
61
|
+
if (!call || kind === 'none')
|
|
56
62
|
return;
|
|
57
63
|
call.updateSubscriptionsPartial(kind, {
|
|
58
64
|
[sessionId]: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Video.js","sourceRoot":"","sources":["../../../../../src/core/components/Video/Video.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAGL,WAAW,EACX,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,YAAY,EACZ,SAAS,EAET,eAAe,GAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,uBAAuB,GAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAe1D,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAOT,EAAE,EAAE;QAPK,EACpB,IAAI,EACJ,WAAW,EACX,SAAS,EACT,gBAAgB,GAAG,uBAAuB,EAC1C,IAAI,OAEO,EADR,IAAI,cANa,gEAOrB,CADQ;IAEP,MAAM,EACJ,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,MAAM,GACP,GAAG,WAAW,CAAC;IAEhB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,IAAI,CACL,CAAC;IAEF,iEAAiE;IACjE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,qBAAqB,GAAG,MAAM,CAClC,uBAAuB,CACxB,CAAC;IAEF,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Video.js","sourceRoot":"","sources":["../../../../../src/core/components/Video/Video.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@floating-ui/react": "^0.22.0",
|
|
26
26
|
"@nivo/core": "^0.80.0",
|
|
27
27
|
"@nivo/line": "^0.80.0",
|
|
28
|
-
"@stream-io/i18n": "^0.0.
|
|
29
|
-
"@stream-io/video-client": "^0.0.
|
|
30
|
-
"@stream-io/video-react-bindings": "^0.0.
|
|
28
|
+
"@stream-io/i18n": "^0.0.5",
|
|
29
|
+
"@stream-io/video-client": "^0.0.16",
|
|
30
|
+
"@stream-io/video-react-bindings": "^0.0.17",
|
|
31
31
|
"clsx": "^1.2.1",
|
|
32
32
|
"rxjs": "~7.8.1"
|
|
33
33
|
},
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"typedoc": "^0.24.7",
|
|
48
48
|
"typescript": "^4.9.5"
|
|
49
49
|
},
|
|
50
|
-
"version": "0.0.
|
|
50
|
+
"version": "0.0.35"
|
|
51
51
|
}
|
|
@@ -96,7 +96,7 @@ export const SpeakerLayout = ({
|
|
|
96
96
|
<ParticipantView
|
|
97
97
|
participant={participantInSpotlight}
|
|
98
98
|
muteAudio={isSpeakerScreenSharing}
|
|
99
|
-
|
|
99
|
+
videoMode={isSpeakerScreenSharing ? 'screen' : 'video'}
|
|
100
100
|
ParticipantViewUI={ParticipantViewUISpotlight}
|
|
101
101
|
VideoPlaceholder={VideoPlaceholder}
|
|
102
102
|
/>
|
|
@@ -69,7 +69,7 @@ export const DefaultParticipantViewUI = ({
|
|
|
69
69
|
showMenuButton = true,
|
|
70
70
|
}: DefaultParticipantViewUIProps) => {
|
|
71
71
|
const call = useCall()!;
|
|
72
|
-
const { participant, participantViewElement,
|
|
72
|
+
const { participant, participantViewElement, videoMode, videoElement } =
|
|
73
73
|
useParticipantViewContext();
|
|
74
74
|
const { reaction, sessionId, publishedTracks } = participant;
|
|
75
75
|
|
|
@@ -80,7 +80,7 @@ export const DefaultParticipantViewUI = ({
|
|
|
80
80
|
if (
|
|
81
81
|
participant.isLocalParticipant &&
|
|
82
82
|
hasScreenShare &&
|
|
83
|
-
|
|
83
|
+
videoMode === 'screen'
|
|
84
84
|
)
|
|
85
85
|
return (
|
|
86
86
|
<>
|
|
@@ -21,7 +21,7 @@ import { isComponentType, applyElementToRef } from '../../../utilities';
|
|
|
21
21
|
import { useLocalParticipant } from '@stream-io/video-react-bindings';
|
|
22
22
|
|
|
23
23
|
export type ParticipantViewContextValue = Required<
|
|
24
|
-
Pick<ParticipantViewProps, 'participant' | '
|
|
24
|
+
Pick<ParticipantViewProps, 'participant' | 'videoMode'>
|
|
25
25
|
> & {
|
|
26
26
|
participantViewElement: HTMLDivElement | null;
|
|
27
27
|
videoElement: HTMLVideoElement | null;
|
|
@@ -49,12 +49,12 @@ export type ParticipantViewProps = {
|
|
|
49
49
|
ParticipantViewUI?: ComponentType | ReactElement | null;
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
* The kind of video stream to play for the given participant.
|
|
52
|
+
* The kind of video stream to play for the given participant. The default value is `video`. You can use `none` if you're building an audio-only call.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
videoMode?: 'video' | 'screen' | 'none';
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
*
|
|
57
|
+
* This prop is only useful for advanced use-cases (for example building your own paginated layout). When set to `true` it will mute the give participant's audio stream on the client side. The local participant is always muted.
|
|
58
58
|
*/
|
|
59
59
|
muteAudio?: boolean;
|
|
60
60
|
|
|
@@ -76,7 +76,7 @@ export const ParticipantView = forwardRef<HTMLDivElement, ParticipantViewProps>(
|
|
|
76
76
|
(
|
|
77
77
|
{
|
|
78
78
|
participant,
|
|
79
|
-
|
|
79
|
+
videoMode = 'video',
|
|
80
80
|
muteAudio,
|
|
81
81
|
refs: { setVideoElement, setVideoPlaceholderElement } = {},
|
|
82
82
|
className,
|
|
@@ -119,14 +119,14 @@ export const ParticipantView = forwardRef<HTMLDivElement, ParticipantViewProps>(
|
|
|
119
119
|
participantViewElement: trackedElement,
|
|
120
120
|
videoElement: contextVideoElement,
|
|
121
121
|
videoPlaceholderElement: contextVideoPlaceholderElement,
|
|
122
|
-
|
|
122
|
+
videoMode,
|
|
123
123
|
}),
|
|
124
124
|
[
|
|
125
125
|
contextVideoElement,
|
|
126
126
|
contextVideoPlaceholderElement,
|
|
127
127
|
participant,
|
|
128
128
|
trackedElement,
|
|
129
|
-
|
|
129
|
+
videoMode,
|
|
130
130
|
],
|
|
131
131
|
);
|
|
132
132
|
|
|
@@ -168,7 +168,7 @@ export const ParticipantView = forwardRef<HTMLDivElement, ParticipantViewProps>(
|
|
|
168
168
|
<Video
|
|
169
169
|
VideoPlaceholder={VideoPlaceholder}
|
|
170
170
|
participant={participant}
|
|
171
|
-
kind={
|
|
171
|
+
kind={videoMode}
|
|
172
172
|
refs={videoRefs}
|
|
173
173
|
autoPlay
|
|
174
174
|
/>
|
|
@@ -21,7 +21,7 @@ import { BaseVideo } from './BaseVideo';
|
|
|
21
21
|
import { useCall } from '@stream-io/video-react-bindings';
|
|
22
22
|
|
|
23
23
|
export type VideoProps = ComponentPropsWithoutRef<'video'> & {
|
|
24
|
-
kind: 'video' | 'screen';
|
|
24
|
+
kind: 'video' | 'screen' | 'none';
|
|
25
25
|
participant: StreamVideoParticipant;
|
|
26
26
|
/**
|
|
27
27
|
* Override the default UI that's visible when a participant turned off their video.
|
|
@@ -63,7 +63,12 @@ export const Video = ({
|
|
|
63
63
|
viewportVisibilityState,
|
|
64
64
|
);
|
|
65
65
|
|
|
66
|
-
const stream =
|
|
66
|
+
const stream =
|
|
67
|
+
kind === 'none'
|
|
68
|
+
? undefined
|
|
69
|
+
: kind === 'video'
|
|
70
|
+
? videoStream
|
|
71
|
+
: screenShareStream;
|
|
67
72
|
|
|
68
73
|
// TODO: handle track muting
|
|
69
74
|
// useEffect(() => {
|
|
@@ -88,11 +93,14 @@ export const Video = ({
|
|
|
88
93
|
// };
|
|
89
94
|
// }, [stream]);
|
|
90
95
|
|
|
91
|
-
const isPublishingTrack =
|
|
92
|
-
kind === '
|
|
93
|
-
?
|
|
94
|
-
:
|
|
95
|
-
|
|
96
|
+
const isPublishingTrack =
|
|
97
|
+
kind === 'none'
|
|
98
|
+
? false
|
|
99
|
+
: publishedTracks.includes(
|
|
100
|
+
kind === 'video'
|
|
101
|
+
? SfuModels.TrackType.VIDEO
|
|
102
|
+
: SfuModels.TrackType.SCREEN_SHARE,
|
|
103
|
+
);
|
|
96
104
|
|
|
97
105
|
const displayPlaceholder =
|
|
98
106
|
!isPublishingTrack ||
|
|
@@ -106,7 +114,7 @@ export const Video = ({
|
|
|
106
114
|
dimension?: SfuModels.VideoDimension,
|
|
107
115
|
type: DebounceType = DebounceType.SLOW,
|
|
108
116
|
) => {
|
|
109
|
-
if (!call) return;
|
|
117
|
+
if (!call || kind === 'none') return;
|
|
110
118
|
|
|
111
119
|
call.updateSubscriptionsPartial(
|
|
112
120
|
kind,
|