@100mslive/react-native-room-kit 1.1.8 → 1.1.9-beta.1

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.
Files changed (215) hide show
  1. package/lib/commonjs/HMSInstanceSetup.js +11 -5
  2. package/lib/commonjs/HMSInstanceSetup.js.map +1 -1
  3. package/lib/commonjs/Icons/AddImage/assets/add-image.png +0 -0
  4. package/lib/commonjs/Icons/AddImage/assets/add-image@2x.png +0 -0
  5. package/lib/commonjs/Icons/AddImage/assets/add-image@3x.png +0 -0
  6. package/lib/commonjs/Icons/AddImage/index.js +33 -0
  7. package/lib/commonjs/Icons/AddImage/index.js.map +1 -0
  8. package/lib/commonjs/Icons/BlurPeople/assets/blur-people.png +0 -0
  9. package/lib/commonjs/Icons/BlurPeople/assets/blur-people@2x.png +0 -0
  10. package/lib/commonjs/Icons/BlurPeople/assets/blur-people@3x.png +0 -0
  11. package/lib/commonjs/Icons/BlurPeople/index.js +33 -0
  12. package/lib/commonjs/Icons/BlurPeople/index.js.map +1 -0
  13. package/lib/commonjs/Icons/CrossCircle/assets/cross-circle-large.png +0 -0
  14. package/lib/commonjs/Icons/CrossCircle/assets/cross-circle-large@2x.png +0 -0
  15. package/lib/commonjs/Icons/CrossCircle/assets/cross-circle-large@3x.png +0 -0
  16. package/lib/commonjs/Icons/CrossCircle/index.js +7 -2
  17. package/lib/commonjs/Icons/CrossCircle/index.js.map +1 -1
  18. package/lib/commonjs/Icons/VirtualBackground/assets/virtual-background.png +0 -0
  19. package/lib/commonjs/Icons/VirtualBackground/assets/virtual-background@2x.png +0 -0
  20. package/lib/commonjs/Icons/VirtualBackground/assets/virtual-background@3x.png +0 -0
  21. package/lib/commonjs/Icons/VirtualBackground/index.js +33 -0
  22. package/lib/commonjs/Icons/VirtualBackground/index.js.map +1 -0
  23. package/lib/commonjs/Icons/index.js +33 -0
  24. package/lib/commonjs/Icons/index.js.map +1 -1
  25. package/lib/commonjs/components/Chat/ChatMessage.js +13 -1
  26. package/lib/commonjs/components/Chat/ChatMessage.js.map +1 -1
  27. package/lib/commonjs/components/HLSDescriptionPane.js +3 -29
  28. package/lib/commonjs/components/HLSDescriptionPane.js.map +1 -1
  29. package/lib/commonjs/components/HMSHLSMessage.js +14 -1
  30. package/lib/commonjs/components/HMSHLSMessage.js.map +1 -1
  31. package/lib/commonjs/components/HMSManageCameraRotation.js +11 -4
  32. package/lib/commonjs/components/HMSManageCameraRotation.js.map +1 -1
  33. package/lib/commonjs/components/HMSManageLocalVideo.js +11 -4
  34. package/lib/commonjs/components/HMSManageLocalVideo.js.map +1 -1
  35. package/lib/commonjs/components/HMSManageVirtualBackground.js +55 -0
  36. package/lib/commonjs/components/HMSManageVirtualBackground.js.map +1 -0
  37. package/lib/commonjs/components/HMSOverlayMessageView.js +14 -1
  38. package/lib/commonjs/components/HMSOverlayMessageView.js.map +1 -1
  39. package/lib/commonjs/components/HMSRoomOptions.js +2 -1
  40. package/lib/commonjs/components/HMSRoomOptions.js.map +1 -1
  41. package/lib/commonjs/components/Preview.js +8 -3
  42. package/lib/commonjs/components/Preview.js.map +1 -1
  43. package/lib/commonjs/components/RoomSettingsModalContent.js +29 -0
  44. package/lib/commonjs/components/RoomSettingsModalContent.js.map +1 -1
  45. package/lib/commonjs/components/VirtualBackgroundBottomSheet.js +52 -0
  46. package/lib/commonjs/components/VirtualBackgroundBottomSheet.js.map +1 -0
  47. package/lib/commonjs/components/VirtualBackgroundModalContent.js +364 -0
  48. package/lib/commonjs/components/VirtualBackgroundModalContent.js.map +1 -0
  49. package/lib/commonjs/modules/imagePickerWrapper.js +19 -0
  50. package/lib/commonjs/modules/imagePickerWrapper.js.map +1 -0
  51. package/lib/commonjs/modules/videoPluginWrapper.js +13 -0
  52. package/lib/commonjs/modules/videoPluginWrapper.js.map +1 -0
  53. package/lib/commonjs/redux/actionTypes.js +3 -0
  54. package/lib/commonjs/redux/actionTypes.js.map +1 -1
  55. package/lib/commonjs/redux/actions/index.js +14 -2
  56. package/lib/commonjs/redux/actions/index.js.map +1 -1
  57. package/lib/commonjs/redux/reducers/appState.js +9 -1
  58. package/lib/commonjs/redux/reducers/appState.js.map +1 -1
  59. package/lib/commonjs/redux/reducers/hmsStates.js +6 -0
  60. package/lib/commonjs/redux/reducers/hmsStates.js.map +1 -1
  61. package/lib/commonjs/utils/functions.js +33 -1
  62. package/lib/commonjs/utils/functions.js.map +1 -1
  63. package/lib/commonjs/utils/types.js +1 -0
  64. package/lib/commonjs/utils/types.js.map +1 -1
  65. package/lib/module/HMSInstanceSetup.js +12 -6
  66. package/lib/module/HMSInstanceSetup.js.map +1 -1
  67. package/lib/module/Icons/AddImage/assets/add-image.png +0 -0
  68. package/lib/module/Icons/AddImage/assets/add-image@2x.png +0 -0
  69. package/lib/module/Icons/AddImage/assets/add-image@3x.png +0 -0
  70. package/lib/module/Icons/AddImage/index.js +25 -0
  71. package/lib/module/Icons/AddImage/index.js.map +1 -0
  72. package/lib/module/Icons/BlurPeople/assets/blur-people.png +0 -0
  73. package/lib/module/Icons/BlurPeople/assets/blur-people@2x.png +0 -0
  74. package/lib/module/Icons/BlurPeople/assets/blur-people@3x.png +0 -0
  75. package/lib/module/Icons/BlurPeople/index.js +25 -0
  76. package/lib/module/Icons/BlurPeople/index.js.map +1 -0
  77. package/lib/module/Icons/CrossCircle/assets/cross-circle-large.png +0 -0
  78. package/lib/module/Icons/CrossCircle/assets/cross-circle-large@2x.png +0 -0
  79. package/lib/module/Icons/CrossCircle/assets/cross-circle-large@3x.png +0 -0
  80. package/lib/module/Icons/CrossCircle/index.js +7 -2
  81. package/lib/module/Icons/CrossCircle/index.js.map +1 -1
  82. package/lib/module/Icons/VirtualBackground/assets/virtual-background.png +0 -0
  83. package/lib/module/Icons/VirtualBackground/assets/virtual-background@2x.png +0 -0
  84. package/lib/module/Icons/VirtualBackground/assets/virtual-background@3x.png +0 -0
  85. package/lib/module/Icons/VirtualBackground/index.js +25 -0
  86. package/lib/module/Icons/VirtualBackground/index.js.map +1 -0
  87. package/lib/module/Icons/index.js +3 -0
  88. package/lib/module/Icons/index.js.map +1 -1
  89. package/lib/module/components/Chat/ChatMessage.js +15 -3
  90. package/lib/module/components/Chat/ChatMessage.js.map +1 -1
  91. package/lib/module/components/HLSDescriptionPane.js +2 -28
  92. package/lib/module/components/HLSDescriptionPane.js.map +1 -1
  93. package/lib/module/components/HMSHLSMessage.js +15 -2
  94. package/lib/module/components/HMSHLSMessage.js.map +1 -1
  95. package/lib/module/components/HMSManageCameraRotation.js +11 -4
  96. package/lib/module/components/HMSManageCameraRotation.js.map +1 -1
  97. package/lib/module/components/HMSManageLocalVideo.js +11 -4
  98. package/lib/module/components/HMSManageLocalVideo.js.map +1 -1
  99. package/lib/module/components/HMSManageVirtualBackground.js +46 -0
  100. package/lib/module/components/HMSManageVirtualBackground.js.map +1 -0
  101. package/lib/module/components/HMSOverlayMessageView.js +15 -2
  102. package/lib/module/components/HMSOverlayMessageView.js.map +1 -1
  103. package/lib/module/components/HMSRoomOptions.js +2 -1
  104. package/lib/module/components/HMSRoomOptions.js.map +1 -1
  105. package/lib/module/components/Preview.js +8 -3
  106. package/lib/module/components/Preview.js.map +1 -1
  107. package/lib/module/components/RoomSettingsModalContent.js +31 -2
  108. package/lib/module/components/RoomSettingsModalContent.js.map +1 -1
  109. package/lib/module/components/VirtualBackgroundBottomSheet.js +43 -0
  110. package/lib/module/components/VirtualBackgroundBottomSheet.js.map +1 -0
  111. package/lib/module/components/VirtualBackgroundModalContent.js +355 -0
  112. package/lib/module/components/VirtualBackgroundModalContent.js.map +1 -0
  113. package/lib/module/modules/imagePickerWrapper.js +14 -0
  114. package/lib/module/modules/imagePickerWrapper.js.map +1 -0
  115. package/lib/module/modules/videoPluginWrapper.js +8 -0
  116. package/lib/module/modules/videoPluginWrapper.js.map +1 -0
  117. package/lib/module/redux/actionTypes.js +3 -0
  118. package/lib/module/redux/actionTypes.js.map +1 -1
  119. package/lib/module/redux/actions/index.js +10 -0
  120. package/lib/module/redux/actions/index.js.map +1 -1
  121. package/lib/module/redux/reducers/appState.js +9 -1
  122. package/lib/module/redux/reducers/appState.js.map +1 -1
  123. package/lib/module/redux/reducers/hmsStates.js +6 -0
  124. package/lib/module/redux/reducers/hmsStates.js.map +1 -1
  125. package/lib/module/utils/functions.js +29 -1
  126. package/lib/module/utils/functions.js.map +1 -1
  127. package/lib/module/utils/types.js +1 -0
  128. package/lib/module/utils/types.js.map +1 -1
  129. package/lib/typescript/HMSInstanceSetup.d.ts.map +1 -1
  130. package/lib/typescript/Icons/AddImage/index.d.ts +7 -0
  131. package/lib/typescript/Icons/AddImage/index.d.ts.map +1 -0
  132. package/lib/typescript/Icons/BlurPeople/index.d.ts +7 -0
  133. package/lib/typescript/Icons/BlurPeople/index.d.ts.map +1 -0
  134. package/lib/typescript/Icons/CrossCircle/index.d.ts +1 -0
  135. package/lib/typescript/Icons/CrossCircle/index.d.ts.map +1 -1
  136. package/lib/typescript/Icons/VirtualBackground/index.d.ts +7 -0
  137. package/lib/typescript/Icons/VirtualBackground/index.d.ts.map +1 -0
  138. package/lib/typescript/Icons/index.d.ts +3 -0
  139. package/lib/typescript/Icons/index.d.ts.map +1 -1
  140. package/lib/typescript/components/Chat/ChatMessage.d.ts.map +1 -1
  141. package/lib/typescript/components/HLSDescriptionPane.d.ts.map +1 -1
  142. package/lib/typescript/components/HMSHLSMessage.d.ts.map +1 -1
  143. package/lib/typescript/components/HMSManageCameraRotation.d.ts +8 -1
  144. package/lib/typescript/components/HMSManageCameraRotation.d.ts.map +1 -1
  145. package/lib/typescript/components/HMSManageLocalVideo.d.ts +8 -1
  146. package/lib/typescript/components/HMSManageLocalVideo.d.ts.map +1 -1
  147. package/lib/typescript/components/HMSManageVirtualBackground.d.ts +8 -0
  148. package/lib/typescript/components/HMSManageVirtualBackground.d.ts.map +1 -0
  149. package/lib/typescript/components/HMSOverlayMessageView.d.ts.map +1 -1
  150. package/lib/typescript/components/HMSRoomOptions.d.ts.map +1 -1
  151. package/lib/typescript/components/Preview.d.ts.map +1 -1
  152. package/lib/typescript/components/RoomSettingsModalContent.d.ts.map +1 -1
  153. package/lib/typescript/components/VirtualBackgroundBottomSheet.d.ts +3 -0
  154. package/lib/typescript/components/VirtualBackgroundBottomSheet.d.ts.map +1 -0
  155. package/lib/typescript/components/VirtualBackgroundModalContent.d.ts +6 -0
  156. package/lib/typescript/components/VirtualBackgroundModalContent.d.ts.map +1 -0
  157. package/lib/typescript/modules/imagePickerWrapper.d.ts +6 -0
  158. package/lib/typescript/modules/imagePickerWrapper.d.ts.map +1 -0
  159. package/lib/typescript/modules/videoPluginWrapper.d.ts +19 -0
  160. package/lib/typescript/modules/videoPluginWrapper.d.ts.map +1 -0
  161. package/lib/typescript/redux/actionTypes.d.ts +2 -0
  162. package/lib/typescript/redux/actionTypes.d.ts.map +1 -1
  163. package/lib/typescript/redux/actions/index.d.ts +11 -0
  164. package/lib/typescript/redux/actions/index.d.ts.map +1 -1
  165. package/lib/typescript/redux/index.d.ts +2 -0
  166. package/lib/typescript/redux/index.d.ts.map +1 -1
  167. package/lib/typescript/redux/reducers/appState.d.ts +1 -0
  168. package/lib/typescript/redux/reducers/appState.d.ts.map +1 -1
  169. package/lib/typescript/redux/reducers/hmsStates.d.ts +7 -1
  170. package/lib/typescript/redux/reducers/hmsStates.d.ts.map +1 -1
  171. package/lib/typescript/redux/reducers/index.d.ts +2 -0
  172. package/lib/typescript/redux/reducers/index.d.ts.map +1 -1
  173. package/lib/typescript/utils/functions.d.ts +2 -0
  174. package/lib/typescript/utils/functions.d.ts.map +1 -1
  175. package/lib/typescript/utils/types.d.ts +1 -0
  176. package/lib/typescript/utils/types.d.ts.map +1 -1
  177. package/package.json +8 -2
  178. package/src/HMSInstanceSetup.tsx +17 -4
  179. package/src/Icons/AddImage/assets/add-image.png +0 -0
  180. package/src/Icons/AddImage/assets/add-image@2x.png +0 -0
  181. package/src/Icons/AddImage/assets/add-image@3x.png +0 -0
  182. package/src/Icons/AddImage/index.tsx +33 -0
  183. package/src/Icons/BlurPeople/assets/blur-people.png +0 -0
  184. package/src/Icons/BlurPeople/assets/blur-people@2x.png +0 -0
  185. package/src/Icons/BlurPeople/assets/blur-people@3x.png +0 -0
  186. package/src/Icons/BlurPeople/index.tsx +33 -0
  187. package/src/Icons/CrossCircle/assets/cross-circle-large.png +0 -0
  188. package/src/Icons/CrossCircle/assets/cross-circle-large@2x.png +0 -0
  189. package/src/Icons/CrossCircle/assets/cross-circle-large@3x.png +0 -0
  190. package/src/Icons/CrossCircle/index.tsx +19 -3
  191. package/src/Icons/VirtualBackground/assets/virtual-background.png +0 -0
  192. package/src/Icons/VirtualBackground/assets/virtual-background@2x.png +0 -0
  193. package/src/Icons/VirtualBackground/assets/virtual-background@3x.png +0 -0
  194. package/src/Icons/VirtualBackground/index.tsx +33 -0
  195. package/src/Icons/index.ts +3 -0
  196. package/src/components/Chat/ChatMessage.tsx +19 -2
  197. package/src/components/HLSDescriptionPane.tsx +2 -33
  198. package/src/components/HMSHLSMessage.tsx +16 -1
  199. package/src/components/HMSManageCameraRotation.tsx +18 -4
  200. package/src/components/HMSManageLocalVideo.tsx +20 -4
  201. package/src/components/HMSManageVirtualBackground.tsx +76 -0
  202. package/src/components/HMSOverlayMessageView.tsx +16 -1
  203. package/src/components/HMSRoomOptions.tsx +3 -0
  204. package/src/components/Preview.tsx +12 -5
  205. package/src/components/RoomSettingsModalContent.tsx +33 -0
  206. package/src/components/VirtualBackgroundBottomSheet.tsx +62 -0
  207. package/src/components/VirtualBackgroundModalContent.tsx +500 -0
  208. package/src/modules/imagePickerWrapper.ts +20 -0
  209. package/src/modules/videoPluginWrapper.ts +32 -0
  210. package/src/redux/actionTypes.ts +4 -0
  211. package/src/redux/actions/index.ts +11 -0
  212. package/src/redux/reducers/appState.ts +8 -0
  213. package/src/redux/reducers/hmsStates.ts +14 -0
  214. package/src/utils/{functions.ts → functions.tsx} +34 -0
  215. package/src/utils/types.ts +1 -0
