@100mslive/react-native-room-kit 1.2.1 → 1.2.2

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 (63) hide show
  1. package/README.md +5 -4
  2. package/lib/commonjs/HMSInstanceSetup.js +2 -1
  3. package/lib/commonjs/HMSInstanceSetup.js.map +1 -1
  4. package/lib/commonjs/HMSRoomSetup.js +31 -1
  5. package/lib/commonjs/HMSRoomSetup.js.map +1 -1
  6. package/lib/commonjs/components/HMSManageNoiseCancellation.js +11 -0
  7. package/lib/commonjs/components/HMSManageNoiseCancellation.js.map +1 -1
  8. package/lib/commonjs/components/MeetingScreenContent.js +11 -0
  9. package/lib/commonjs/components/MeetingScreenContent.js.map +1 -1
  10. package/lib/commonjs/components/Modals.js +45 -24
  11. package/lib/commonjs/components/Modals.js.map +1 -1
  12. package/lib/commonjs/components/Participants/ParticipantsItemOptions.js +26 -0
  13. package/lib/commonjs/components/Participants/ParticipantsItemOptions.js.map +1 -1
  14. package/lib/commonjs/components/PeerSettingsModalContent.js +13 -1
  15. package/lib/commonjs/components/PeerSettingsModalContent.js.map +1 -1
  16. package/lib/commonjs/components/RoomSettingsModalContent.js +1 -1
  17. package/lib/commonjs/components/styles.js +1 -0
  18. package/lib/commonjs/components/styles.js.map +1 -1
  19. package/lib/commonjs/hooks-util.js +25 -15
  20. package/lib/commonjs/hooks-util.js.map +1 -1
  21. package/lib/commonjs/utils.js +2 -2
  22. package/lib/module/HMSInstanceSetup.js +2 -1
  23. package/lib/module/HMSInstanceSetup.js.map +1 -1
  24. package/lib/module/HMSRoomSetup.js +32 -2
  25. package/lib/module/HMSRoomSetup.js.map +1 -1
  26. package/lib/module/components/HMSManageNoiseCancellation.js +11 -0
  27. package/lib/module/components/HMSManageNoiseCancellation.js.map +1 -1
  28. package/lib/module/components/MeetingScreenContent.js +12 -1
  29. package/lib/module/components/MeetingScreenContent.js.map +1 -1
  30. package/lib/module/components/Modals.js +47 -25
  31. package/lib/module/components/Modals.js.map +1 -1
  32. package/lib/module/components/Participants/ParticipantsItemOptions.js +28 -2
  33. package/lib/module/components/Participants/ParticipantsItemOptions.js.map +1 -1
  34. package/lib/module/components/PeerSettingsModalContent.js +14 -2
  35. package/lib/module/components/PeerSettingsModalContent.js.map +1 -1
  36. package/lib/module/components/RoomSettingsModalContent.js +1 -1
  37. package/lib/module/components/styles.js +1 -0
  38. package/lib/module/components/styles.js.map +1 -1
  39. package/lib/module/hooks-util.js +25 -15
  40. package/lib/module/hooks-util.js.map +1 -1
  41. package/lib/module/utils.js +2 -2
  42. package/lib/typescript/HMSInstanceSetup.d.ts.map +1 -1
  43. package/lib/typescript/HMSRoomSetup.d.ts.map +1 -1
  44. package/lib/typescript/components/HMSManageNoiseCancellation.d.ts.map +1 -1
  45. package/lib/typescript/components/MeetingScreenContent.d.ts.map +1 -1
  46. package/lib/typescript/components/Modals.d.ts.map +1 -1
  47. package/lib/typescript/components/Participants/ParticipantsItemOptions.d.ts.map +1 -1
  48. package/lib/typescript/components/PeerSettingsModalContent.d.ts.map +1 -1
  49. package/lib/typescript/components/styles.d.ts +1 -0
  50. package/lib/typescript/components/styles.d.ts.map +1 -1
  51. package/lib/typescript/hooks-util.d.ts.map +1 -1
  52. package/package.json +3 -3
  53. package/src/HMSInstanceSetup.tsx +2 -1
  54. package/src/HMSRoomSetup.tsx +49 -2
  55. package/src/components/HMSManageNoiseCancellation.tsx +15 -0
  56. package/src/components/MeetingScreenContent.tsx +21 -1
  57. package/src/components/Modals.tsx +56 -31
  58. package/src/components/Participants/ParticipantsItemOptions.tsx +28 -1
  59. package/src/components/PeerSettingsModalContent.tsx +17 -1
  60. package/src/components/RoomSettingsModalContent.tsx +1 -1
  61. package/src/components/styles.ts +1 -0
  62. package/src/hooks-util.ts +34 -17
  63. package/src/utils.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@100mslive/react-native-room-kit",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -127,7 +127,7 @@
