@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.
- 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/HMSManageNoiseCancellation.js +11 -0
- package/lib/commonjs/components/HMSManageNoiseCancellation.js.map +1 -1
- package/lib/commonjs/components/MeetingScreenContent.js +11 -0
- package/lib/commonjs/components/MeetingScreenContent.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/styles.js +1 -0
- package/lib/commonjs/components/styles.js.map +1 -1
- package/lib/commonjs/hooks-util.js +25 -15
- 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/HMSManageNoiseCancellation.js +11 -0
- package/lib/module/components/HMSManageNoiseCancellation.js.map +1 -1
- package/lib/module/components/MeetingScreenContent.js +12 -1
- package/lib/module/components/MeetingScreenContent.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/styles.js +1 -0
- package/lib/module/components/styles.js.map +1 -1
- package/lib/module/hooks-util.js +25 -15
- 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/HMSManageNoiseCancellation.d.ts.map +1 -1
- package/lib/typescript/components/MeetingScreenContent.d.ts.map +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-util.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/HMSManageNoiseCancellation.tsx +15 -0
- package/src/components/MeetingScreenContent.tsx +21 -1
- 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/styles.ts +1 -0
- package/src/hooks-util.ts +34 -17
- 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.
|
|
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.
|
|
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.
|
|
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",
|
package/src/HMSInstanceSetup.tsx
CHANGED
|
@@ -75,7 +75,7 @@ const getTrackSettings = (
|
|
|
75
75
|
? HMSTrackSettingsInitState.MUTED
|
|
76
76
|
: HMSTrackSettingsInitState.UNMUTED,
|
|
77
77
|
cameraFacing: HMSCameraFacing.FRONT,
|
|
78
|
-
disableAutoResize:
|
|
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,
|
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({
|
|
@@ -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 {
|
|
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
|
|
package/src/components/styles.ts
CHANGED
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:
|
|
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
|
-
|
|
1609
|
+
return useCallback(
|
|
1595
1610
|
(data: HMSPIPConfig) => {
|
|
1596
|
-
hmsInstance
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
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
|
-
|
|
1627
|
+
return useCallback(
|
|
1612
1628
|
(data: HMSPIPConfig) => {
|
|
1613
|
-
hmsInstance
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
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, //
|
|
8
|
-
musicMode: false, //
|
|
7
|
+
audioMixer: false, // iOS only
|
|
8
|
+
musicMode: false, // iOS only
|
|
9
9
|
softwareDecoder: true, // Android only
|
|
10
10
|
autoResize: false, // Android only
|
|
11
11
|
};
|