@@ -0,0 +1,500 @@
1
+ import * as React from 'react';
2
+ import {
3
+ Image,
4
+ Text,
5
+ View,
6
+ ScrollView,
7
+ StyleSheet,
8
+ TouchableOpacity,
9
+ ActivityIndicator,
10
+ } from 'react-native';
11
+ import type { ImageRequireSource } from 'react-native';
12
+ import { useDispatch, useSelector } from 'react-redux';
13
+ import { HMSTrackType, HMSVideoViewMode } from '@100mslive/react-native-hms';
14
+ import type { HMSVirtualBackgroundPlugin } from '../modules/videoPluginWrapper';
15
+ import { ImagePicker } from '../modules/imagePickerWrapper';
16
+
17
+ import { BottomSheet } from './BottomSheet';
18
+ import {
19
+ AddImageIcon,
20
+ BlurPeopleIcon,
21
+ CloseIcon,
22
+ CrossCircleIcon,
23
+ } from '../Icons';
24
+ import {
25
+ useDisableAutoPip,
26
+ useHMSRoomColorPalette,
27
+ useHMSRoomStyleSheet,
28
+ } from '../hooks-util';
29
+ import { VideoView } from './PeerVideoTile/VideoView';
30
+ import type { RootState } from '../redux';
31
+ import {
32
+ setAutoEnterPipMode,
33
+ setSelectedVirtualBackground,
34
+ } from '../redux/actions';
35
+ import { useState } from 'react';
36
+ import { hexToRgbA } from '../utils/theme';
37
+
38
+ export interface VirtualBackgroundModalContentProps {
39
+ dismissModal(): void;
40
+ }
41
+
42
+ export const VirtualBackgroundModalContent: React.FC<
43
+ VirtualBackgroundModalContentProps
44
+ > = ({ dismissModal }) => {
45
+ const dispatch = useDispatch();
46
+ const localPeer = useSelector(
47
+ (state: RootState) => state.hmsStates.localPeer
48
+ );
49
+ const isLocalVideoMuted = useSelector(
50
+ (state: RootState) => state.hmsStates.isLocalVideoMuted
51
+ );
52
+ const autoEnterPipMode = useSelector(
53
+ (state: RootState) => state.app.autoEnterPipMode
54
+ );
55
+ const disableAutoPip = useDisableAutoPip();
56
+
57
+ const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({
58
+ semiBoldSurfaceHigh: {
59
+ color: theme.palette.on_surface_high,
60
+ fontFamily: `${typography.font_family}-SemiBold`,
61
+ },
62
+ regularSurfaceMedium: {
63
+ color: theme.palette.on_surface_medium,
64
+ fontFamily: `${typography.font_family}-Regular`,
65
+ },
66
+ effectButton: {
67
+ backgroundColor: theme.palette.surface_bright,
68
+ },
69
+ active: {
70
+ borderColor: theme.palette.primary_default,
71
+ },
72
+ inactive: {
73
+ borderColor: theme.palette.surface_bright,
74
+ },
75
+ loadingContainer: {
76
+ backgroundColor:
77
+ theme.palette.background_default &&
78
+ hexToRgbA(theme.palette.background_default, 0.5),
79
+ },
80
+ }));
81
+
82
+ const { primary_bright: primaryBrightColor } = useHMSRoomColorPalette();
83
+
84
+ const videoPlugin = useSelector(
85
+ (state: RootState) => state.hmsStates.videoPlugin
86
+ );
87
+ const selectedVirtualBG = useSelector(
88
+ (state: RootState) => state.app.selectedVirtualBackground
89
+ );
90
+
91
+ const handleClosePress = () => dismissModal();
92
+
93
+ const handleNoEffectPress = async () => {
94
+ if (videoPlugin) {
95
+ await videoPlugin.disable();
96
+ dispatch(setSelectedVirtualBackground(null));
97
+ }
98
+ };
99
+
100
+ const [showLoading, setShowLoading] = useState(false);
101
+
102
+ const handlePhotoLibraryPress = async () => {
103
+ if (!ImagePicker) {
104
+ return;
105
+ }
106
+ // Current value of `autoEnterPipMode` state
107
+ let pipModeEnabled = autoEnterPipMode;
108
+ try {
109
+ // If PIP is enabled, disable it
110
+ if (pipModeEnabled) {
111
+ dispatch(setAutoEnterPipMode(false));
112
+ disableAutoPip();
113
+ }
114
+
115
+ const imageLibraryResponse = await ImagePicker.launchImageLibrary({
116
+ mediaType: 'photo',
117
+ selectionLimit: 1,
118
+ });
119
+
120
+ // If PIP was enabled earlier, enable it again
121
+ if (pipModeEnabled) {
122
+ dispatch(setAutoEnterPipMode(true));
123
+ }
124
+ handleImagePickerResponse(imageLibraryResponse);
125
+ } catch (error) {
126
+ console.warn(error);
127
+ }
128
+ };
129
+
130
+ // const handleCameraPress = async () => {
131
+ // if (!ImagePicker) {
132
+ // return;
133
+ // }
134
+ // try {
135
+ // const cameraResponse = await ImagePicker.launchCamera({
136
+ // mediaType: 'photo',
137
+ // cameraType: 'back',
138
+ // });
139
+ // handleImagePickerResponse(cameraResponse);
140
+ // } catch (error) {
141
+ // console.warn(error);
142
+ // }
143
+ // };
144
+
145
+ const handleImagePickerResponse = (response: any) => {
146
+ if (response.didCancel) {
147
+ throw new Error('User cancelled');
148
+ }
149
+ if (response.errorCode !== undefined) {
150
+ throw new Error(response.errorCode, {
151
+ cause: response.errorMessage,
152
+ });
153
+ }
154
+ const firstAsset = response.assets?.[0];
155
+ if (firstAsset && firstAsset.uri && firstAsset.fileName) {
156
+ handleImagePress({ label: firstAsset.fileName, src: firstAsset });
157
+ }
158
+ };
159
+
160
+ const handleBlurEffectPress = async () => {
161
+ try {
162
+ if (videoPlugin) {
163
+ setShowLoading(true);
164
+ if (selectedVirtualBG === null) {
165
+ await videoPlugin.enable();
166
+ }
167
+ await videoPlugin.setBlur(100);
168
+ setShowLoading(false);
169
+ dispatch(setSelectedVirtualBackground('blur'));
170
+ }
171
+ } catch (error) {
172
+ setShowLoading(false);
173
+ console.error('Error setting blur effect', error);
174
+ }
175
+ };
176
+
177
+ const handleImagePress = async (asset: {
178
+ label: string;
179
+ src: Parameters<HMSVirtualBackgroundPlugin['setBackground']>[0];
180
+ }) => {
181
+ try {
182
+ if (videoPlugin) {
183
+ setShowLoading(true);
184
+ if (selectedVirtualBG === null) {
185
+ await videoPlugin.enable();
186
+ }
187
+ await videoPlugin.setBackground(asset.src);
188
+ setShowLoading(false);
189
+ dispatch(setSelectedVirtualBackground(asset.label));
190
+ }
191
+ } catch (error) {
192
+ setShowLoading(false);
193
+ console.error('Error setting virtual background', error);
194
+ }
195
+ };
196
+
197
+ const showingVideoTrack =
198
+ localPeer &&
199
+ localPeer.videoTrack &&
200
+ localPeer.videoTrack.trackId &&
201
+ localPeer.videoTrack.type === HMSTrackType.VIDEO &&
202
+ !isLocalVideoMuted;
203
+
204
+ const backgrounds: Array<
205
+ | {
206
+ icon: React.JSX.Element;
207
+ onPress: () => Promise<void>;
208
+ label: string;
209
+ src?: undefined;
210
+ }
211
+ | {
212
+ icon?: undefined;
213
+ onPress?: undefined;
214
+ label: string;
215
+ src: ImageRequireSource;
216
+ }
217
+ > = [];
218
+
219
+ if (ImagePicker) {
220
+ // backgrounds.push({
221
+ // label: 'Camera',
222
+ // onPress: handleCameraPress,
223
+ // });
224
+ backgrounds.push({
225
+ icon: <AddImageIcon />,
226
+ label: 'Upload',
227
+ onPress: handlePhotoLibraryPress,
228
+ });
229
+ }
230
+
231
+ return (
232
+ <View style={styles.flexView}>
233
+ {/* Header */}
234
+ <View style={styles.header}>
235
+ <Text style={[styles.headerText, hmsRoomStyles.semiBoldSurfaceHigh]}>
236
+ Virtual Background
237
+ </Text>
238
+
239
+ <TouchableOpacity
240
+ onPress={handleClosePress}
241
+ hitSlop={styles.closeIconHitSlop}
242
+ style={styles.closeIconButton}
243
+ >
244
+ <CloseIcon />
245
+ </TouchableOpacity>
246
+ </View>
247
+
248
+ {/* Divider */}
249
+ <BottomSheet.Divider style={styles.divider} />
250
+
251
+ {/* Content */}
252
+ <View style={styles.flexView}>
253
+ {showingVideoTrack ? (
254
+ <View style={{ height: 280, alignItems: 'center', marginTop: 32 }}>
255
+ <View style={{ width: 166, height: 280 }}>
256
+ <VideoView
257
+ peer={localPeer}
258
+ trackId={localPeer.videoTrack.trackId}
259
+ scaleType={HMSVideoViewMode.ASPECT_FILL}
260
+ />
261
+ </View>
262
+ </View>
263
+ ) : null}
264
+
265
+ <ScrollView
266
+ style={styles.scrollView}
267
+ contentContainerStyle={styles.scrollContent}
268
+ >
269
+ <View style={{ marginHorizontal: 24 }}>
270
+ <Text
271
+ style={[hmsRoomStyles.semiBoldSurfaceHigh, styles.normalText]}
272
+ >
273
+ Effects
274
+ </Text>
275
+
276
+ <View style={{ flexDirection: 'row' }}>
277
+ <TouchableOpacity
278
+ activeOpacity={0.8}
279
+ onPress={handleNoEffectPress}
280
+ >
281
+ <View
282
+ style={[
283
+ styles.effectButton,
284
+ hmsRoomStyles.effectButton,
285
+ selectedVirtualBG === null
286
+ ? hmsRoomStyles.active
287
+ : hmsRoomStyles.inactive,
288
+ ]}
289
+ >
290
+ <CrossCircleIcon size="large" style={{ marginBottom: 8 }} />
291
+ <Text
292
+ style={[
293
+ styles.smallText,
294
+ hmsRoomStyles.regularSurfaceMedium,
295
+ ]}
296
+ >
297
+ No Effect
298
+ </Text>
299
+ </View>
300
+ </TouchableOpacity>
301
+
302
+ <TouchableOpacity
303
+ activeOpacity={0.8}
304
+ style={styles.horizontalSpacing}
305
+ onPress={handleBlurEffectPress}
306
+ >
307
+ <View
308
+ style={[
309
+ styles.effectButton,
310
+ hmsRoomStyles.effectButton,
311
+ selectedVirtualBG === 'blur'
312
+ ? hmsRoomStyles.active
313
+ : hmsRoomStyles.inactive,
314
+ ]}
315
+ >
316
+ <BlurPeopleIcon style={{ marginBottom: 8 }} />
317
+ <Text
318
+ style={[
319
+ styles.smallText,
320
+ hmsRoomStyles.regularSurfaceMedium,
321
+ ]}
322
+ >
323
+ Blur
324
+ </Text>
325
+ </View>
326
+ </TouchableOpacity>
327
+ </View>
328
+
329
+ {/* Blur radius slider here */}
330
+ </View>
331
+
332
+ {backgrounds && backgrounds.length > 0 ? (
333
+ <View style={styles.backgroundContainer}>
334
+ <Text
335
+ style={[
336
+ hmsRoomStyles.semiBoldSurfaceHigh,
337
+ styles.normalText,
338
+ { marginHorizontal: 24 },
339
+ ]}
340
+ >
341
+ Backgrounds
342
+ </Text>
343
+
344
+ <View style={[styles.backgroundImages, { marginHorizontal: 18 }]}>
345
+ {backgrounds.map((asset) => {
346
+ return (
347
+ <TouchableOpacity
348
+ key={asset.label}
349
+ activeOpacity={0.8}
350
+ onPress={() => {
351
+ const src = asset.src;
352
+ if (src) {
353
+ handleImagePress({ label: asset.label, src });
354
+ } else if (asset.onPress) {
355
+ asset.onPress();
356
+ }
357
+ }}
358
+ style={
359
+ asset.src
360
+ ? styles.backgroundImageContainer
361
+ : [
362
+ styles.effectButton,
363
+ hmsRoomStyles.effectButton,
364
+ hmsRoomStyles.inactive,
365
+ styles.backgroundImageContainer,
366
+ ]
367
+ }
368
+ >
369
+ {asset.src ? (
370
+ <Image
371
+ source={asset.src}
372
+ style={[
373
+ styles.backgroundImage,
374
+ selectedVirtualBG === asset.label
375
+ ? hmsRoomStyles.active
376
+ : null,
377
+ ]}
378
+ />
379
+ ) : (
380
+ <>
381
+ {asset.icon || null}
382
+ <Text
383
+ style={[
384
+ styles.smallText,
385
+ hmsRoomStyles.regularSurfaceMedium,
386
+ ]}
387
+ >
388
+ {asset.label}
389
+ </Text>
390
+ </>
391
+ )}
392
+ </TouchableOpacity>
393
+ );
394
+ })}
395
+ </View>
396
+ </View>
397
+ ) : null}
398
+ </ScrollView>
399
+
400
+ {showLoading && (
401
+ <View
402
+ style={[styles.loadingContainer, hmsRoomStyles.loadingContainer]}
403
+ >
404
+ <ActivityIndicator size="large" color={primaryBrightColor} />
405
+ </View>
406
+ )}
407
+ </View>
408
+ </View>
409
+ );
410
+ };
411
+
412
+ const styles = StyleSheet.create({
413
+ // Header
414
+ header: {
415
+ flexDirection: 'row',
416
+ alignItems: 'center',
417
+ justifyContent: 'space-between',
418
+ marginTop: 16,
419
+ marginHorizontal: 24,
420
+ },
421
+ headerText: {
422
+ fontSize: 16,
423
+ lineHeight: 24,
424
+ letterSpacing: 0.15,
425
+ },
426
+ closeIconButton: {
427
+ marginLeft: 16,
428
+ },
429
+ closeIconHitSlop: {
430
+ bottom: 16,
431
+ left: 16,
432
+ right: 16,
433
+ top: 16,
434
+ },
435
+ // Divider
436
+ divider: {
437
+ marginVertical: 0,
438
+ marginTop: 16,
439
+ },
440
+ // Content
441
+ flexView: {
442
+ flex: 1,
443
+ position: 'relative',
444
+ },
445
+ scrollView: {
446
+ marginTop: 16,
447
+ },
448
+ scrollContent: {
449
+ paddingTop: 8,
450
+ paddingBottom: 24,
451
+ },
452
+ normalText: {
453
+ fontSize: 14,
454
+ lineHeight: 20,
455
+ marginBottom: 8,
456
+ },
457
+ smallText: {
458
+ fontSize: 12,
459
+ lineHeight: 16,
460
+ letterSpacing: 0.4,
461
+ },
462
+ effectButton: {
463
+ width: 104,
464
+ height: 88,
465
+ borderRadius: 8,
466
+ alignItems: 'center',
467
+ justifyContent: 'center',
468
+ borderWidth: 2,
469
+ },
470
+ horizontalSpacing: {
471
+ marginHorizontal: 12,
472
+ },
473
+ backgroundContainer: {
474
+ marginTop: 24,
475
+ },
476
+ backgroundImages: {
477
+ flex: 1,
478
+ flexDirection: 'row',
479
+ flexWrap: 'wrap',
480
+ },
481
+ backgroundImage: {
482
+ width: 104,
483
+ height: 88,
484
+ borderRadius: 8,
485
+ resizeMode: 'cover',
486
+ borderWidth: 2,
487
+ borderColor: 'transparent',
488
+ },
489
+ backgroundImageContainer: {
490
+ marginHorizontal: 6,
491
+ marginVertical: 8,
492
+ },
493
+ loadingContainer: {
494
+ width: '100%',
495
+ height: '100%',
496
+ position: 'absolute',
497
+ alignItems: 'center',
498
+ justifyContent: 'center',
499
+ },
500
+ });
@@ -0,0 +1,20 @@
1
+ let ImagePicker:
2
+ | {
3
+ launchCamera: (options: Record<string, any>) => Promise<any>;
4
+ launchImageLibrary: (options: Record<string, any>) => Promise<any>;
5
+ }
6
+ | undefined;
7
+
8
+ try {
9
+ ImagePicker = require('react-native-image-picker');
10
+ } catch (error) {
11
+ ImagePicker = undefined;
12
+ }
13
+
14
+ if (!ImagePicker?.launchCamera || !ImagePicker?.launchImageLibrary) {
15
+ // Make sure the loaded module is actually `react-native-image-picker`, if it's not
16
+ // reset the module to undefined so we can fallback to the default implementation
17
+ ImagePicker = undefined;
18
+ }
19
+
20
+ export { ImagePicker };
@@ -0,0 +1,32 @@
1
+ import type { ImageRequireSource, ImageURISource } from 'react-native';
2
+
3
+ export declare class HMSVideoPlugin {
4
+ protected type: string;
5
+ constructor(pluginType: string);
6
+ protected get nativeModule(): any;
7
+ enable(): Promise<boolean>;
8
+ disable(): Promise<boolean>;
9
+ }
10
+
11
+ export declare class HMSVirtualBackgroundPlugin extends HMSVideoPlugin {
12
+ static NAME: string;
13
+ constructor();
14
+ setBlur(blurRadius: number): Promise<boolean>;
15
+ setBackground(
16
+ backgroundImage: ImageURISource | ImageRequireSource
17
+ ): Promise<boolean>;
18
+ }
19
+
20
+ let VideoPlugin:
21
+ | {
22
+ HMSVirtualBackgroundPlugin: typeof HMSVirtualBackgroundPlugin;
23
+ }
24
+ | undefined;
25
+
26
+ try {
27
+ VideoPlugin = require('@100mslive/react-native-video-plugin');
28
+ } catch (error) {
29
+ VideoPlugin = undefined;
30
+ }
31
+
32
+ export { VideoPlugin };
@@ -117,6 +117,8 @@ const SET_HLS_FULL_SCREEN = 'SET_HLS_FULL_SCREEN';
117
117
 