127
127
  "registry": "https://registry.npmjs.org/"
128
128
  },
129
129
  "dependencies": {
130
- "@100mslive/types-prebuilt": "^0.12.8",
130
+ "@100mslive/types-prebuilt": "^0.12.9",
131
131
  "@react-navigation/native": "^6.0.8",
132
132
  "react-redux": "^7.2.4",
133
133
  "redux": "^4.1.0"
@@ -157,7 +157,7 @@
157
157
  "typescript": "^5.0.2"
158
158
  },
159
159
  "peerDependencies": {
160
- "@100mslive/react-native-hms": "1.10.8",
160
+ "@100mslive/react-native-hms": "1.10.9",
161
161
  "@react-native-community/blur": "^4.3.2",
162
162
  "@react-native-masked-view/masked-view": "^0.2.9",
163
163
  "@shopify/flash-list": "^1.4.3",
@@ -75,7 +75,7 @@ const getTrackSettings = (
75
75
  ? HMSTrackSettingsInitState.MUTED
76
76
  : HMSTrackSettingsInitState.UNMUTED,
77
77
  cameraFacing: HMSCameraFacing.FRONT,
78
- disableAutoResize: !joinConfig.autoResize,
78
+ disableAutoResize: joinConfig.autoResize,
79
79
  forceSoftwareDecoder: joinConfig.softwareDecoder,
80
80
  videoPlugin: videoPlugin || undefined,
81
81
  });
