@stream-io/video-react-native-sdk 0.0.1-alpha.185 → 0.0.1-alpha.187
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/src/components/ActiveCall.js +14 -29
- package/dist/src/components/ActiveCall.js.map +1 -1
- package/dist/src/components/CallControlsView.d.ts +4 -3
- package/dist/src/components/CallControlsView.js +6 -10
- package/dist/src/components/CallControlsView.js.map +1 -1
- package/dist/src/components/CallParticipantsBadge.d.ts +4 -1
- package/dist/src/components/CallParticipantsBadge.js +11 -13
- package/dist/src/components/CallParticipantsBadge.js.map +1 -1
- package/dist/src/components/CallParticipantsInfoView.js +64 -30
- package/dist/src/components/CallParticipantsInfoView.js.map +1 -1
- package/dist/src/components/CallParticipantsOptions.d.ts +3 -3
- package/dist/src/components/CallParticipantsOptions.js +94 -65
- package/dist/src/components/CallParticipantsOptions.js.map +1 -1
- package/dist/src/components/CallParticipantsView.js +1 -1
- package/dist/src/components/CallParticipantsView.js.map +1 -1
- package/dist/src/components/LobbyView.js +0 -1
- package/dist/src/components/LobbyView.js.map +1 -1
- package/dist/src/components/LocalVideoView.js +19 -6
- package/dist/src/components/LocalVideoView.js.map +1 -1
- package/dist/src/components/OutgoingCallView.js +3 -3
- package/dist/src/components/OutgoingCallView.js.map +1 -1
- package/dist/src/components/ParticipantView.js +7 -4
- package/dist/src/components/ParticipantView.js.map +1 -1
- package/dist/src/constants/index.d.ts +5 -0
- package/dist/src/constants/index.js +6 -1
- package/dist/src/constants/index.js.map +1 -1
- package/dist/src/icons/Cross.d.ts +3 -2
- package/dist/src/icons/Cross.js +5 -1
- package/dist/src/icons/Cross.js.map +1 -1
- package/dist/src/icons/index.d.ts +0 -1
- package/dist/src/icons/index.js +0 -1
- package/dist/src/icons/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActiveCall.tsx +18 -34
- package/src/components/CallControlsView.tsx +12 -13
- package/src/components/CallParticipantsBadge.tsx +13 -14
- package/src/components/CallParticipantsInfoView.tsx +73 -36
- package/src/components/CallParticipantsOptions.tsx +111 -94
- package/src/components/CallParticipantsView.tsx +1 -1
- package/src/components/LobbyView.tsx +0 -1
- package/src/components/LocalVideoView.tsx +22 -6
- package/src/components/OutgoingCallView.tsx +3 -3
- package/src/components/ParticipantView.tsx +9 -4
- package/src/constants/index.ts +6 -0
- package/src/icons/Cross.tsx +5 -4
- package/src/icons/index.tsx +0 -1
- package/dist/src/icons/VideoOff.d.ts +0 -5
- package/dist/src/icons/VideoOff.js +0 -10
- package/dist/src/icons/VideoOff.js.map +0 -1
- package/src/icons/VideoOff.tsx +0 -20
|
@@ -3,13 +3,22 @@ import {
|
|
|
3
3
|
SfuModels,
|
|
4
4
|
StreamVideoParticipant,
|
|
5
5
|
} from '@stream-io/video-client';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
Cross,
|
|
8
|
+
Mic,
|
|
9
|
+
MicOff,
|
|
10
|
+
ScreenShare,
|
|
11
|
+
Video,
|
|
12
|
+
VideoDisabled,
|
|
13
|
+
VideoSlash,
|
|
14
|
+
} from '../icons';
|
|
7
15
|
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
|
8
16
|
import { generateParticipantTitle } from '../utils';
|
|
9
|
-
import { useCallback } from 'react';
|
|
17
|
+
import React, { useCallback } from 'react';
|
|
10
18
|
import { Avatar } from './Avatar';
|
|
11
19
|
import { theme } from '../theme';
|
|
12
20
|
import { useCall, useHasPermissions } from '@stream-io/video-react-bindings';
|
|
21
|
+
import { palette } from '../theme/constants';
|
|
13
22
|
|
|
14
23
|
type CallParticipantOptionType = {
|
|
15
24
|
title: string;
|
|
@@ -18,7 +27,7 @@ type CallParticipantOptionType = {
|
|
|
18
27
|
};
|
|
19
28
|
|
|
20
29
|
type CallParticipantOptionsType = {
|
|
21
|
-
participant: StreamVideoParticipant;
|
|
30
|
+
participant: StreamVideoParticipant | undefined;
|
|
22
31
|
setSelectedParticipant: React.Dispatch<
|
|
23
32
|
React.SetStateAction<StreamVideoParticipant | undefined>
|
|
24
33
|
>;
|
|
@@ -27,6 +36,22 @@ type CallParticipantOptionsType = {
|
|
|
27
36
|
export const CallParticipantOptions = (props: CallParticipantOptionsType) => {
|
|
28
37
|
const { participant, setSelectedParticipant } = props;
|
|
29
38
|
const call = useCall();
|
|
39
|
+
const userHasMuteUsersCapability = useHasPermissions(
|
|
40
|
+
OwnCapability.MUTE_USERS,
|
|
41
|
+
);
|
|
42
|
+
const userHasUpdateCallPermissionsCapability = useHasPermissions(
|
|
43
|
+
OwnCapability.UPDATE_CALL_PERMISSIONS,
|
|
44
|
+
);
|
|
45
|
+
const userHasBlockUserCapability = useHasPermissions(
|
|
46
|
+
OwnCapability.BLOCK_USERS,
|
|
47
|
+
);
|
|
48
|
+
const onCloseParticipantOptions = useCallback(() => {
|
|
49
|
+
setSelectedParticipant(undefined);
|
|
50
|
+
}, [setSelectedParticipant]);
|
|
51
|
+
|
|
52
|
+
if (!participant) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
30
55
|
|
|
31
56
|
const grantPermission = async (permission: string) => {
|
|
32
57
|
await call?.updateUserPermissions({
|
|
@@ -58,70 +83,68 @@ export const CallParticipantOptions = (props: CallParticipantOptionsType) => {
|
|
|
58
83
|
await call?.blockUser(participant.userId);
|
|
59
84
|
};
|
|
60
85
|
|
|
61
|
-
const
|
|
62
|
-
OwnCapability.MUTE_USERS,
|
|
63
|
-
);
|
|
64
|
-
const userHasUpdateCallPermissionsCapability = useHasPermissions(
|
|
65
|
-
OwnCapability.UPDATE_CALL_PERMISSIONS,
|
|
66
|
-
);
|
|
67
|
-
const userHasBlockUserCapability = useHasPermissions(
|
|
68
|
-
OwnCapability.BLOCK_USERS,
|
|
69
|
-
);
|
|
70
|
-
const participantCanPublishVideo = participant.publishedTracks.includes(
|
|
86
|
+
const participantPublishesVideo = participant.publishedTracks.includes(
|
|
71
87
|
SfuModels.TrackType.VIDEO,
|
|
72
88
|
);
|
|
73
|
-
const
|
|
89
|
+
const participantPublishesAudio = participant.publishedTracks.includes(
|
|
74
90
|
SfuModels.TrackType.AUDIO,
|
|
75
91
|
);
|
|
76
92
|
|
|
77
|
-
const
|
|
93
|
+
const muteUserVideoOption = participantPublishesVideo
|
|
94
|
+
? {
|
|
95
|
+
icon: <VideoSlash color={theme.dark.text_high_emphasis} />,
|
|
96
|
+
title: 'Mute Video',
|
|
97
|
+
onPressHandler: muteUserVideo,
|
|
98
|
+
}
|
|
99
|
+
: null;
|
|
100
|
+
|
|
101
|
+
const muteUserAudioOption = participantPublishesAudio
|
|
102
|
+
? {
|
|
103
|
+
icon: <MicOff color={theme.dark.text_high_emphasis} />,
|
|
104
|
+
title: 'Mute Audio',
|
|
105
|
+
onPressHandler: muteUserAudio,
|
|
106
|
+
}
|
|
107
|
+
: null;
|
|
108
|
+
const muteUserCapabilities: (CallParticipantOptionType | null)[] =
|
|
78
109
|
userHasMuteUsersCapability
|
|
79
|
-
? [
|
|
80
|
-
participantCanPublishVideo
|
|
81
|
-
? {
|
|
82
|
-
title: 'Mute Video',
|
|
83
|
-
onPressHandler: muteUserVideo,
|
|
84
|
-
}
|
|
85
|
-
: null,
|
|
86
|
-
participantCanPublishAudio
|
|
87
|
-
? {
|
|
88
|
-
title: 'Mute Audio',
|
|
89
|
-
onPressHandler: muteUserAudio,
|
|
90
|
-
}
|
|
91
|
-
: null,
|
|
92
|
-
]
|
|
110
|
+
? [muteUserVideoOption, muteUserAudioOption]
|
|
93
111
|
: [];
|
|
94
112
|
|
|
95
|
-
const
|
|
113
|
+
const updateCallPermissionsCapabilities: (CallParticipantOptionType | null)[] =
|
|
96
114
|
userHasUpdateCallPermissionsCapability
|
|
97
115
|
? [
|
|
98
116
|
{
|
|
99
|
-
icon: <VideoDisabled color={theme.
|
|
117
|
+
icon: <VideoDisabled color={theme.dark.text_high_emphasis} />,
|
|
100
118
|
title: 'Disable Video',
|
|
101
119
|
onPressHandler: async () =>
|
|
102
120
|
await revokePermission(OwnCapability.SEND_VIDEO),
|
|
103
121
|
},
|
|
104
122
|
{
|
|
123
|
+
icon: <MicOff color={theme.dark.text_high_emphasis} />,
|
|
105
124
|
title: 'Disable Audio',
|
|
106
125
|
onPressHandler: async () =>
|
|
107
126
|
await revokePermission(OwnCapability.SEND_AUDIO),
|
|
108
127
|
},
|
|
109
128
|
{
|
|
129
|
+
icon: <Mic color={theme.dark.text_high_emphasis} />,
|
|
110
130
|
title: 'Allow Audio',
|
|
111
131
|
onPressHandler: async () =>
|
|
112
132
|
await grantPermission(OwnCapability.SEND_AUDIO),
|
|
113
133
|
},
|
|
114
134
|
{
|
|
135
|
+
icon: <Video color={theme.dark.text_high_emphasis} />,
|
|
115
136
|
title: 'Allow Video',
|
|
116
137
|
onPressHandler: async () =>
|
|
117
138
|
await grantPermission(OwnCapability.SEND_VIDEO),
|
|
118
139
|
},
|
|
119
140
|
{
|
|
141
|
+
icon: <ScreenShare color={theme.dark.text_high_emphasis} />,
|
|
120
142
|
title: 'Allow Screen Sharing',
|
|
121
143
|
onPressHandler: async () =>
|
|
122
144
|
await grantPermission(OwnCapability.SCREENSHARE),
|
|
123
145
|
},
|
|
124
146
|
{
|
|
147
|
+
icon: <Cross color={theme.dark.text_high_emphasis} />,
|
|
125
148
|
title: 'Disable Screen Sharing',
|
|
126
149
|
onPressHandler: async () =>
|
|
127
150
|
await revokePermission(OwnCapability.SCREENSHARE),
|
|
@@ -129,120 +152,114 @@ export const CallParticipantOptions = (props: CallParticipantOptionsType) => {
|
|
|
129
152
|
]
|
|
130
153
|
: [];
|
|
131
154
|
|
|
132
|
-
const
|
|
155
|
+
const blockCapabilities: (CallParticipantOptionType | null)[] =
|
|
133
156
|
userHasBlockUserCapability
|
|
134
|
-
?
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
? [
|
|
158
|
+
{
|
|
159
|
+
icon: <Cross color={theme.dark.text_high_emphasis} />,
|
|
160
|
+
title: 'Block',
|
|
161
|
+
onPressHandler: blockUser,
|
|
162
|
+
},
|
|
163
|
+
]
|
|
164
|
+
: [];
|
|
142
165
|
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
166
|
+
const options: (CallParticipantOptionType | null)[] = [
|
|
167
|
+
...blockCapabilities,
|
|
168
|
+
...muteUserCapabilities,
|
|
169
|
+
...updateCallPermissionsCapabilities,
|
|
170
|
+
];
|
|
146
171
|
|
|
147
172
|
const showYouLabel = participant.isLocalParticipant;
|
|
148
173
|
|
|
149
174
|
return (
|
|
150
|
-
<View style={styles.
|
|
151
|
-
<View style={styles.
|
|
175
|
+
<View style={styles.outerContainer}>
|
|
176
|
+
<View style={styles.modalContainer}>
|
|
152
177
|
<View style={styles.participantInfo}>
|
|
153
178
|
<View style={styles.userInfo}>
|
|
154
179
|
<Avatar radius={theme.avatar.xs} participant={participant} />
|
|
155
|
-
|
|
156
180
|
<Text style={styles.name}>
|
|
157
181
|
{generateParticipantTitle(participant.userId) +
|
|
158
182
|
(showYouLabel ? ' (You)' : '')}
|
|
159
183
|
</Text>
|
|
160
184
|
</View>
|
|
161
|
-
|
|
162
185
|
<Pressable
|
|
163
|
-
style={
|
|
186
|
+
style={styles.closePressable}
|
|
164
187
|
onPress={onCloseParticipantOptions}
|
|
165
188
|
>
|
|
166
|
-
<Cross color={theme.
|
|
189
|
+
<Cross color={theme.dark.primary} style={theme.icon.xs} />
|
|
167
190
|
</Pressable>
|
|
168
191
|
</View>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
>
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
</Pressable>
|
|
193
|
-
);
|
|
194
|
-
})}
|
|
195
|
-
</View>
|
|
192
|
+
{options.map((option, index) => {
|
|
193
|
+
if (!option) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
const applyBottomPadding =
|
|
197
|
+
index < options.length - 1 ? styles.borderBottom : null;
|
|
198
|
+
|
|
199
|
+
const onPressHandler = () => {
|
|
200
|
+
option?.onPressHandler();
|
|
201
|
+
onCloseParticipantOptions();
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<Pressable
|
|
206
|
+
style={[applyBottomPadding, styles.option]}
|
|
207
|
+
key={option.title}
|
|
208
|
+
onPress={onPressHandler}
|
|
209
|
+
>
|
|
210
|
+
<View style={theme.icon.sm}>{option.icon}</View>
|
|
211
|
+
<Text style={styles.title}>{option.title}</Text>
|
|
212
|
+
</Pressable>
|
|
213
|
+
);
|
|
214
|
+
})}
|
|
196
215
|
</View>
|
|
197
216
|
</View>
|
|
198
217
|
);
|
|
199
218
|
};
|
|
200
219
|
|
|
201
220
|
const styles = StyleSheet.create({
|
|
202
|
-
|
|
203
|
-
width: '100%',
|
|
204
|
-
height: '100%',
|
|
205
|
-
display: 'flex',
|
|
221
|
+
outerContainer: {
|
|
206
222
|
justifyContent: 'center',
|
|
207
|
-
|
|
223
|
+
flex: 1,
|
|
208
224
|
},
|
|
209
|
-
|
|
210
|
-
backgroundColor: theme.
|
|
225
|
+
modalContainer: {
|
|
226
|
+
backgroundColor: theme.dark.bars,
|
|
211
227
|
borderRadius: theme.rounded.md,
|
|
228
|
+
marginHorizontal: theme.margin.xl,
|
|
212
229
|
},
|
|
213
230
|
participantInfo: {
|
|
214
|
-
display: 'flex',
|
|
215
231
|
flexDirection: 'row',
|
|
216
|
-
alignItems: 'center',
|
|
217
232
|
justifyContent: 'space-between',
|
|
233
|
+
alignItems: 'flex-start',
|
|
218
234
|
padding: theme.padding.md,
|
|
219
235
|
},
|
|
220
236
|
userInfo: {
|
|
221
|
-
display: 'flex',
|
|
222
237
|
flexDirection: 'row',
|
|
223
238
|
alignItems: 'center',
|
|
224
239
|
},
|
|
225
240
|
name: {
|
|
226
241
|
marginLeft: theme.margin.sm,
|
|
227
242
|
...theme.fonts.subtitleBold,
|
|
228
|
-
color: theme.
|
|
243
|
+
color: theme.dark.text_high_emphasis,
|
|
229
244
|
},
|
|
230
|
-
svgContainerStyle: {},
|
|
231
|
-
options: {},
|
|
232
245
|
option: {
|
|
233
|
-
paddingHorizontal: theme.padding.
|
|
234
|
-
paddingVertical: theme.padding.
|
|
235
|
-
display: 'flex',
|
|
246
|
+
paddingHorizontal: theme.padding.lg,
|
|
247
|
+
paddingVertical: theme.padding.md,
|
|
236
248
|
flexDirection: 'row',
|
|
237
249
|
alignItems: 'center',
|
|
238
250
|
},
|
|
239
251
|
title: {
|
|
240
252
|
marginLeft: theme.margin.md,
|
|
241
|
-
color: theme.
|
|
253
|
+
color: theme.dark.text_high_emphasis,
|
|
242
254
|
...theme.fonts.subtitle,
|
|
243
255
|
},
|
|
244
256
|
borderBottom: {
|
|
245
|
-
borderBottomColor: theme.
|
|
257
|
+
borderBottomColor: theme.dark.borders,
|
|
246
258
|
borderBottomWidth: 1,
|
|
247
259
|
},
|
|
260
|
+
closePressable: {
|
|
261
|
+
padding: theme.padding.sm,
|
|
262
|
+
borderRadius: theme.rounded.xs,
|
|
263
|
+
backgroundColor: palette.grey800,
|
|
264
|
+
},
|
|
248
265
|
});
|
|
@@ -17,7 +17,7 @@ export const CallParticipantsView = () => {
|
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<View style={styles.container}>
|
|
20
|
-
<LocalVideoView layout={'floating'}
|
|
20
|
+
<LocalVideoView layout={'floating'} />
|
|
21
21
|
<CallParticipantsList participants={remoteParticipants} />
|
|
22
22
|
</View>
|
|
23
23
|
);
|
|
@@ -13,8 +13,9 @@ import { SfuModels } from '@stream-io/video-client';
|
|
|
13
13
|
import { useStreamVideoStoreValue } from '../contexts';
|
|
14
14
|
import { theme } from '../theme';
|
|
15
15
|
import { VideoSlash } from '../icons';
|
|
16
|
-
import { LOCAL_VIDEO_VIEW_STYLE } from '../constants';
|
|
17
16
|
import { A11yComponents } from '../constants/A11yLabels';
|
|
17
|
+
import { Avatar } from './Avatar';
|
|
18
|
+
import { LOCAL_VIDEO_VIEW_STYLE, Z_INDEX } from '../constants';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Props to be passed for the LocalVideoView component.
|
|
@@ -52,7 +53,7 @@ export interface LocalVideoViewProps {
|
|
|
52
53
|
* |||
|
|
53
54
|
*/
|
|
54
55
|
export const LocalVideoView = (props: LocalVideoViewProps) => {
|
|
55
|
-
const { layout = 'floating', zOrder =
|
|
56
|
+
const { layout = 'floating', zOrder = Z_INDEX.IN_MIDDLE } = props;
|
|
56
57
|
const containerStyle =
|
|
57
58
|
layout === 'floating'
|
|
58
59
|
? styles.floatingContainer
|
|
@@ -75,13 +76,22 @@ export const LocalVideoView = (props: LocalVideoViewProps) => {
|
|
|
75
76
|
}),
|
|
76
77
|
).current;
|
|
77
78
|
|
|
78
|
-
if (!localParticipant)
|
|
79
|
+
if (!localParticipant) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
79
82
|
|
|
80
83
|
const isVideoMuted = !localParticipant.publishedTracks.includes(
|
|
81
84
|
SfuModels.TrackType.VIDEO,
|
|
82
85
|
);
|
|
83
86
|
|
|
84
87
|
if (layout === 'fullscreen') {
|
|
88
|
+
if (isVideoMuted) {
|
|
89
|
+
return (
|
|
90
|
+
<View style={styles.avatarContainer}>
|
|
91
|
+
<Avatar participant={localParticipant} />
|
|
92
|
+
</View>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
85
95
|
return (
|
|
86
96
|
<VideoRenderer
|
|
87
97
|
mirror={isCameraOnFrontFacingMode}
|
|
@@ -96,7 +106,8 @@ export const LocalVideoView = (props: LocalVideoViewProps) => {
|
|
|
96
106
|
<Animated.View
|
|
97
107
|
accessibilityLabel={A11yComponents.LOCAL_PARTICIPANT}
|
|
98
108
|
style={{
|
|
99
|
-
|
|
109
|
+
// Needed to make the view is on top and draggable
|
|
110
|
+
zIndex: Z_INDEX.IN_MIDDLE,
|
|
100
111
|
transform: [{ translateX: pan.x }, { translateY: pan.y }],
|
|
101
112
|
}}
|
|
102
113
|
{...panResponder.panHandlers}
|
|
@@ -125,9 +136,9 @@ const styles = StyleSheet.create({
|
|
|
125
136
|
height: LOCAL_VIDEO_VIEW_STYLE.height,
|
|
126
137
|
width: LOCAL_VIDEO_VIEW_STYLE.width,
|
|
127
138
|
right: theme.spacing.lg * 2,
|
|
128
|
-
top: theme.margin.
|
|
139
|
+
top: theme.margin.xl * 2,
|
|
129
140
|
borderRadius: LOCAL_VIDEO_VIEW_STYLE.borderRadius,
|
|
130
|
-
zIndex:
|
|
141
|
+
zIndex: Z_INDEX.IN_MIDDLE,
|
|
131
142
|
overflow: 'hidden',
|
|
132
143
|
backgroundColor: theme.light.disabled,
|
|
133
144
|
justifyContent: 'center',
|
|
@@ -138,4 +149,9 @@ const styles = StyleSheet.create({
|
|
|
138
149
|
justifyContent: 'center',
|
|
139
150
|
alignItems: 'center',
|
|
140
151
|
},
|
|
152
|
+
avatarContainer: {
|
|
153
|
+
flex: 1,
|
|
154
|
+
justifyContent: 'center',
|
|
155
|
+
alignItems: 'center',
|
|
156
|
+
},
|
|
141
157
|
});
|
|
@@ -10,6 +10,7 @@ import { useLocalVideoStream } from '../hooks/useLocalVideoStream';
|
|
|
10
10
|
import { theme } from '../theme';
|
|
11
11
|
import { useCall, useCallCallingState } from '@stream-io/video-react-bindings';
|
|
12
12
|
import { CallingState } from '@stream-io/video-client';
|
|
13
|
+
import { Z_INDEX } from '../constants';
|
|
13
14
|
|
|
14
15
|
export const OutgoingCallView = () => {
|
|
15
16
|
const { isAudioMuted, isVideoMuted, toggleAudioState, toggleVideoState } =
|
|
@@ -92,7 +93,7 @@ const Background = () => {
|
|
|
92
93
|
<View style={styles.background}>
|
|
93
94
|
<VideoRenderer
|
|
94
95
|
mediaStream={localVideoStream}
|
|
95
|
-
zOrder={
|
|
96
|
+
zOrder={Z_INDEX.IN_BACK}
|
|
96
97
|
style={StyleSheet.absoluteFill}
|
|
97
98
|
mirror
|
|
98
99
|
/>
|
|
@@ -102,8 +103,7 @@ const Background = () => {
|
|
|
102
103
|
|
|
103
104
|
const styles = StyleSheet.create({
|
|
104
105
|
container: {
|
|
105
|
-
zIndex:
|
|
106
|
-
display: 'flex',
|
|
106
|
+
zIndex: Z_INDEX.IN_MIDDLE,
|
|
107
107
|
flexDirection: 'column',
|
|
108
108
|
justifyContent: 'space-between',
|
|
109
109
|
paddingVertical: 2 * theme.margin.xl,
|
|
@@ -16,6 +16,7 @@ import { palette } from '../theme/constants';
|
|
|
16
16
|
import { ParticipantReaction } from './ParticipantReaction';
|
|
17
17
|
import { useCall } from '@stream-io/video-react-bindings';
|
|
18
18
|
import { NetworkQualityIndicator } from './NetworkQualityIndicator';
|
|
19
|
+
import { Z_INDEX } from '../constants';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Props to be passed for the ParticipantView component.
|
|
@@ -78,7 +79,9 @@ export const ParticipantView = (props: ParticipantViewProps) => {
|
|
|
78
79
|
* Additionally makes sure that when this view becomes visible again, the layout to subscribe is known
|
|
79
80
|
*/
|
|
80
81
|
useEffect(() => {
|
|
81
|
-
if (!call)
|
|
82
|
+
if (!call) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
82
85
|
if (isVisible) {
|
|
83
86
|
if (participant.viewportVisibilityState !== VisibilityState.VISIBLE) {
|
|
84
87
|
call.state.updateParticipant(participant.sessionId, (p) => ({
|
|
@@ -114,7 +117,9 @@ export const ParticipantView = (props: ParticipantViewProps) => {
|
|
|
114
117
|
useEffect(() => {
|
|
115
118
|
// NOTE: We only want to update the subscription if the pendingVideoLayoutRef is set
|
|
116
119
|
const updateIsNeeded = pendingVideoLayoutRef.current;
|
|
117
|
-
if (!updateIsNeeded || !call || !isPublishingVideoTrack)
|
|
120
|
+
if (!updateIsNeeded || !call || !isPublishingVideoTrack) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
118
123
|
|
|
119
124
|
// NOTE: When the view is not visible, we want to subscribe to audio only.
|
|
120
125
|
// We unsubscribe their video by setting the dimension to undefined
|
|
@@ -216,7 +221,7 @@ export const ParticipantView = (props: ParticipantViewProps) => {
|
|
|
216
221
|
</View>
|
|
217
222
|
{canShowVideo ? (
|
|
218
223
|
<VideoRenderer
|
|
219
|
-
zOrder={
|
|
224
|
+
zOrder={Z_INDEX.IN_BACK}
|
|
220
225
|
mirror={mirror}
|
|
221
226
|
mediaStream={videoStream as MediaStream}
|
|
222
227
|
objectFit={isScreenSharing ? 'contain' : 'cover'}
|
|
@@ -270,7 +275,7 @@ const styles = StyleSheet.create({
|
|
|
270
275
|
},
|
|
271
276
|
topView: {
|
|
272
277
|
alignSelf: 'flex-end',
|
|
273
|
-
zIndex:
|
|
278
|
+
zIndex: Z_INDEX.IN_FRONT,
|
|
274
279
|
},
|
|
275
280
|
videoRenderer: {
|
|
276
281
|
...StyleSheet.absoluteFillObject,
|
package/src/constants/index.ts
CHANGED
package/src/icons/Cross.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Svg, Path, SvgProps } from 'react-native-svg';
|
|
2
3
|
|
|
3
4
|
type Props = {
|
|
4
5
|
color: string;
|
|
5
|
-
}
|
|
6
|
+
} & Pick<SvgProps, 'style'>;
|
|
6
7
|
|
|
7
|
-
export const Cross = ({ color }: Props) => (
|
|
8
|
-
<Svg viewBox="0 0 12 13">
|
|
8
|
+
export const Cross = ({ color, style }: Props) => (
|
|
9
|
+
<Svg viewBox="0 0 12 13" style={style}>
|
|
9
10
|
<Path
|
|
10
11
|
d="M 0.322153 11.8408 C 0.700083 12.2188 1.34168 12.21 1.71083 11.8408 L 5.99989 7.56055 L 10.2802 11.8408 C 10.6493 12.21 11.2909 12.2188 11.6688 11.8408 C 12.0468 11.4629 12.038 10.8213 11.6688 10.4521 L 7.38856 6.16309 L 11.6688 1.88281 C 12.038 1.51367 12.0468 0.87207 11.6688 0.494141 C 11.2909 0.116211 10.6493 0.125 10.2802 0.494141 L 5.99989 4.77441 L 1.71083 0.485352 C 1.34168 0.125 0.700083 0.116211 0.322153 0.494141 C -0.0557764 0.87207 -0.0469874 1.51367 0.322153 1.88281 L 4.60243 6.16309 L 0.322153 10.4521 C -0.0469874 10.8213 -0.0557764 11.4629 0.322153 11.8408 Z"
|
|
11
12
|
fill={color}
|
package/src/icons/index.tsx
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VideoOff = void 0;
|
|
4
|
-
const react_native_svg_1 = require("react-native-svg");
|
|
5
|
-
const VideoOff = ({ color }) => (<react_native_svg_1.Svg viewBox="0 0 24 24" fill={color}>
|
|
6
|
-
<react_native_svg_1.Path fill={color} d="M 22.1126 16.2238 L 19.1546 13.6686 V 8.37994 L 22.1126 5.82471 L 22.1127 5.82476 L 22.1205 5.81781 C 22.4413 5.53481 22.6269 5.49515 22.686 5.49515 C 22.8267 5.49515 22.8809 5.53948 22.9048 5.56519 C 22.9344 5.59687 23 5.69295 23 5.91262 V 16.1359 C 23 16.3556 22.9344 16.4517 22.9048 16.4833 C 22.8809 16.5091 22.8267 16.5534 22.686 16.5534 C 22.634 16.5534 22.4383 16.5111 22.1205 16.2307 L 22.1206 16.2307 L 22.1126 16.2238 Z M 13.4493 18 H 3.28502 C 2.41817 18 1.87542 17.7686 1.55341 17.4618 C 1.23884 17.162 1 16.6616 1 15.835 V 6.23301 C 1 5.4144 1.24841 4.88792 1.58386 4.5637 C 1.92432 4.23463 2.47262 4 3.28502 4 H 13.5266 C 14.3853 4 14.898 4.23821 15.1995 4.54532 C 15.5041 4.85542 15.7343 5.37926 15.7343 6.23301 V 15.767 C 15.7343 16.6029 15.4949 17.126 15.1733 17.4423 C 14.8492 17.7609 14.3088 18 13.4493 18 Z"/>
|
|
7
|
-
<react_native_svg_1.Path fill={color} fillRule="evenodd" clipRule="evenodd" d="M 5.79311 7.27924 C 5.38794 6.90692 4.73102 6.90692 4.32585 7.27924 C 3.92068 7.65156 3.92068 8.25521 4.32585 8.62753 L 6.90766 11 L 4.32586 13.3725 C 3.92069 13.7448 3.92069 14.3484 4.32586 14.7208 C 4.73103 15.0931 5.38795 15.0931 5.79312 14.7208 L 8.37492 12.3483 L 10.9567 14.7208 C 11.3619 15.0931 12.0188 15.0931 12.424 14.7208 C 12.8291 14.3484 12.8291 13.7448 12.424 13.3725 L 9.84217 11 L 12.424 8.62754 C 12.8291 8.25521 12.8291 7.65156 12.424 7.27924 C 12.0188 6.90692 11.3619 6.90692 10.9567 7.27924 L 8.37492 9.65171 L 5.79311 7.27924 Z"/>
|
|
8
|
-
</react_native_svg_1.Svg>);
|
|
9
|
-
exports.VideoOff = VideoOff;
|
|
10
|
-
//# sourceMappingURL=VideoOff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VideoOff.js","sourceRoot":"","sources":["../../../src/icons/VideoOff.tsx"],"names":[],"mappings":";;;AAAA,uDAA6C;AAMtC,MAAM,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAS,EAAE,EAAE,CAAC,CAC5C,CAAC,sBAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CACnC;IAAA,CAAC,uBAAI,CACH,IAAI,CAAC,CAAC,KAAK,CAAC,CACZ,CAAC,CAAC,4zBAA4zB,EAEh0B;IAAA,CAAC,uBAAI,CACH,IAAI,CAAC,CAAC,KAAK,CAAC,CACZ,QAAQ,CAAC,SAAS,CAClB,QAAQ,CAAC,SAAS,CAClB,CAAC,CAAC,uiBAAuiB,EAE7iB;EAAA,EAAE,sBAAG,CAAC,CACP,CAAC;AAbW,QAAA,QAAQ,YAanB"}
|
package/src/icons/VideoOff.tsx
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Svg, Path } from 'react-native-svg';
|
|
2
|
-
|
|
3
|
-
type Props = {
|
|
4
|
-
color: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const VideoOff = ({ color }: Props) => (
|
|
8
|
-
<Svg viewBox="0 0 24 24" fill={color}>
|
|
9
|
-
<Path
|
|
10
|
-
fill={color}
|
|
11
|
-
d="M 22.1126 16.2238 L 19.1546 13.6686 V 8.37994 L 22.1126 5.82471 L 22.1127 5.82476 L 22.1205 5.81781 C 22.4413 5.53481 22.6269 5.49515 22.686 5.49515 C 22.8267 5.49515 22.8809 5.53948 22.9048 5.56519 C 22.9344 5.59687 23 5.69295 23 5.91262 V 16.1359 C 23 16.3556 22.9344 16.4517 22.9048 16.4833 C 22.8809 16.5091 22.8267 16.5534 22.686 16.5534 C 22.634 16.5534 22.4383 16.5111 22.1205 16.2307 L 22.1206 16.2307 L 22.1126 16.2238 Z M 13.4493 18 H 3.28502 C 2.41817 18 1.87542 17.7686 1.55341 17.4618 C 1.23884 17.162 1 16.6616 1 15.835 V 6.23301 C 1 5.4144 1.24841 4.88792 1.58386 4.5637 C 1.92432 4.23463 2.47262 4 3.28502 4 H 13.5266 C 14.3853 4 14.898 4.23821 15.1995 4.54532 C 15.5041 4.85542 15.7343 5.37926 15.7343 6.23301 V 15.767 C 15.7343 16.6029 15.4949 17.126 15.1733 17.4423 C 14.8492 17.7609 14.3088 18 13.4493 18 Z"
|
|
12
|
-
/>
|
|
13
|
-
<Path
|
|
14
|
-
fill={color}
|
|
15
|
-
fillRule="evenodd"
|
|
16
|
-
clipRule="evenodd"
|
|
17
|
-
d="M 5.79311 7.27924 C 5.38794 6.90692 4.73102 6.90692 4.32585 7.27924 C 3.92068 7.65156 3.92068 8.25521 4.32585 8.62753 L 6.90766 11 L 4.32586 13.3725 C 3.92069 13.7448 3.92069 14.3484 4.32586 14.7208 C 4.73103 15.0931 5.38795 15.0931 5.79312 14.7208 L 8.37492 12.3483 L 10.9567 14.7208 C 11.3619 15.0931 12.0188 15.0931 12.424 14.7208 C 12.8291 14.3484 12.8291 13.7448 12.424 13.3725 L 9.84217 11 L 12.424 8.62754 C 12.8291 8.25521 12.8291 7.65156 12.424 7.27924 C 12.0188 6.90692 11.3619 6.90692 10.9567 7.27924 L 8.37492 9.65171 L 5.79311 7.27924 Z"
|
|
18
|
-
/>
|
|
19
|
-
</Svg>
|
|
20
|
-
);
|