@100mslive/react-native-room-kit 1.2.0 → 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.
- package/README.md +5 -4
- package/lib/commonjs/HMSInstanceSetup.js +2 -1
- package/lib/commonjs/HMSInstanceSetup.js.map +1 -1
- package/lib/commonjs/HMSRoomSetup.js +31 -1
- package/lib/commonjs/HMSRoomSetup.js.map +1 -1
- package/lib/commonjs/components/Chat/ChatBanner.js +8 -7
- package/lib/commonjs/components/Chat/ChatBanner.js.map +1 -1
- package/lib/commonjs/components/CustomButton.js +2 -0
- package/lib/commonjs/components/CustomButton.js.map +1 -1
- package/lib/commonjs/components/DisplayView.js +1 -1
- package/lib/commonjs/components/DisplayView.js.map +1 -1
- package/lib/commonjs/components/HMSManageNoiseCancellation.js +11 -0
- package/lib/commonjs/components/HMSManageNoiseCancellation.js.map +1 -1
- package/lib/commonjs/components/HMSPreviewHLSLiveIndicator.js +2 -0
- package/lib/commonjs/components/HMSPreviewHLSLiveIndicator.js.map +1 -1
- package/lib/commonjs/components/MeetingScreenContent.js +13 -2
- package/lib/commonjs/components/MeetingScreenContent.js.map +1 -1
- package/lib/commonjs/components/MenuModal/MenuDivider.js +2 -0
- package/lib/commonjs/components/MenuModal/MenuDivider.js.map +1 -1
- package/lib/commonjs/components/Modals.js +45 -24
- package/lib/commonjs/components/Modals.js.map +1 -1
- package/lib/commonjs/components/Participants/ParticipantsItemOptions.js +26 -0
- package/lib/commonjs/components/Participants/ParticipantsItemOptions.js.map +1 -1
- package/lib/commonjs/components/PeerSettingsModalContent.js +13 -1
- package/lib/commonjs/components/PeerSettingsModalContent.js.map +1 -1
- package/lib/commonjs/components/RoomSettingsModalContent.js +1 -1
- package/lib/commonjs/components/VirtualBackgroundModalContent.js +1 -1
- package/lib/commonjs/components/VirtualBackgroundModalContent.js.map +1 -1
- package/lib/commonjs/components/WebrtcView.js +1 -1
- package/lib/commonjs/components/WebrtcView.js.map +1 -1
- package/lib/commonjs/components/styles.js +1 -0
- package/lib/commonjs/components/styles.js.map +1 -1
- package/lib/commonjs/hooks-util.js +48 -21
- package/lib/commonjs/hooks-util.js.map +1 -1
- package/lib/commonjs/utils.js +2 -2
- package/lib/module/HMSInstanceSetup.js +2 -1
- package/lib/module/HMSInstanceSetup.js.map +1 -1
- package/lib/module/HMSRoomSetup.js +32 -2
- package/lib/module/HMSRoomSetup.js.map +1 -1
- package/lib/module/components/Chat/ChatBanner.js +2 -1
- package/lib/module/components/Chat/ChatBanner.js.map +1 -1
- package/lib/module/components/CustomButton.js +1 -0
- package/lib/module/components/CustomButton.js.map +1 -1
- package/lib/module/components/DisplayView.js +2 -2
- package/lib/module/components/DisplayView.js.map +1 -1
- package/lib/module/components/HMSManageNoiseCancellation.js +11 -0
- package/lib/module/components/HMSManageNoiseCancellation.js.map +1 -1
- package/lib/module/components/HMSPreviewHLSLiveIndicator.js +1 -0
- package/lib/module/components/HMSPreviewHLSLiveIndicator.js.map +1 -1
- package/lib/module/components/MeetingScreenContent.js +14 -3
- package/lib/module/components/MeetingScreenContent.js.map +1 -1
- package/lib/module/components/MenuModal/MenuDivider.js +1 -0
- package/lib/module/components/MenuModal/MenuDivider.js.map +1 -1
- package/lib/module/components/Modals.js +47 -25
- package/lib/module/components/Modals.js.map +1 -1
- package/lib/module/components/Participants/ParticipantsItemOptions.js +28 -2
- package/lib/module/components/Participants/ParticipantsItemOptions.js.map +1 -1
- package/lib/module/components/PeerSettingsModalContent.js +14 -2
- package/lib/module/components/PeerSettingsModalContent.js.map +1 -1
- package/lib/module/components/RoomSettingsModalContent.js +1 -1
- package/lib/module/components/VirtualBackgroundModalContent.js +1 -1
- package/lib/module/components/VirtualBackgroundModalContent.js.map +1 -1
- package/lib/module/components/WebrtcView.js +2 -2
- package/lib/module/components/WebrtcView.js.map +1 -1
- package/lib/module/components/styles.js +1 -0
- package/lib/module/components/styles.js.map +1 -1
- package/lib/module/hooks-util.js +53 -29
- package/lib/module/hooks-util.js.map +1 -1
- package/lib/module/utils.js +2 -2
- package/lib/typescript/HMSInstanceSetup.d.ts.map +1 -1
- package/lib/typescript/HMSRoomSetup.d.ts.map +1 -1
- package/lib/typescript/components/Chat/ChatBanner.d.ts +1 -1
- package/lib/typescript/components/Chat/ChatBanner.d.ts.map +1 -1
- package/lib/typescript/components/CustomButton.d.ts.map +1 -1
- package/lib/typescript/components/HMSManageNoiseCancellation.d.ts.map +1 -1
- package/lib/typescript/components/HMSPreviewHLSLiveIndicator.d.ts.map +1 -1
- package/lib/typescript/components/MeetingScreenContent.d.ts.map +1 -1
- package/lib/typescript/components/MenuModal/MenuDivider.d.ts.map +1 -1
- package/lib/typescript/components/Modals.d.ts +1 -1
- package/lib/typescript/components/Modals.d.ts.map +1 -1
- package/lib/typescript/components/Participants/ParticipantsItemOptions.d.ts.map +1 -1
- package/lib/typescript/components/PeerSettingsModalContent.d.ts.map +1 -1
- package/lib/typescript/components/styles.d.ts +1 -0
- package/lib/typescript/components/styles.d.ts.map +1 -1
- package/lib/typescript/hooks-sdk-selectors.d.ts +2 -2
- package/lib/typescript/hooks-sdk.d.ts.map +1 -1
- package/lib/typescript/hooks-util.d.ts +8 -9
- package/lib/typescript/hooks-util.d.ts.map +1 -1
- package/lib/typescript/redux/actions/index.d.ts +39 -39
- package/lib/typescript/redux/actions/index.d.ts.map +1 -1
- package/lib/typescript/redux/index.d.ts +13 -15
- package/lib/typescript/redux/index.d.ts.map +1 -1
- package/lib/typescript/redux/reducers/index.d.ts +13 -15
- package/lib/typescript/redux/reducers/index.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/utils/dimension.d.ts.map +1 -1
- package/lib/typescript/utils/functions.d.ts +1 -1
- package/lib/typescript/utils/functions.d.ts.map +1 -1
- package/lib/typescript/utils/hooks.d.ts +2 -2
- package/lib/typescript/utils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/HMSInstanceSetup.tsx +2 -1
- package/src/HMSRoomSetup.tsx +49 -2
- package/src/components/Chat/ChatBanner.tsx +2 -2
- package/src/components/CustomButton.tsx +1 -0
- package/src/components/DisplayView.tsx +2 -2
- package/src/components/HMSManageNoiseCancellation.tsx +15 -0
- package/src/components/HMSPreviewHLSLiveIndicator.tsx +1 -0
- package/src/components/MeetingScreenContent.tsx +23 -3
- package/src/components/MenuModal/MenuDivider.tsx +1 -0
- package/src/components/Modals.tsx +56 -31
- package/src/components/Participants/ParticipantsItemOptions.tsx +28 -1
- package/src/components/PeerSettingsModalContent.tsx +17 -1
- package/src/components/RoomSettingsModalContent.tsx +1 -1
- package/src/components/VirtualBackgroundModalContent.tsx +1 -1
- package/src/components/WebrtcView.tsx +2 -2
- package/src/components/styles.ts +1 -0
- package/src/hooks-util.ts +89 -48
- package/src/utils.ts +2 -2
package/src/HMSRoomSetup.tsx
CHANGED
|
@@ -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 {
|
|
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() >=
|
|
502
|
+
Date.now() - poll.startedAt.getTime() >= 20000
|
|
456
503
|
) {
|
|
457
504
|
dispatch(
|
|
458
505
|
addNotification({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-ignore - Ignoring React import as it is generating error while running prepack script
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { View, StyleSheet, Text, Image } from 'react-native';
|
|
3
|
-
|
|
4
4
|
import { useHMSRoomStyleSheet } from '../../hooks-util';
|
|
5
5
|
import { useIsLandscapeOrientation } from '../../utils/dimension';
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { InteractionManager, View } from 'react-native';
|
|
3
|
+
import { InteractionManager, Platform, View } from 'react-native';
|
|
4
4
|
import { HMSTrack, HMSCameraControl } from '@100mslive/react-native-hms';
|
|
5
5
|
import type { SharedValue } from 'react-native-reanimated';
|
|
6
6
|
|
|
@@ -134,7 +134,7 @@ export const DisplayView: React.FC<DisplayViewProps> = ({
|
|
|
134
134
|
handlePeerTileMorePress={handlePeerTileMorePress}
|
|
135
135
|
/>
|
|
136
136
|
|
|
137
|
-
{isPipModeActive ? null : (
|
|
137
|
+
{isPipModeActive && Platform.OS === 'android' ? null : (
|
|
138
138
|
<>
|
|
139
139
|
<LeaveRoomBottomSheet />
|
|
140
140
|
|
|
@@ -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,13 +138,33 @@ 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'} />
|
|
144
164
|
|
|
145
165
|
<GestureDetector gesture={tapGesture}>
|
|
146
166
|
<View collapsable={false} style={styles.container}>
|
|
147
|
-
{isPipModeActive ? null : (
|
|
167
|
+
{isPipModeActive && Platform.OS === 'android' ? null : (
|
|
148
168
|
<AnimatedHeader offset={offset}>
|
|
149
169
|
<Header />
|
|
150
170
|
</AnimatedHeader>
|
|
@@ -152,7 +172,7 @@ export const MeetingScreenContent: React.FC<MeetingScreenContentProps> = ({
|
|
|
152
172
|
|
|
153
173
|
<DisplayView offset={offset} peerTrackNodes={peerTrackNodes} />
|
|
154
174
|
|
|
155
|
-
{isPipModeActive ? null : (
|
|
175
|
+
{isPipModeActive && Platform.OS === 'android' ? null : (
|
|
156
176
|
<AnimatedFooter offset={offset}>
|
|
157
177
|
<Footer />
|
|
158
178
|
</AnimatedFooter>
|
|
@@ -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 {
|
|
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 {
|
|
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
|
|
48
|
-
const
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
70
|
-
|
|
71
|
-
?.changeRoleOfPeer(peer!, newRole,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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}>
|
|
102
|
+
<Text style={styles.roleChangeModalHeading}>Switch Role</Text>
|
|
82
103
|
<Text style={styles.roleChangeModalDescription}>
|
|
83
|
-
|
|
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
|
-
{
|
|
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="
|
|
127
|
-
onPress={
|
|
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
|
|
255
|
+
// Register callback to be called when bottom sheet is hidden
|
|
256
256
|
registerOnModalHideAction(() => {
|
|
257
257
|
if (!noiseCancellationPlugin || !isNoiseCancellationAvailable) return;
|
|
258
258
|
|
|
@@ -109,7 +109,7 @@ export const VirtualBackgroundModalContent: React.FC<
|
|
|
109
109
|
// If PIP is enabled, disable it
|
|
110
110
|
if (pipModeEnabled) {
|
|
111
111
|
dispatch(setAutoEnterPipMode(false));
|
|
112
|
-
disableAutoPip();
|
|
112
|
+
disableAutoPip({});
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const imageLibraryResponse = await ImagePicker.launchImageLibrary({
|
|
@@ -24,7 +24,7 @@ import { OverlayContainer } from './OverlayContainer';
|
|
|
24
24
|
import { OverlayedViews } from './OverlayedViews';
|
|
25
25
|
import { useFooterHeight } from './Footer';
|
|
26
26
|
import { useHeaderHeight } from './Header';
|
|
27
|
-
import { View } from 'react-native';
|
|
27
|
+
import { Platform, View } from 'react-native';
|
|
28
28
|
import { WebrtcTranscriptOverlayView } from './WebrtcTranscriptOverlayView';
|
|
29
29
|
|
|
30
30
|
interface WebrtcViewProps {
|
|
@@ -111,7 +111,7 @@ export const WebrtcView = React.forwardRef<GridViewRefAttrs, WebrtcViewProps>(
|
|
|
111
111
|
};
|
|
112
112
|
}, [isPortrait, bottom]);
|
|
113
113
|
|
|
114
|
-
if (isPipModeActive) {
|
|
114
|
+
if (isPipModeActive && Platform.OS === 'android') {
|
|
115
115
|
return (
|
|
116
116
|
<PIPView
|
|
117
117
|
peerTrackNodes={peerTrackNodes}
|