@@ -141,6 +141,7 @@ const getHmsInstance = async (
141
141
  const hmsInstance = await HMSSDK.build({
142
142
  logSettings,
143
143
  trackSettings,
144
+ haltPreviewJoinForPermissionsRequestOnAndroid: true,
144
145
  appGroup,
145
146
  preferredExtension,
146
147
  isPrebuilt: true,
@@ -7,7 +7,16 @@ import {
7
7
  HMSWhiteboardUpdateType,
8
8
  } from '@100mslive/react-native-hms';
9
9
  import React, { useCallback, useEffect, useRef, useState } from 'react';
10
- import { Alert, Keyboard, StatusBar, StyleSheet, View } from 'react-native';
10
+ import {
11
+ Alert,
12
+ Keyboard,
13
+ PermissionsAndroid,
14
+ Platform,
15
+ StatusBar,
16
+ StyleSheet,
17
+ View,
18
+ } from 'react-native';
19
+ import type { Permission } from 'react-native';
11
20
  import Toast from 'react-native-simple-toast';
12
21
  import { batch, useDispatch, useSelector, useStore } from 'react-redux';
13
22
 
@@ -366,6 +375,44 @@ export const HMSRoomSetup = () => {
366
375
  };
367
376
  }, [startHLSStreaming, hmsInstance]);
368
377
 
378
+ if (Platform.OS === 'android') {
379
+ /**
380
+ * Sets up a listener for permissions requests on Android devices.
381
+ *
382
+ * This listener is activated when the HMS SDK requests permissions, such as camera or microphone access.
383
+ * It uses the `PermissionsAndroid` API to request these permissions from the user asynchronously.
384
+ * Upon receiving the permissions, it notifies the HMS SDK that the permissions have been accepted,
385
+ * allowing the SDK to proceed with operations that require these permissions.
386
+ *
387
+ * Note: This listener is only set up and functional on Android devices, as indicated by the `Platform.OS` check.
388
+ */
389
+ useEffect(() => {
390
+ const onPermissionsRequested = async ({
391
+ permissions,
392
+ }: {
393
+ permissions: Array<string>;
394
+ }) => {
395
+ // Requests multiple permissions using the PermissionsAndroid API.
396
+ await PermissionsAndroid.requestMultiple(permissions as Permission[]);
397
+ // Notifies the HMS SDK that the permissions have been accepted.
398
+ await hmsInstance.setPermissionsAcceptedOnAndroid();
399
+ };
400
+
401
+ // Adds the permissions requested listener to the HMS SDK.
402
+ hmsInstance.addEventListener(
403
+ HMSUpdateListenerActions.ON_PERMISSIONS_REQUESTED,
404
+ onPermissionsRequested
405
+ );
406
+
407
+ // Cleanup function to remove the listener when the component unmounts or dependencies change.
408
+ return () => {
409
+ hmsInstance.removeEventListener(
410
+ HMSUpdateListenerActions.ON_PERMISSIONS_REQUESTED
411
+ );
412
+ };
413
+ }, [hmsInstance]);
414
+ }
415
+
369
416
  // HMS Active Speaker Listener
370
417
  // dev-note: This is added here because we have `setPeerTrackNodes` here
371
418
  useHMSActiveSpeakerUpdates(setPeerTrackNodes, meetingJoined);
@@ -452,7 +499,7 @@ export const HMSRoomSetup = () => {
452
499
  // Show notification only if poll is started 20 or more seconds ago
453
500
  if (
454
501
  poll.startedAt &&
455
- Date.now() - poll.startedAt.getTime() >= 20_000
502
+ Date.now() - poll.startedAt.getTime() >= 20000
456
503
  ) {
457
504
  dispatch(
458
505
  addNotification({
@@ -4,6 +4,7 @@ import { PressableIcon } from './PressableIcon';
4
4
  import { styles } from './styles';
5
5
  import { useSelector } from 'react-redux';
6
6
  import type { RootState } from '../redux';
7
+ import { useHMSLayoutConfig } from '../hooks-util';
7
8
 
8
9
  export const HMSManageNoiseCancellation = () => {
9
10
  const noiseCancellationPlugin = useSelector(
@@ -12,6 +13,20 @@ export const HMSManageNoiseCancellation = () => {
12
13
  const [isNoiseCancellationEnabled, setIsNoiseCancellationEnabled] =
13
14
  React.useState(false);
14
15
 
16
+ const enabledByDefault = useHMSLayoutConfig((layoutConfig) => {
17
+ return (
18
+ layoutConfig?.screens?.preview?.default?.elements?.noise_cancellation
19
+ ?.enabled_by_default || false
20
+ );
21
+ });
22
+
23
+ React.useEffect(() => {
24
+ if (enabledByDefault) {
25
+ noiseCancellationPlugin?.enable();
26
+ setIsNoiseCancellationEnabled(true);
27
+ }
28
+ }, []);
29
+
15
30
  const handleButtonPress = async () => {
16
31
  const isAvailable =
17
32
  await noiseCancellationPlugin?.isNoiseCancellationAvailable();
@@ -17,7 +17,7 @@ import type { RootState } from '../redux';
17
17
  import { Footer } from './Footer';
18
18
  import { DisplayView } from './DisplayView';
19
19
  import { Header } from './Header';
20
- import { useKeyboardState } from '../hooks-util';
20
+ import { useHMSLayoutConfig, useKeyboardState } from '../hooks-util';
21
21
  import { HMSStatusBar } from './StatusBar';
22
22
  import { AnimatedFooter } from './AnimatedFooter';
23
23
  import { AnimatedHeader } from './AnimatedHeader';
@@ -138,6 +138,26 @@ export const MeetingScreenContent: React.FC<MeetingScreenContentProps> = ({
138
138
  .onEnd(() => toggleControls())
139
139
  .requireExternalGestureToFail();
140
140
 
141
+ const enabledByDefault = useHMSLayoutConfig((layoutConfig) => {
142
+ return (
143
+ layoutConfig?.screens?.preview?.default?.elements?.noise_cancellation
144
+ ?.enabled_by_default || false
145
+ );
146
+ });
147
+
148
+ const shouldEnableNoiseCancellation =
149
+ Platform.OS === 'ios' && enabledByDefault;
150
+
151
+ const noiseCancellationPlugin = useSelector(
152
+ (state: RootState) => state.hmsStates.noiseCancellationPlugin
153
+ );
154
+
155
+ React.useEffect(() => {
156
+ if (shouldEnableNoiseCancellation) {
157
+ noiseCancellationPlugin?.enable();
158
+ }
159
+ }, []);
160
+
141
161
  return (
142
162
  <View style={styles.container}>
143
163
  <HMSStatusBar hidden={controlsHidden} barStyle={'light-content'} />
@@ -10,7 +10,6 @@ import {
10
10
  useWindowDimensions,
11
11
  } from 'react-native';
12
12
  import type { ImageURISource } from 'react-native';
13
- import Toast from 'react-native-simple-toast';
14
13
  import { useDispatch, useSelector } from 'react-redux';
15
14
  import {
16
15
  HMSTrack,
@@ -34,53 +33,75 @@ import { styles } from './styles';
34
33
  import { CustomButton } from './CustomButton';
35
34
  import { Menu, MenuItem } from './MenuModal';
36
35
 
37
- import { changeHLSAspectRatio, changeShowStats } from '../redux/actions';
36
+ import {
37
+ addNotification,
38
+ changeHLSAspectRatio,
39
+ changeShowStats,
40
+ } from '../redux/actions';
38
41
  import { getTime } from '../utils/functions';
39
42
  import { ModalTypes, SUPPORTED_ASPECT_RATIOS } from '../utils/types';
40
43
  import { COLORS } from '../utils/theme';
41
44
  import type { RootState } from '../redux';
42
45
  import { SwitchRow } from './SwitchRow';
43
- import { useHMSConferencingScreenConfig, useHMSInstance } from '../hooks-util';
46
+ import { useHMSInstance } from '../hooks-util';
47
+ import { ChevronIcon } from '../Icons';
48
+ import { NotificationTypes } from '../types';
44
49
 
45
50
  export const ChangeRoleModal = ({ cancelModal }: { cancelModal: Function }) => {
46
51
  const instance = useHMSInstance();
47
- const peer = useSelector((state: RootState) => state.app.peerToUpdate);
48
- const roles = useSelector((state: RootState) => state.hmsStates.roles);
49
-
50
- const [newRole, setNewRole] = useState<HMSRole>(peer?.role!);
51
- const [visible, setVisible] = useState<boolean>(false);
52
+ const dispatch = useDispatch();
53
+ const allRoles = useSelector((state: RootState) => state.hmsStates.roles);
54
+ let peer = useSelector((state: RootState) => state.app.peerToUpdate);
52
55
 
53
- const skipPreviewForRoleChange = useHMSConferencingScreenConfig(
54
- (conferencingScreenConfig) => {
55
- if (
56
- conferencingScreenConfig?.elements &&
57
- 'on_stage_exp' in conferencingScreenConfig.elements
58
- ) {
59
- return (
60
- conferencingScreenConfig.elements.on_stage_exp
61
- ?.skip_preview_for_role_change || false
62
- );
63
- }
64
- return false;
56
+ useEffect(() => {
57
+ let validRoles = allRoles.filter(
58
+ (role) =>
59
+ role.name !== peer?.role?.name && role.name !== '__internal_recorder'
60
+ );
61
+ setValidRoles(validRoles);
62
+ if (validRoles.length > 0) {
63
+ setNewRole(validRoles[0]);
65
64
  }
65
+ }, [allRoles, peer]);
66
+
67
+ const [validRoles, setValidRoles] = useState<HMSRole[] | undefined>(
68
+ undefined
66
69
  );
70
+ const [newRole, setNewRole] = useState<HMSRole | undefined>(undefined);
71
+
72
+ const [visible, setVisible] = useState<boolean>(false);
73
+
67
74
  const hideMenu = () => setVisible(false);
68
75
  const showMenu = () => setVisible(true);
69
- const changeRole = () => {
70
- instance
71
- ?.changeRoleOfPeer(peer!, newRole, skipPreviewForRoleChange)
72
- .catch((e) => {
73
- console.log('Change Role of Peer Error: ', e);
74
- Toast.showWithGravity((e as Error).message, Toast.LONG, Toast.TOP);
76
+ const switchRole = () => {
77
+ if (newRole) {
78
+ instance?.changeRoleOfPeer(peer!, newRole, true).catch((e) => {
79
+ console.log('Switch Role of Peer Error: ', e);
80
+ dispatch(
81
+ addNotification({
82
+ id: Math.random().toString(16).slice(2),
83
+ type: NotificationTypes.ERROR,
84
+ title: e.message,
85
+ })
86
+ );
75
87
  });
88
+ } else {
89
+ dispatch(
90
+ addNotification({
91
+ id: Math.random().toString(16).slice(2),
92
+ type: NotificationTypes.ERROR,
93
+ title: 'Please select a role',
94
+ })
95
+ );
96
+ }
76
97
  cancelModal();
77
98
  };
78
99
 
79
100
  return (
80
101
  <View style={styles.roleChangeModal}>
81
- <Text style={styles.roleChangeModalHeading}>Change Role</Text>
102
+ <Text style={styles.roleChangeModalHeading}>Switch Role</Text>
82
103
  <Text style={styles.roleChangeModalDescription}>
83
- Change the role of '{peer?.name}' to
104
+ Switch the role of '{peer?.name}' from '{peer?.role?.name}' to
84
105
  </Text>
85
106
  <Menu
86
107
  visible={visible}
@@ -88,16 +109,20 @@ export const ChangeRoleModal = ({ cancelModal }: { cancelModal: Function }) => {
88
109
  <TouchableOpacity
89
110
  style={styles.participantChangeRoleContainer}
90
111
  onPress={showMenu}
112
+ disabled={validRoles && validRoles?.length <= 1}
91
113
  >
92
114
  <Text style={styles.participantFilterText} numberOfLines={1}>
93
115
  {newRole?.name}
94
116
  </Text>
117
+ {validRoles && validRoles?.length > 1 && (
118
+ <ChevronIcon direction={'down'} />
119
+ )}
95
120
  </TouchableOpacity>
96
121
  }
97
122
  onRequestClose={hideMenu}
98
123
  style={styles.participantsMenuContainer}
99
124
  >
100
- {roles?.map((knownRole) => {
125
+ {validRoles?.map((knownRole) => {
101
126
  return (
102
127
  <MenuItem
103
128
  onPress={() => {
@@ -123,8 +148,8 @@ export const ChangeRoleModal = ({ cancelModal }: { cancelModal: Function }) => {
123
148
  textStyle={styles.roleChangeModalButtonText}
124
149
  />
125
150
  <CustomButton
126
- title="Change"
127
- onPress={changeRole}
151
+ title="Switch Role"
152
+ onPress={switchRole}
128
153
  viewStyle={styles.roleChangeModalSuccessButton}
129
154
  textStyle={styles.roleChangeModalButtonText}
130
155
  />
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
- import { useSelector } from 'react-redux';
3
+ import { useDispatch, useSelector } from 'react-redux';
4
4
  import type { HMSLocalPeer, HMSPeer } from '@100mslive/react-native-hms';
5
5
  import { HMSPeerType } from '@100mslive/react-native-hms';
6
6
 
@@ -8,12 +8,15 @@ import {
8
8
  useHMSInstance,
9
9
  useHMSLayoutConfig,
10
10
  useHMSRoomStyleSheet,
11
+ useModalType,
11
12
  } from '../../hooks-util';
12
13
  import { CameraIcon, HandIcon, MicIcon, PersonIcon } from '../../Icons';
13
14
  import { ParticipantsItemOption } from './ParticipantsItemOption';
14
15
  import type { RootState } from '../../redux';
15
16
  import { selectCanPublishTrackForRole } from '../../hooks-sdk-selectors';
16
17
  import { parseMetadata } from '../../utils/functions';
18
+ import { ModalTypes } from '../../utils/types';
19
+ import { setPeerToUpdate } from '../../redux/actions';
17
20
 
18
21
  interface ParticipantsItemOptionsProps {
19
22
  insideHandRaiseGroup: boolean;
@@ -33,12 +36,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
33
36
  (state: RootState) => state.hmsStates.localPeer?.role?.permissions
34
37
  );
35
38
 
39
+ const roles = useSelector((state: RootState) => state.hmsStates.roles);
40
+
36
41
  const localPeerCanMuteTrack =
37
42
  localPeerPermissions && localPeerPermissions.mute;
38
43
  const localPeerCanUnmuteTrack =
39
44
  localPeerPermissions && localPeerPermissions.unmute;
40
45
  const localPeerCanRemove =
41
46
  localPeerPermissions && localPeerPermissions.removeOthers;
47
+ const localPeerCanChangeRole =
48
+ localPeerPermissions && localPeerPermissions.changeRole && roles.length > 1;
42
49
 
43
50
  // Selected Peer Permissions related states
44
51
  const peerCanPublishAudio = selectCanPublishTrackForRole(peer.role!, 'audio');
@@ -153,6 +160,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
153
160
  onItemPress();
154
161
  };
155
162
 
163
+ const { handleModalVisibleType: setModalVisible } = useModalType();
164
+
165
+ const dispatch = useDispatch();
166
+
167
+ const handleChangeRolePress = () => {
168
+ setModalVisible(ModalTypes.CHANGE_ROLE, true);
169
+ dispatch(setPeerToUpdate(peer));
170
+ onItemPress();
171
+ };
172
+
156
173
  const showMuteAudioOption =
157
174
  !insideHandRaiseGroup &&
158
175
  localPeerCanMuteTrack &&
@@ -249,6 +266,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
249
266
  isActive: false,
250
267
  hide: Boolean(!onStageRoleStr || peer.role?.name !== onStageRoleStr),
251
268
  },
269
+ {
270
+ id: 'change-role',
271
+ icon: (
272
+ <PersonIcon type="rectangle" style={{ width: 20, height: 20 }} />
273
+ ),
274
+ label: 'Switch Role',
275
+ pressHandler: handleChangeRolePress,
276
+ isActive: false,
277
+ hide: !localPeerCanChangeRole,
278
+ },
252
279
  {
253
280
  id: 'remove-participant',
254
281
  icon: <PersonIcon type="left" style={{ width: 20, height: 20 }} />,
@@ -14,7 +14,7 @@ import { HMSPeerType, HMSTrack } from '@100mslive/react-native-hms';
14
14
  import type { RootState } from '../redux';
15
15
  import type { PeerTrackNode } from '../utils/types';
16
16
  import { ModalTypes } from '../utils/types';
17
- import { setInsetViewMinimized } from '../redux/actions';
17
+ import { setInsetViewMinimized, setPeerToUpdate } from '../redux/actions';
18
18
  import { useHMSRoomStyle, useModalType } from '../hooks-util';
19
19
  import {
20
20
  CameraIcon,
@@ -40,6 +40,7 @@ export const PeerSettingsModalContent: React.FC<
40
40
  > = ({ peerTrackNode, peerTrackNodesListEmpty, cancelModal }) => {
41
41
  const dispatch = useDispatch();
42
42
  const hmsInstance = useSelector((state: RootState) => state.user.hmsInstance);
43
+ const allRoles = useSelector((state: RootState) => state.hmsStates.roles);
43
44
  const localPeer = useSelector(
44
45
  (state: RootState) => state.hmsStates.localPeer
45
46
  );
@@ -92,6 +93,11 @@ export const PeerSettingsModalContent: React.FC<
92
93
  );
93
94
  };
94
95
 
96
+ const switchRole = () => {
97
+ setModalVisible(ModalTypes.CHANGE_ROLE, true);
98
+ dispatch(setPeerToUpdate(peerTrackNode.peer));
99
+ };
100
+
95
101
  const changeName = () => {
96
102
  setModalVisible(ModalTypes.CHANGE_NAME, true);
97
103
  };
@@ -194,6 +200,16 @@ export const PeerSettingsModalContent: React.FC<
194
200
  </>
195
201
  ) : null}
196
202
 
203
+ {allRoles.length > 1 &&
204
+ !peer.isLocal &&
205
+ localPeerPermissions?.changeRole ? (
206
+ <SettingItem
207
+ text={'Switch Role'}
208
+ icon={<PersonIcon type="rectangle" style={styles.customIcon} />}
209
+ onPress={switchRole}
210
+ />
211
+ ) : null}
212
+
197
213
  {!peer.isLocal && localPeerPermissions?.removeOthers ? (
198
214
  <SettingItem
199
215
  text="Remove Participant"
@@ -252,7 +252,7 @@ export const RoomSettingsModalContent: React.FC<
252
252
  }, [noiseCancellationPlugin]);
253
253
 
254
254
  const handleNoiseCancellation = () => {
255
- // Register callback to be called when bottom sheet is hiddden
255
+ // Register callback to be called when bottom sheet is hidden
256
256
  registerOnModalHideAction(() => {
257
257
  if (!noiseCancellationPlugin || !isNoiseCancellationAvailable) return;
258
258
 
@@ -766,6 +766,7 @@ const styles = StyleSheet.create({
766
766
  padding: 8,
767
767
  flexDirection: 'row',
768
768
  alignItems: 'center',
769
+ justifyContent: 'space-between',
769
770
  width: '100%',
770
771
  marginTop: 24,
771
772
  borderWidth: 1,
package/src/hooks-util.ts CHANGED
@@ -217,9 +217,10 @@ const useHMSRoomUpdate = (hmsInstance: HMSSDK) => {
217
217
  if (captionTranscription?.state === TranscriptionState.STARTED) {
218
218
  batch(() => {
219
219
  dispatch(removeNotification('enable-cc'));
220
+ dispatch(removeNotification('TranscriptionState.STARTED'));
220
221
  dispatch(
221
222
  addNotification({
222
- id: Math.random().toString(16).slice(2),
223
+ id: 'TranscriptionState.STARTED',
223
224
  type: NotificationTypes.INFO,
224
225
  icon: 'cc',
225
226
  title: 'Closed Captioning enabled for everyone',
@@ -287,6 +288,8 @@ const useHMSPeersUpdate = (
287
288
  // );
288
289
  const hmsActions = useHMSActions();
289
290
 
291
+ const isFirstRunForRoleChangeModal = useRef(true);
292
+
290
293
  useEffect(() => {
291
294
  const peerUpdateHandler = ({ peer, type }: PeerUpdate) => {
292
295
  // Handle State from Preview screen
@@ -428,6 +431,18 @@ const useHMSPeersUpdate = (
428
431
  .catch((e) => {
429
432
  console.log('Metadata change failed', e);
430
433
  });
434
+
435
+ if (isFirstRunForRoleChangeModal.current) {
436
+ isFirstRunForRoleChangeModal.current = false;
437
+ } else {
438
+ dispatch(
439
+ addNotification({
440
+ id: Math.random().toString(16).slice(2),
441
+ type: NotificationTypes.INFO,
442
+ title: `You are now a ${peer.role?.name}`,
443
+ })
444
+ );
445
+ }
431
446
  }
432
447
  }
433
448
  return;
@@ -1591,35 +1606,37 @@ const pipConfig: HMSPIPConfig = {
1591
1606
  export const useEnableAutoPip = () => {
1592
1607
  const hmsInstance = useHMSInstance();
1593
1608
 
1594
- const enableAutoPip = useCallback(
1609
+ return useCallback(
1595
1610
  (data: HMSPIPConfig) => {
1596
- hmsInstance.setPipParams({
1597
- ...pipConfig,
1598
- ...data,
1599
- autoEnterPipMode: true,
1600
- });
1611
+ hmsInstance
1612
+ .setPipParams({
1613
+ ...pipConfig,
1614
+ ...data,
1615
+ autoEnterPipMode: true,
1616
+ })
1617
+ .then((r) => console.log('Enable Auto PIP: ', r))
1618
+ .catch((e) => console.log('Enable Auto PIP Error: ', e));
1601
1619
  },
1602
1620
  [hmsInstance]
1603
1621
  );
1604
-
1605
- return enableAutoPip;
1606
1622
  };
1607
1623
 
1608
1624
  export const useDisableAutoPip = () => {
1609
1625
  const hmsInstance = useHMSInstance();
1610
1626
 
1611
- const disableAutoPip = useCallback(
1627
+ return useCallback(
1612
1628
  (data: HMSPIPConfig) => {
1613
- hmsInstance.setPipParams({
1614
- ...pipConfig,
1615
- ...data,
1616
- autoEnterPipMode: false,
1617
- });
1629
+ hmsInstance
1630
+ .setPipParams({
1631
+ ...pipConfig,
1632
+ ...data,
1633
+ autoEnterPipMode: false,
1634
+ })
1635
+ .then((r) => console.log('Disable Auto PIP: ', r))
1636
+ .catch((e) => console.log('Disable Auto PIP Error: ', e));
1618
1637
  },
1619
1638
  [hmsInstance]
1620
1639
  );
1621
-
1622
- return disableAutoPip;
1623
1640
  };
1624
1641
 
1625
1642
  export const useAutoPip = (oneToOneCall: boolean) => {
package/src/utils.ts CHANGED
@@ -4,8 +4,8 @@ const DEFAULT_JOINING_CONFIG = {
4
4
  mutedAudio: true,
5
5
  mutedVideo: true,
6
6
  skipPreview: false,
7
- audioMixer: false, // IOS only
8
- musicMode: false, // IOS only
7
+ audioMixer: false, // iOS only
8
+ musicMode: false, // iOS only
9
9
  softwareDecoder: true, // Android only
10
10
  autoResize: false, // Android only
11
11
  };