@stream-io/video-react-native-sdk 0.6.2 → 0.6.3
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 +7 -0
- package/dist/commonjs/components/Call/CallContent/CallContent.js +3 -0
- package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/commonjs/components/Call/CallControls/{ScreenShareButton.js → ScreenShareToggleButton.js} +44 -43
- package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -0
- package/dist/commonjs/components/Call/CallControls/index.js +4 -4
- package/dist/commonjs/components/Call/CallControls/index.js.map +1 -1
- package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js +3 -2
- package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
- package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js +59 -6
- package/dist/commonjs/components/Livestream/HostLivestream/HostLivestream.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/HostLivestreamControls.js +7 -3
- package/dist/commonjs/components/Livestream/LivestreamControls/HostLivestreamControls.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js +13 -9
- package/dist/commonjs/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.js +126 -0
- package/dist/commonjs/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.js.map +1 -0
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +4 -2
- package/dist/commonjs/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamControls/index.js +44 -11
- package/dist/commonjs/components/Livestream/LivestreamControls/index.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js +45 -6
- package/dist/commonjs/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/HostLivestreamTopView.js +4 -2
- package/dist/commonjs/components/Livestream/LivestreamTopView/HostLivestreamTopView.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.js +4 -2
- package/dist/commonjs/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.js.map +1 -1
- package/dist/commonjs/components/Livestream/LivestreamTopView/index.js +11 -0
- package/dist/commonjs/components/Livestream/LivestreamTopView/index.js.map +1 -1
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js +24 -23
- package/dist/commonjs/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/commonjs/components/Participant/FloatingParticipantView/index.js +4 -3
- package/dist/commonjs/components/Participant/FloatingParticipantView/index.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js +33 -9
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
- package/dist/commonjs/components/utility/ScreenShareOverlay.js +92 -0
- package/dist/commonjs/components/utility/ScreenShareOverlay.js.map +1 -0
- package/dist/commonjs/components/utility/index.js +11 -0
- package/dist/commonjs/components/utility/index.js.map +1 -1
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +5 -3
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/icons/StopScreenShare.js +26 -0
- package/dist/commonjs/icons/StopScreenShare.js.map +1 -0
- package/dist/commonjs/icons/index.js +11 -0
- package/dist/commonjs/icons/index.js.map +1 -1
- package/dist/commonjs/theme/theme.js +13 -4
- package/dist/commonjs/theme/theme.js.map +1 -1
- package/dist/commonjs/translations/en.json +2 -0
- package/dist/commonjs/utils/StreamVideoRN/index.js +2 -1
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/pushLogoutCallback.js.map +1 -1
- package/dist/commonjs/utils/push/android.js +6 -4
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js +6 -4
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Call/CallContent/CallContent.js +3 -0
- package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/module/components/Call/CallControls/{ScreenShareButton.js → ScreenShareToggleButton.js} +41 -40
- package/dist/module/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -0
- package/dist/module/components/Call/CallControls/index.js +1 -1
- package/dist/module/components/Call/CallControls/index.js.map +1 -1
- package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js +3 -2
- package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
- package/dist/module/components/Livestream/HostLivestream/HostLivestream.js +60 -7
- package/dist/module/components/Livestream/HostLivestream/HostLivestream.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/HostLivestreamControls.js +7 -3
- package/dist/module/components/Livestream/LivestreamControls/HostLivestreamControls.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js +13 -9
- package/dist/module/components/Livestream/LivestreamControls/HostStartStreamButton.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.js +117 -0
- package/dist/module/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.js.map +1 -0
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js +4 -2
- package/dist/module/components/Livestream/LivestreamControls/ViewerLivestreamControls.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamControls/index.js +4 -1
- package/dist/module/components/Livestream/LivestreamControls/index.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js +43 -5
- package/dist/module/components/Livestream/LivestreamLayout/LivestreamLayout.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/HostLivestreamTopView.js +4 -2
- package/dist/module/components/Livestream/LivestreamTopView/HostLivestreamTopView.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.js +4 -2
- package/dist/module/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.js.map +1 -1
- package/dist/module/components/Livestream/LivestreamTopView/index.js +1 -0
- package/dist/module/components/Livestream/LivestreamTopView/index.js.map +1 -1
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js +24 -24
- package/dist/module/components/Livestream/ViewerLivestream/ViewerLivestream.js.map +1 -1
- package/dist/module/components/Participant/FloatingParticipantView/index.js +4 -3
- package/dist/module/components/Participant/FloatingParticipantView/index.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/VideoRenderer.js +33 -9
- package/dist/module/components/Participant/ParticipantView/VideoRenderer.js.map +1 -1
- package/dist/module/components/utility/ScreenShareOverlay.js +85 -0
- package/dist/module/components/utility/ScreenShareOverlay.js.map +1 -0
- package/dist/module/components/utility/index.js +1 -0
- package/dist/module/components/utility/index.js.map +1 -1
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +5 -3
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/icons/StopScreenShare.js +16 -0
- package/dist/module/icons/StopScreenShare.js.map +1 -0
- package/dist/module/icons/index.js +1 -0
- package/dist/module/icons/index.js.map +1 -1
- package/dist/module/theme/theme.js +13 -4
- package/dist/module/theme/theme.js.map +1 -1
- package/dist/module/translations/en.json +2 -0
- package/dist/module/utils/StreamVideoRN/index.js +2 -1
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/pushLogoutCallback.js.map +1 -1
- package/dist/module/utils/push/android.js +6 -4
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/ios.js +6 -4
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Call/CallContent/CallContent.d.ts +6 -1
- package/dist/typescript/components/Call/CallContent/CallContent.d.ts.map +1 -1
- package/dist/typescript/components/Call/CallControls/{ScreenShareButton.d.ts → ScreenShareToggleButton.d.ts} +3 -3
- package/dist/typescript/components/Call/CallControls/ScreenShareToggleButton.d.ts.map +1 -0
- package/dist/typescript/components/Call/CallControls/index.d.ts +1 -1
- package/dist/typescript/components/Call/CallControls/index.d.ts.map +1 -1
- package/dist/typescript/components/Call/CallLayout/CallParticipantsSpotlight.d.ts +2 -2
- package/dist/typescript/components/Call/CallLayout/CallParticipantsSpotlight.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/HostLivestream/HostLivestream.d.ts +16 -1
- package/dist/typescript/components/Livestream/HostLivestream/HostLivestream.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/HostLivestreamControls.d.ts +7 -1
- package/dist/typescript/components/Livestream/LivestreamControls/HostLivestreamControls.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/HostStartStreamButton.d.ts +7 -3
- package/dist/typescript/components/Livestream/LivestreamControls/HostStartStreamButton.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.d.ts +7 -0
- package/dist/typescript/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.d.ts.map +1 -0
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLivestreamControls.d.ts +3 -1
- package/dist/typescript/components/Livestream/LivestreamControls/ViewerLivestreamControls.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamControls/index.d.ts +4 -1
- package/dist/typescript/components/Livestream/LivestreamControls/index.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamLayout/LivestreamLayout.d.ts +6 -1
- package/dist/typescript/components/Livestream/LivestreamLayout/LivestreamLayout.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/HostLivestreamTopView.d.ts +3 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/HostLivestreamTopView.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.d.ts +3 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/LivestreamTopView/index.d.ts +1 -0
- package/dist/typescript/components/Livestream/LivestreamTopView/index.d.ts.map +1 -1
- package/dist/typescript/components/Livestream/ViewerLivestream/ViewerLivestream.d.ts.map +1 -1
- package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts +8 -3
- package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts.map +1 -1
- package/dist/typescript/components/Participant/ParticipantView/VideoRenderer.d.ts.map +1 -1
- package/dist/typescript/components/utility/ScreenShareOverlay.d.ts +10 -0
- package/dist/typescript/components/utility/ScreenShareOverlay.d.ts.map +1 -0
- package/dist/typescript/components/utility/index.d.ts +1 -0
- package/dist/typescript/components/utility/index.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/icons/StopScreenShare.d.ts +8 -0
- package/dist/typescript/icons/StopScreenShare.d.ts.map +1 -0
- package/dist/typescript/icons/index.d.ts +1 -0
- package/dist/typescript/icons/index.d.ts.map +1 -1
- package/dist/typescript/theme/theme.d.ts +12 -3
- package/dist/typescript/theme/theme.d.ts.map +1 -1
- package/dist/typescript/translations/index.d.ts +2 -0
- package/dist/typescript/translations/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/internal/pushLogoutCallback.d.ts +2 -2
- package/dist/typescript/utils/internal/pushLogoutCallback.d.ts.map +1 -1
- package/dist/typescript/utils/push/android.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/Call/CallContent/CallContent.tsx +10 -0
- package/src/components/Call/CallControls/{ScreenShareButton.tsx → ScreenShareToggleButton.tsx} +59 -41
- package/src/components/Call/CallControls/index.tsx +1 -1
- package/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx +32 -24
- package/src/components/Livestream/HostLivestream/HostLivestream.tsx +92 -6
- package/src/components/Livestream/LivestreamControls/HostLivestreamControls.tsx +10 -1
- package/src/components/Livestream/LivestreamControls/HostStartStreamButton.tsx +18 -10
- package/src/components/Livestream/LivestreamControls/LivestreamScreenShareToggleButton.tsx +161 -0
- package/src/components/Livestream/LivestreamControls/ViewerLivestreamControls.tsx +4 -1
- package/src/components/Livestream/LivestreamControls/index.ts +4 -1
- package/src/components/Livestream/LivestreamLayout/LivestreamLayout.tsx +66 -6
- package/src/components/Livestream/LivestreamTopView/HostLivestreamTopView.tsx +4 -1
- package/src/components/Livestream/LivestreamTopView/ViewerLivestreamTopView.tsx +4 -1
- package/src/components/Livestream/LivestreamTopView/index.ts +1 -0
- package/src/components/Livestream/ViewerLivestream/ViewerLivestream.tsx +39 -38
- package/src/components/Participant/FloatingParticipantView/index.tsx +15 -5
- package/src/components/Participant/ParticipantView/VideoRenderer.tsx +54 -8
- package/src/components/utility/ScreenShareOverlay.tsx +106 -0
- package/src/components/utility/index.ts +1 -0
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +5 -3
- package/src/icons/StopScreenShare.tsx +22 -0
- package/src/icons/index.tsx +1 -0
- package/src/theme/theme.ts +24 -6
- package/src/translations/en.json +2 -0
- package/src/utils/StreamVideoRN/index.ts +4 -1
- package/src/utils/internal/pushLogoutCallback.ts +2 -2
- package/src/utils/push/android.ts +6 -4
- package/src/utils/push/ios.ts +6 -4
- package/src/version.ts +1 -1
- package/dist/commonjs/components/Call/CallControls/ScreenShareButton.js.map +0 -1
- package/dist/module/components/Call/CallControls/ScreenShareButton.js.map +0 -1
- package/dist/typescript/components/Call/CallControls/ScreenShareButton.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
|
-
import { StyleSheet,
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import InCallManager from 'react-native-incall-manager';
|
|
4
4
|
|
|
5
5
|
import { useTheme } from '../../../contexts';
|
|
@@ -15,6 +15,17 @@ import {
|
|
|
15
15
|
LivestreamLayout as DefaultLivestreamLayout,
|
|
16
16
|
LivestreamLayoutProps,
|
|
17
17
|
} from '../LivestreamLayout';
|
|
18
|
+
import { Z_INDEX } from '../../../constants';
|
|
19
|
+
import {
|
|
20
|
+
FloatingParticipantView as DefaultFloatingParticipantView,
|
|
21
|
+
FloatingParticipantViewProps,
|
|
22
|
+
} from '../../Participant/FloatingParticipantView';
|
|
23
|
+
import { useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
24
|
+
import { SfuModels, StreamVideoParticipant } from '@stream-io/video-client';
|
|
25
|
+
import {
|
|
26
|
+
ScreenShareOverlay as DefaultScreenShaerOverlay,
|
|
27
|
+
ScreenShareOverlayProps,
|
|
28
|
+
} from '../../utility/ScreenShareOverlay';
|
|
18
29
|
|
|
19
30
|
/**
|
|
20
31
|
* Props for the HostLivestream component.
|
|
@@ -33,12 +44,28 @@ export type HostLivestreamProps = HostLivestreamTopViewProps &
|
|
|
33
44
|
* Component to customize the bottom view controls at the host's live stream.
|
|
34
45
|
*/
|
|
35
46
|
HostLivestreamControls?: React.ComponentType<HostLivestreamControlsProps> | null;
|
|
47
|
+
/**
|
|
48
|
+
* Component to customize the FloatingParticipantView when screen is shared.
|
|
49
|
+
*/
|
|
50
|
+
FloatingParticipantView?: React.ComponentType<FloatingParticipantViewProps> | null;
|
|
51
|
+
/**
|
|
52
|
+
* Component to customize the ScreenShareOverlay.
|
|
53
|
+
*/
|
|
54
|
+
ScreenShareOverlay?: React.ComponentType<ScreenShareOverlayProps> | null;
|
|
36
55
|
/**
|
|
37
56
|
* Enable HTTP live streaming
|
|
38
57
|
*/
|
|
39
58
|
hls?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Should the published streams be stopped if the host end the livestream.
|
|
61
|
+
* @default true
|
|
62
|
+
*/
|
|
63
|
+
stopPublishedStreamsOnEndStream?: boolean;
|
|
40
64
|
};
|
|
41
65
|
|
|
66
|
+
const hasVideoTrack = (p?: StreamVideoParticipant) =>
|
|
67
|
+
p?.publishedTracks.includes(SfuModels.TrackType.VIDEO);
|
|
68
|
+
|
|
42
69
|
/**
|
|
43
70
|
* The HostLivestream component displays the UI for the Host's live stream.
|
|
44
71
|
*/
|
|
@@ -46,6 +73,8 @@ export const HostLivestream = ({
|
|
|
46
73
|
HostLivestreamTopView = DefaultHostLivestreamTopView,
|
|
47
74
|
HostLivestreamControls = DefaultHostLivestreamControls,
|
|
48
75
|
LivestreamLayout = DefaultLivestreamLayout,
|
|
76
|
+
FloatingParticipantView = DefaultFloatingParticipantView,
|
|
77
|
+
ScreenShareOverlay = DefaultScreenShaerOverlay,
|
|
49
78
|
LiveIndicator,
|
|
50
79
|
FollowerCount,
|
|
51
80
|
DurationBadge,
|
|
@@ -54,35 +83,74 @@ export const HostLivestream = ({
|
|
|
54
83
|
onEndStreamHandler,
|
|
55
84
|
onStartStreamHandler,
|
|
56
85
|
hls = false,
|
|
86
|
+
stopPublishedStreamsOnEndStream = true,
|
|
57
87
|
}: HostLivestreamProps) => {
|
|
58
88
|
const {
|
|
59
89
|
theme: { colors, hostLivestream },
|
|
60
90
|
} = useTheme();
|
|
61
91
|
|
|
92
|
+
const { useParticipants, useHasOngoingScreenShare } = useCallStateHooks();
|
|
93
|
+
const [currentSpeaker] = useParticipants();
|
|
94
|
+
const hasOngoingScreenShare = useHasOngoingScreenShare();
|
|
95
|
+
const floatingParticipant =
|
|
96
|
+
hasOngoingScreenShare && hasVideoTrack(currentSpeaker) && currentSpeaker;
|
|
97
|
+
|
|
62
98
|
// Automatically route audio to speaker devices as relevant for watching videos.
|
|
63
99
|
useEffect(() => {
|
|
64
100
|
InCallManager.start({ media: 'video' });
|
|
65
101
|
return () => InCallManager.stop();
|
|
66
102
|
}, []);
|
|
67
103
|
|
|
104
|
+
const [topViewHeight, setTopViewHeight] = React.useState<number>();
|
|
105
|
+
const [controlsHeight, setControlsHeight] = React.useState<number>();
|
|
106
|
+
|
|
68
107
|
const topViewProps: HostLivestreamTopViewProps = {
|
|
69
108
|
LiveIndicator,
|
|
70
109
|
FollowerCount,
|
|
71
110
|
DurationBadge,
|
|
111
|
+
onLayout: (event) => {
|
|
112
|
+
setTopViewHeight(event.nativeEvent.layout.height);
|
|
113
|
+
},
|
|
72
114
|
};
|
|
73
115
|
|
|
74
116
|
return (
|
|
75
|
-
<
|
|
117
|
+
<View
|
|
76
118
|
style={[
|
|
77
119
|
styles.container,
|
|
78
120
|
{
|
|
79
|
-
backgroundColor: colors.
|
|
121
|
+
backgroundColor: colors.dark_gray,
|
|
80
122
|
},
|
|
81
123
|
hostLivestream.container,
|
|
82
124
|
]}
|
|
83
125
|
>
|
|
84
|
-
{HostLivestreamTopView &&
|
|
85
|
-
|
|
126
|
+
{HostLivestreamTopView && (
|
|
127
|
+
<View
|
|
128
|
+
style={styles.topViewContainer}
|
|
129
|
+
onLayout={(event) => {
|
|
130
|
+
setTopViewHeight(event.nativeEvent.layout.height);
|
|
131
|
+
}}
|
|
132
|
+
>
|
|
133
|
+
<HostLivestreamTopView {...topViewProps} />
|
|
134
|
+
</View>
|
|
135
|
+
)}
|
|
136
|
+
{FloatingParticipantView &&
|
|
137
|
+
floatingParticipant &&
|
|
138
|
+
topViewHeight &&
|
|
139
|
+
controlsHeight && (
|
|
140
|
+
<FloatingParticipantView
|
|
141
|
+
participant={floatingParticipant}
|
|
142
|
+
draggableContainerStyle={[
|
|
143
|
+
StyleSheet.absoluteFill,
|
|
144
|
+
{
|
|
145
|
+
top: topViewHeight,
|
|
146
|
+
bottom: controlsHeight,
|
|
147
|
+
},
|
|
148
|
+
]}
|
|
149
|
+
/>
|
|
150
|
+
)}
|
|
151
|
+
{LivestreamLayout && (
|
|
152
|
+
<LivestreamLayout ScreenShareOverlay={ScreenShareOverlay} />
|
|
153
|
+
)}
|
|
86
154
|
{HostLivestreamControls && (
|
|
87
155
|
<HostLivestreamControls
|
|
88
156
|
onEndStreamHandler={onEndStreamHandler}
|
|
@@ -90,9 +158,13 @@ export const HostLivestream = ({
|
|
|
90
158
|
HostStartStreamButton={HostStartStreamButton}
|
|
91
159
|
LivestreamMediaControls={LivestreamMediaControls}
|
|
92
160
|
hls={hls}
|
|
161
|
+
onLayout={(event) => {
|
|
162
|
+
setControlsHeight(event.nativeEvent.layout.height);
|
|
163
|
+
}}
|
|
164
|
+
stopPublishedStreamsOnEndStream={stopPublishedStreamsOnEndStream}
|
|
93
165
|
/>
|
|
94
166
|
)}
|
|
95
|
-
</
|
|
167
|
+
</View>
|
|
96
168
|
);
|
|
97
169
|
};
|
|
98
170
|
|
|
@@ -100,4 +172,18 @@ const styles = StyleSheet.create({
|
|
|
100
172
|
container: {
|
|
101
173
|
flex: 1,
|
|
102
174
|
},
|
|
175
|
+
topViewContainer: {
|
|
176
|
+
position: 'absolute',
|
|
177
|
+
top: 0,
|
|
178
|
+
left: 0,
|
|
179
|
+
right: 0,
|
|
180
|
+
zIndex: Z_INDEX.IN_FRONT,
|
|
181
|
+
},
|
|
182
|
+
controlsViewContainer: {
|
|
183
|
+
position: 'absolute',
|
|
184
|
+
bottom: 0,
|
|
185
|
+
left: 0,
|
|
186
|
+
right: 0,
|
|
187
|
+
zIndex: Z_INDEX.IN_FRONT,
|
|
188
|
+
},
|
|
103
189
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
3
3
|
import {
|
|
4
4
|
HostStartStreamButton as DefaultHostStartStreamButton,
|
|
5
5
|
HostStartStreamButtonProps,
|
|
@@ -27,6 +27,11 @@ export type HostLivestreamControlsProps = HostStartStreamButtonProps & {
|
|
|
27
27
|
* Enable HTTP live streaming
|
|
28
28
|
*/
|
|
29
29
|
hls?: boolean;
|
|
30
|
+
onLayout?: ViewProps['onLayout'];
|
|
31
|
+
/**
|
|
32
|
+
* Should the published streams be stopped if the host end the livestream.
|
|
33
|
+
*/
|
|
34
|
+
stopPublishedStreamsOnEndStream: boolean;
|
|
30
35
|
};
|
|
31
36
|
|
|
32
37
|
/**
|
|
@@ -38,6 +43,8 @@ export const HostLivestreamControls = ({
|
|
|
38
43
|
onEndStreamHandler,
|
|
39
44
|
onStartStreamHandler,
|
|
40
45
|
hls = false,
|
|
46
|
+
stopPublishedStreamsOnEndStream,
|
|
47
|
+
onLayout,
|
|
41
48
|
}: HostLivestreamControlsProps) => {
|
|
42
49
|
const {
|
|
43
50
|
theme: { colors, hostLivestreamControls },
|
|
@@ -49,6 +56,7 @@ export const HostLivestreamControls = ({
|
|
|
49
56
|
{ backgroundColor: colors.static_overlay },
|
|
50
57
|
hostLivestreamControls.container,
|
|
51
58
|
]}
|
|
59
|
+
onLayout={onLayout}
|
|
52
60
|
>
|
|
53
61
|
<View style={[styles.leftElement, hostLivestreamControls.leftElement]}>
|
|
54
62
|
{HostStartStreamButton && (
|
|
@@ -56,6 +64,7 @@ export const HostLivestreamControls = ({
|
|
|
56
64
|
onEndStreamHandler={onEndStreamHandler}
|
|
57
65
|
onStartStreamHandler={onStartStreamHandler}
|
|
58
66
|
hls={hls}
|
|
67
|
+
stopPublishedStreamsOnEndStream={stopPublishedStreamsOnEndStream}
|
|
59
68
|
/>
|
|
60
69
|
)}
|
|
61
70
|
</View>
|
|
@@ -13,18 +13,19 @@ import {
|
|
|
13
13
|
} from 'react-native';
|
|
14
14
|
import { useTheme } from '../../../contexts';
|
|
15
15
|
import { EndBroadcastIcon, StartStreamIcon } from '../../../icons';
|
|
16
|
+
import { SfuModels } from '@stream-io/video-client';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* Props for the HostStartStreamButton component.
|
|
19
20
|
*/
|
|
20
21
|
export type HostStartStreamButtonProps = {
|
|
21
22
|
/**
|
|
22
|
-
* Handler to be called
|
|
23
|
+
* Handler to be called after the Start Stream button is pressed.
|
|
23
24
|
* @returns void
|
|
24
25
|
*/
|
|
25
26
|
onStartStreamHandler?: () => void;
|
|
26
27
|
/**
|
|
27
|
-
* Handler to be called
|
|
28
|
+
* Handler to be called after the End Stream button is pressed.
|
|
28
29
|
* @returns void
|
|
29
30
|
*/
|
|
30
31
|
onEndStreamHandler?: () => void;
|
|
@@ -32,6 +33,10 @@ export type HostStartStreamButtonProps = {
|
|
|
32
33
|
* Enable HTTP live streaming
|
|
33
34
|
*/
|
|
34
35
|
hls?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Should the published streams be stopped if the host end the livestream.
|
|
38
|
+
*/
|
|
39
|
+
stopPublishedStreamsOnEndStream: boolean;
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -41,6 +46,7 @@ export const HostStartStreamButton = ({
|
|
|
41
46
|
onEndStreamHandler,
|
|
42
47
|
onStartStreamHandler,
|
|
43
48
|
hls,
|
|
49
|
+
stopPublishedStreamsOnEndStream,
|
|
44
50
|
}: HostStartStreamButtonProps) => {
|
|
45
51
|
const [isAwaitingResponse, setIsAwaitingResponse] = useState(false);
|
|
46
52
|
const { useIsCallLive, useIsCallHLSBroadcastingInProgress } =
|
|
@@ -62,10 +68,6 @@ export const HostStartStreamButton = ({
|
|
|
62
68
|
const liveOrBroadcasting = isCallLive || isCallBroadcasting;
|
|
63
69
|
|
|
64
70
|
const onStartStreamButtonPress = async () => {
|
|
65
|
-
if (onStartStreamHandler) {
|
|
66
|
-
onStartStreamHandler();
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
71
|
try {
|
|
70
72
|
setIsAwaitingResponse(true);
|
|
71
73
|
await call?.goLive();
|
|
@@ -73,18 +75,21 @@ export const HostStartStreamButton = ({
|
|
|
73
75
|
await call?.startHLS();
|
|
74
76
|
}
|
|
75
77
|
setIsAwaitingResponse(false);
|
|
78
|
+
if (onStartStreamHandler) {
|
|
79
|
+
onStartStreamHandler();
|
|
80
|
+
}
|
|
76
81
|
} catch (error) {
|
|
77
82
|
console.error('Error starting livestream', error);
|
|
78
83
|
}
|
|
79
84
|
};
|
|
80
85
|
|
|
81
86
|
const onEndStreamButtonPress = async () => {
|
|
82
|
-
if (onEndStreamHandler) {
|
|
83
|
-
onEndStreamHandler();
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
87
|
try {
|
|
87
88
|
setIsAwaitingResponse(true);
|
|
89
|
+
if (stopPublishedStreamsOnEndStream) {
|
|
90
|
+
await call?.stopPublish(SfuModels.TrackType.VIDEO);
|
|
91
|
+
await call?.stopPublish(SfuModels.TrackType.SCREEN_SHARE);
|
|
92
|
+
}
|
|
88
93
|
if (hls) {
|
|
89
94
|
await call?.stopHLS();
|
|
90
95
|
} else {
|
|
@@ -92,6 +97,9 @@ export const HostStartStreamButton = ({
|
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
setIsAwaitingResponse(false);
|
|
100
|
+
if (onEndStreamHandler) {
|
|
101
|
+
onEndStreamHandler();
|
|
102
|
+
}
|
|
95
103
|
} catch (error) {
|
|
96
104
|
console.error('Error stopping livestream', error);
|
|
97
105
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { useTheme } from '../../../contexts/ThemeContext';
|
|
3
|
+
import {
|
|
4
|
+
NativeModules,
|
|
5
|
+
Platform,
|
|
6
|
+
Pressable,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
View,
|
|
9
|
+
findNodeHandle,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import { ScreenShare } from '../../../icons/ScreenShare';
|
|
12
|
+
import { StopScreenShare } from '../../../icons/StopScreenShare';
|
|
13
|
+
import { ScreenCapturePickerView } from '@stream-io/react-native-webrtc';
|
|
14
|
+
import { SfuModels } from '@stream-io/video-client';
|
|
15
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
16
|
+
import { useIsIosScreenshareBroadcastStarted } from '../../../hooks/useIsIosScreenshareBroadcastStarted';
|
|
17
|
+
import { usePrevious } from '../../../utils/hooks/usePrevious';
|
|
18
|
+
|
|
19
|
+
export type LivestreamScreenShareToggleButtonProps = {};
|
|
20
|
+
|
|
21
|
+
// ios >= 14.0 or android - platform restrictions
|
|
22
|
+
const CanDeviceScreenShare =
|
|
23
|
+
(Platform.OS === 'ios' &&
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
Number.parseInt(Platform.Version.split('.')[0], 10) >= 14) ||
|
|
26
|
+
Platform.OS === 'android';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The LivestreamVideoControlButton controls the screenshare stream publish/unpublish while in the livestream for the host.
|
|
30
|
+
*/
|
|
31
|
+
export const LivestreamScreenShareToggleButton = () => {
|
|
32
|
+
const {
|
|
33
|
+
theme: {
|
|
34
|
+
colors,
|
|
35
|
+
variants: { iconSizes, buttonSizes },
|
|
36
|
+
livestreamScreenShareToggleButton,
|
|
37
|
+
},
|
|
38
|
+
} = useTheme();
|
|
39
|
+
|
|
40
|
+
const call = useCall();
|
|
41
|
+
const { useLocalParticipant, useCallSettings } = useCallStateHooks();
|
|
42
|
+
const callSettings = useCallSettings();
|
|
43
|
+
const isScreenSharingEnabledInCall = callSettings?.screensharing.enabled;
|
|
44
|
+
|
|
45
|
+
const iosScreenShareStartedFromSystem = useIsIosScreenshareBroadcastStarted();
|
|
46
|
+
const prevIosScreenShareStartedFromSystem = usePrevious(
|
|
47
|
+
iosScreenShareStartedFromSystem,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const localParticipant = useLocalParticipant();
|
|
51
|
+
const hasPublishedScreenShare = localParticipant?.publishedTracks.includes(
|
|
52
|
+
SfuModels.TrackType.SCREEN_SHARE,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// listens to iOS screen share broadcast started event from the system
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const run = async () => {
|
|
58
|
+
if (Platform.OS !== 'ios') {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (
|
|
62
|
+
iosScreenShareStartedFromSystem &&
|
|
63
|
+
!prevIosScreenShareStartedFromSystem
|
|
64
|
+
) {
|
|
65
|
+
const media = await navigator.mediaDevices.getDisplayMedia({
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
deviceId: 'broadcast',
|
|
68
|
+
video: true,
|
|
69
|
+
audio: true,
|
|
70
|
+
});
|
|
71
|
+
await call?.publishScreenShareStream(media);
|
|
72
|
+
} else if (
|
|
73
|
+
!iosScreenShareStartedFromSystem &&
|
|
74
|
+
prevIosScreenShareStartedFromSystem
|
|
75
|
+
) {
|
|
76
|
+
await call?.stopPublish(SfuModels.TrackType.SCREEN_SHARE);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
run();
|
|
80
|
+
}, [
|
|
81
|
+
call,
|
|
82
|
+
iosScreenShareStartedFromSystem,
|
|
83
|
+
prevIosScreenShareStartedFromSystem,
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
const screenCapturePickerViewiOSRef = React.useRef(null);
|
|
87
|
+
|
|
88
|
+
const onPress = async () => {
|
|
89
|
+
if (!hasPublishedScreenShare) {
|
|
90
|
+
if (Platform.OS === 'ios') {
|
|
91
|
+
const reactTag = findNodeHandle(screenCapturePickerViewiOSRef.current);
|
|
92
|
+
await NativeModules.ScreenCapturePickerViewManager.show(reactTag);
|
|
93
|
+
// After this the iOS screen share broadcast started/stopped event will be triggered
|
|
94
|
+
// and the useEffect listener will handle the rest
|
|
95
|
+
} else {
|
|
96
|
+
try {
|
|
97
|
+
const media = await navigator.mediaDevices.getDisplayMedia({
|
|
98
|
+
video: true,
|
|
99
|
+
audio: true,
|
|
100
|
+
});
|
|
101
|
+
await call?.publishScreenShareStream(media);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
// ignored.. user didnt allow the screen share in the popup
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} else if (hasPublishedScreenShare) {
|
|
107
|
+
await call?.stopPublish(SfuModels.TrackType.SCREEN_SHARE);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (!isScreenSharingEnabledInCall || !CanDeviceScreenShare) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<Pressable
|
|
117
|
+
onPress={onPress}
|
|
118
|
+
style={[
|
|
119
|
+
styles.container,
|
|
120
|
+
{
|
|
121
|
+
backgroundColor: hasPublishedScreenShare
|
|
122
|
+
? colors.error
|
|
123
|
+
: colors.dark_gray,
|
|
124
|
+
height: buttonSizes.xs,
|
|
125
|
+
width: buttonSizes.xs,
|
|
126
|
+
},
|
|
127
|
+
livestreamScreenShareToggleButton.container,
|
|
128
|
+
]}
|
|
129
|
+
>
|
|
130
|
+
<View
|
|
131
|
+
style={[
|
|
132
|
+
styles.icon,
|
|
133
|
+
{
|
|
134
|
+
height: iconSizes.sm,
|
|
135
|
+
width: iconSizes.sm,
|
|
136
|
+
},
|
|
137
|
+
livestreamScreenShareToggleButton.icon,
|
|
138
|
+
]}
|
|
139
|
+
>
|
|
140
|
+
{hasPublishedScreenShare ? (
|
|
141
|
+
<StopScreenShare color={colors.static_white} />
|
|
142
|
+
) : (
|
|
143
|
+
<ScreenShare color={colors.static_white} />
|
|
144
|
+
)}
|
|
145
|
+
</View>
|
|
146
|
+
{Platform.OS === 'ios' && (
|
|
147
|
+
<ScreenCapturePickerView ref={screenCapturePickerViewiOSRef} />
|
|
148
|
+
)}
|
|
149
|
+
</Pressable>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const styles = StyleSheet.create({
|
|
154
|
+
container: {
|
|
155
|
+
justifyContent: 'center',
|
|
156
|
+
alignItems: 'center',
|
|
157
|
+
marginHorizontal: 4,
|
|
158
|
+
borderRadius: 4,
|
|
159
|
+
},
|
|
160
|
+
icon: {},
|
|
161
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
ViewerLeaveStreamButton as DefaultViewerLeaveStreamButton,
|
|
@@ -16,6 +16,7 @@ export type ViewerLivestreamControlsProps = ViewerLeaveStreamButtonProps & {
|
|
|
16
16
|
* Component to customize the leave stream button on the viewer's end live stream.
|
|
17
17
|
*/
|
|
18
18
|
ViewerLeaveStreamButton?: React.ComponentType<ViewerLeaveStreamButtonProps> | null;
|
|
19
|
+
onLayout?: ViewProps['onLayout'];
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -24,6 +25,7 @@ export type ViewerLivestreamControlsProps = ViewerLeaveStreamButtonProps & {
|
|
|
24
25
|
export const ViewerLivestreamControls = ({
|
|
25
26
|
ViewerLeaveStreamButton = DefaultViewerLeaveStreamButton,
|
|
26
27
|
onLeaveStreamHandler,
|
|
28
|
+
onLayout,
|
|
27
29
|
}: ViewerLivestreamControlsProps) => {
|
|
28
30
|
const {
|
|
29
31
|
theme: { colors, viewerLivestreamControls },
|
|
@@ -38,6 +40,7 @@ export const ViewerLivestreamControls = ({
|
|
|
38
40
|
},
|
|
39
41
|
viewerLivestreamControls.container,
|
|
40
42
|
]}
|
|
43
|
+
onLayout={onLayout}
|
|
41
44
|
>
|
|
42
45
|
<View style={[styles.leftElement, viewerLivestreamControls.leftElement]}>
|
|
43
46
|
{ViewerLeaveStreamButton && (
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from './HostLivestreamControls';
|
|
2
|
-
export * from './LivestreamMediaControls';
|
|
3
2
|
export * from './HostStartStreamButton';
|
|
4
3
|
export * from './LivestreamAudioControlButton';
|
|
4
|
+
export * from './LivestreamMediaControls';
|
|
5
5
|
export * from './LivestreamVideoControlButton';
|
|
6
|
+
export * from './ViewerLeaveStreamButton';
|
|
7
|
+
export * from './ViewerLivestreamControls';
|
|
8
|
+
export * from './LivestreamScreenShareToggleButton';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { SfuModels, StreamVideoParticipant } from '@stream-io/video-client';
|
|
3
3
|
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
4
4
|
import { StyleSheet, View, ViewStyle } from 'react-native';
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
VideoRenderer as DefaultVideoRenderer,
|
|
9
9
|
VideoRendererProps,
|
|
10
10
|
} from '../../Participant';
|
|
11
|
+
import { ScreenShareOverlayProps } from '../../utility/ScreenShareOverlay';
|
|
12
|
+
import { VideoDimension } from '@stream-io/video-client/dist/src/gen/video/sfu/models/models';
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Props for the LivestreamLayout component.
|
|
@@ -22,6 +24,10 @@ export type LivestreamLayoutProps = {
|
|
|
22
24
|
* Component to customize the video component of the participant.
|
|
23
25
|
*/
|
|
24
26
|
VideoRenderer?: React.ComponentType<VideoRendererProps> | null;
|
|
27
|
+
/**
|
|
28
|
+
* Component to customize the ScreenShareOverlay.
|
|
29
|
+
*/
|
|
30
|
+
ScreenShareOverlay?: React.ComponentType<ScreenShareOverlayProps> | null;
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
const hasScreenShare = (p?: StreamVideoParticipant) =>
|
|
@@ -33,6 +39,7 @@ const hasScreenShare = (p?: StreamVideoParticipant) =>
|
|
|
33
39
|
export const LivestreamLayout = ({
|
|
34
40
|
landscape,
|
|
35
41
|
VideoRenderer = DefaultVideoRenderer,
|
|
42
|
+
ScreenShareOverlay,
|
|
36
43
|
}: LivestreamLayoutProps) => {
|
|
37
44
|
const { useParticipants, useHasOngoingScreenShare } = useCallStateHooks();
|
|
38
45
|
const call = useCall();
|
|
@@ -47,6 +54,23 @@ export const LivestreamLayout = ({
|
|
|
47
54
|
|
|
48
55
|
usePaginatedLayoutSortPreset(call);
|
|
49
56
|
|
|
57
|
+
const [objectFit, setObjectFit] =
|
|
58
|
+
useState<
|
|
59
|
+
React.ComponentProps<NonNullable<typeof VideoRenderer>>['objectFit']
|
|
60
|
+
>();
|
|
61
|
+
|
|
62
|
+
// no need to pass object fit for local participant as the dimensions are for remote tracks
|
|
63
|
+
const objectFitToBeSet = currentSpeaker?.isLocalParticipant
|
|
64
|
+
? undefined
|
|
65
|
+
: objectFit;
|
|
66
|
+
|
|
67
|
+
const onDimensionsChange = useCallback((d: VideoDimension | undefined) => {
|
|
68
|
+
if (d) {
|
|
69
|
+
const isWidthWide = d.width > d.height;
|
|
70
|
+
setObjectFit(isWidthWide ? 'contain' : 'cover');
|
|
71
|
+
}
|
|
72
|
+
}, []);
|
|
73
|
+
|
|
50
74
|
const landScapeStyles: ViewStyle = {
|
|
51
75
|
flexDirection: landscape ? 'row' : 'column',
|
|
52
76
|
};
|
|
@@ -56,20 +80,56 @@ export const LivestreamLayout = ({
|
|
|
56
80
|
style={[
|
|
57
81
|
styles.container,
|
|
58
82
|
landScapeStyles,
|
|
59
|
-
{ backgroundColor: colors.
|
|
83
|
+
{ backgroundColor: colors.static_grey },
|
|
60
84
|
livestreamLayout.container,
|
|
61
85
|
]}
|
|
62
86
|
>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
87
|
+
<RemoteVideoTrackDimensionsRenderLessComponent
|
|
88
|
+
onDimensionsChange={onDimensionsChange}
|
|
89
|
+
/>
|
|
90
|
+
{VideoRenderer &&
|
|
91
|
+
hasOngoingScreenShare &&
|
|
92
|
+
presenter &&
|
|
93
|
+
(ScreenShareOverlay ? (
|
|
94
|
+
<ScreenShareOverlay />
|
|
95
|
+
) : (
|
|
96
|
+
<VideoRenderer trackType="screenShareTrack" participant={presenter} />
|
|
97
|
+
))}
|
|
66
98
|
{VideoRenderer && !hasOngoingScreenShare && currentSpeaker && (
|
|
67
|
-
<VideoRenderer
|
|
99
|
+
<VideoRenderer
|
|
100
|
+
participant={currentSpeaker}
|
|
101
|
+
objectFit={objectFitToBeSet}
|
|
102
|
+
trackType="videoTrack"
|
|
103
|
+
/>
|
|
68
104
|
)}
|
|
69
105
|
</View>
|
|
70
106
|
);
|
|
71
107
|
};
|
|
72
108
|
|
|
109
|
+
const RemoteVideoTrackDimensionsRenderLessComponent = ({
|
|
110
|
+
onDimensionsChange,
|
|
111
|
+
}: {
|
|
112
|
+
onDimensionsChange: (d: VideoDimension | undefined) => void;
|
|
113
|
+
}) => {
|
|
114
|
+
const [dimension, setDimension] = useState<VideoDimension>();
|
|
115
|
+
const { useCallStatsReport } = useCallStateHooks();
|
|
116
|
+
const statsReport = useCallStatsReport();
|
|
117
|
+
const highestFrameHeight = statsReport?.subscriberStats?.highestFrameHeight;
|
|
118
|
+
const highestFrameWidth = statsReport?.subscriberStats?.highestFrameWidth;
|
|
119
|
+
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (highestFrameHeight && highestFrameWidth) {
|
|
122
|
+
setDimension({ height: highestFrameHeight, width: highestFrameWidth });
|
|
123
|
+
}
|
|
124
|
+
}, [highestFrameHeight, highestFrameWidth]);
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
onDimensionsChange(dimension);
|
|
128
|
+
}, [dimension, onDimensionsChange]);
|
|
129
|
+
|
|
130
|
+
return null;
|
|
131
|
+
};
|
|
132
|
+
|
|
73
133
|
const styles = StyleSheet.create({
|
|
74
134
|
container: {
|
|
75
135
|
flex: 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
3
3
|
import {
|
|
4
4
|
DurationBadge as DefaultDurationBadge,
|
|
5
5
|
DurationBadgeProps,
|
|
@@ -32,6 +32,7 @@ export type HostLivestreamTopViewProps = {
|
|
|
32
32
|
* Component to customize the Follower count indicator on the host's live stream's top view.
|
|
33
33
|
*/
|
|
34
34
|
FollowerCount?: React.ComponentType<FollowerCountProps> | null;
|
|
35
|
+
onLayout?: ViewProps['onLayout'];
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -41,6 +42,7 @@ export const HostLivestreamTopView = ({
|
|
|
41
42
|
DurationBadge = DefaultDurationBadge,
|
|
42
43
|
LiveIndicator = DefaultLiveIndicator,
|
|
43
44
|
FollowerCount = DefaultFollowerCount,
|
|
45
|
+
onLayout,
|
|
44
46
|
}: HostLivestreamTopViewProps) => {
|
|
45
47
|
const { useIsCallLive, useIsCallHLSBroadcastingInProgress } =
|
|
46
48
|
useCallStateHooks();
|
|
@@ -58,6 +60,7 @@ export const HostLivestreamTopView = ({
|
|
|
58
60
|
{ backgroundColor: colors.static_overlay },
|
|
59
61
|
hostLivestreamTopView.container,
|
|
60
62
|
]}
|
|
63
|
+
onLayout={onLayout}
|
|
61
64
|
>
|
|
62
65
|
<View style={[styles.leftElement, hostLivestreamTopView.leftElement]}>
|
|
63
66
|
{DurationBadge && <DurationBadge mode="host" />}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
3
3
|
import {
|
|
4
4
|
DurationBadge as DefaultDurationBadge,
|
|
5
5
|
DurationBadgeProps,
|
|
@@ -31,6 +31,7 @@ export type ViewerLivestreamTopViewProps = {
|
|
|
31
31
|
* Component to customize the Follower count indicator on the viewer's live stream's top view.
|
|
32
32
|
*/
|
|
33
33
|
FollowerCount?: React.ComponentType<FollowerCountProps> | null;
|
|
34
|
+
onLayout?: ViewProps['onLayout'];
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
/**
|
|
@@ -40,6 +41,7 @@ export const ViewerLivestreamTopView = ({
|
|
|
40
41
|
DurationBadge = DefaultDurationBadge,
|
|
41
42
|
LiveIndicator = DefaultLiveIndicator,
|
|
42
43
|
FollowerCount = DefaultFollowerCount,
|
|
44
|
+
onLayout,
|
|
43
45
|
}: ViewerLivestreamTopViewProps) => {
|
|
44
46
|
const {
|
|
45
47
|
theme: { colors, viewerLivestreamTopView },
|
|
@@ -52,6 +54,7 @@ export const ViewerLivestreamTopView = ({
|
|
|
52
54
|
{ backgroundColor: colors.static_overlay },
|
|
53
55
|
viewerLivestreamTopView.container,
|
|
54
56
|
]}
|
|
57
|
+
onLayout={onLayout}
|
|
55
58
|
>
|
|
56
59
|
<View style={[styles.leftElement, viewerLivestreamTopView.leftElement]}>
|
|
57
60
|
<View style={[styles.liveInfo, viewerLivestreamTopView.liveInfo]}>
|