118
118
  const SET_ANDROID_HLS_STREAM_PAUSED = 'SET_ANDROID_HLS_STREAM_PAUSED';
119
119
 
120
+ const SET_SELECTED_VIRTUAL_BG = 'SET_SELECTED_VIRTUAL_BG';
121
+
120
122
  const FILTER_OUT_BLOCKED_MSGS = 'FILTER_OUT_BLOCKED_MSGS';
121
123
 
122
124
  export default {
@@ -170,6 +172,7 @@ export default {
170
172
  SET_HLS_DESC_PANE_VISIBLE,
171
173
  SET_HLS_FULL_SCREEN,
172
174
  SET_ANDROID_HLS_STREAM_PAUSED,
175
+ SET_SELECTED_VIRTUAL_BG,
173
176
  FILTER_OUT_BLOCKED_MSGS,
174
177
  };
175
178
 
@@ -198,6 +201,7 @@ export enum HmsStateActionTypes {
198
201
  SET_ACTIVE_SPEAKERS = 'SET_ACTIVE_SPEAKERS',
199
202
  SET_RECONNECTING = 'SET_RECONNECTING',
200
203
  SET_NOISE_CANCELLATION_PLUGIN = 'SET_NOISE_CANCELLATION_PLUGIN',
204
+ SET_VIDEO_PLUGIN = 'SET_VIDEO_PLUGIN',
201
205
  SET_WHITEBOARD = 'SET_WHITEBOARD',
202
206
  SET_INITIAL_ROLE = 'SET_INITIAL_ROLE',
203
207
  }
@@ -16,6 +16,7 @@ import type {
16
16
  HMSSpeaker,
17
17
  HMSWhiteboard,
18
18
  } from '@100mslive/react-native-hms';
19
+ import type { HMSVirtualBackgroundPlugin } from '../../modules/videoPluginWrapper';
19
20
  import type { Layout } from '@100mslive/types-prebuilt';
20
21
 
21
22
  import type {
@@ -445,6 +446,11 @@ export const setNoiseCancellationPlugin = (
445
446
  noiseCancellationPlugin,
446
447
  });
447
448
 
449
+ export const setVideoPlugin = (videoPlugin: HMSVirtualBackgroundPlugin) => ({
450
+ type: HmsStateActionTypes.SET_VIDEO_PLUGIN,
451
+ videoPlugin,
452
+ });
453
+
448
454
  export const setWhiteboard = (whiteboard: HMSWhiteboard | null) => ({
449
455
  type: HmsStateActionTypes.SET_WHITEBOARD,
450
456
  whiteboard,
@@ -502,6 +508,11 @@ export const setAndroidHLSStreamPaused = (paused: boolean) => ({
502
508
  payload: { hlsStreamPaused_android: paused },
503
509
  });
504
510
 
511
+ export const setSelectedVirtualBackground = (vb: string | null) => ({
512
+ type: actionTypes.SET_SELECTED_VIRTUAL_BG,
513
+ payload: { selectedVirtualBackground: vb },
514
+ });
515
+
505
516
  /**
506
517
  * POLLS
507
518
  */
@@ -66,6 +66,7 @@ type IntialStateType = {
66
66
  hlsDescriptionPaneVisible: boolean;
67
67
  hlsFullScreen: boolean;
68
68
  hlsStreamPaused_android: boolean;
69
+ selectedVirtualBackground: string | null;
69
70
  };
70
71
 
71
72
  const INITIAL_STATE: IntialStateType = {
@@ -107,6 +108,7 @@ const INITIAL_STATE: IntialStateType = {
107
108
  hlsDescriptionPaneVisible: false,
108
109
  hlsFullScreen: false,
109
110
  hlsStreamPaused_android: false,
111
+ selectedVirtualBackground: null,
110
112
  };
111
113
 
112
114
  const appReducer = (
@@ -389,6 +391,12 @@ const appReducer = (
389
391
  hlsStreamPaused_android: action.payload.hlsStreamPaused_android,
390
392
  };
391
393
  }
394
+ case ActionTypes.SET_SELECTED_VIRTUAL_BG: {
395
+ return {
396
+ ...state,
397
+ selectedVirtualBackground: action.payload.selectedVirtualBackground,
398
+ };
399
+ }
392
400
  case HmsStateActionTypes.CLEAR_STATES:
393
401
  return INITIAL_STATE;
394
402
  default:
@@ -8,6 +8,7 @@ import type {
8
8
  HMSSpeaker,
9
9
  HMSWhiteboard,
10
10
  } from '@100mslive/react-native-hms';
11
+ import type { HMSVirtualBackgroundPlugin } from '../../modules/videoPluginWrapper';
11
12
  import type { Layout } from '@100mslive/types-prebuilt';
12
13
  import { HmsStateActionTypes } from '../actionTypes';
13
14
 
@@ -33,6 +34,7 @@ type ActionType =
33
34
  | SetActiveSpeakers
34
35
  | SetReconnecting
35
36
  | SetNoiseCancellationPlugin
37
+ | SetVideoPlugin
36
38
  | SetWhiteboard;
37
39
 
38
40
  type SetRoomAction = {
@@ -140,6 +142,11 @@ type SetNoiseCancellationPlugin = {
140
142
  noiseCancellationPlugin: HMSNoiseCancellationPlugin;
141
143
  };
142
144
 
145
+ type SetVideoPlugin = {
146
+ type: HmsStateActionTypes.SET_VIDEO_PLUGIN;
147
+ videoPlugin: HMSVirtualBackgroundPlugin;
148
+ };
149
+
143
150
  type SetWhiteboard = {
144
151
  type: HmsStateActionTypes.SET_WHITEBOARD;
145
152
  whiteboard: HMSWhiteboard | null;
@@ -160,6 +167,7 @@ type IntialStateType = {
160
167
  layoutConfig: Layout[] | null;
161
168
  roleChangeRequest: HMSRoleChangeRequest | null;
162
169
  noiseCancellationPlugin: HMSNoiseCancellationPlugin | null;
170
+ videoPlugin: HMSVirtualBackgroundPlugin | null;
163
171
  whiteboard: HMSWhiteboard | null;
164
172
  };
165
173
 
@@ -178,6 +186,7 @@ const INITIAL_STATE: IntialStateType = {
178
186
  layoutConfig: null,
179
187
  roleChangeRequest: null,
180
188
  noiseCancellationPlugin: null,
189
+ videoPlugin: null,
181
190
  whiteboard: null,
182
191
  };
183
192
 
@@ -580,6 +589,11 @@ const hmsStatesReducer = (
580
589
  ...state,
581
590
  noiseCancellationPlugin: action.noiseCancellationPlugin,
582
591
  };
592
+ case HmsStateActionTypes.SET_VIDEO_PLUGIN:
593
+ return {
594
+ ...state,
595
+ videoPlugin: action.videoPlugin,
596
+ };
583
597
  case HmsStateActionTypes.SET_WHITEBOARD:
584
598
  return {
585
599
  ...state,