Skip to content

Commit

Permalink
Added support for showing Switch Role option in Prebuilt (#1412)
Browse files Browse the repository at this point in the history
# Description

- Switch Role changes

### Pre-launch Checklist

- [x] The [Documentation] is updated accordingly, or this PR doesn't
require it.
- [x] I have updated the `ExampleAppChangelog.txt` file with relevant
changes.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I added new tests to check the change I am making, or this PR is
test-exempt.
- [x] All existing and new tests are passing.

<!-- Links -->

[Documentation]: https://www.100ms.live/docs

---------

Co-authored-by: Jatin Nagar <[email protected]>
  • Loading branch information
ygit and stanwolverine authored Jul 26, 2024
1 parent 5ffc173 commit 3d406db
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
applicationId "live.hms.rn"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 523
versionName "2.4.73"
versionCode 524
versionName "2.4.74"
missingDimensionStrategy 'react-native-camera', 'general'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@
CODE_SIGN_ENTITLEMENTS = RNExample/RNExample.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 523;
CURRENT_PROJECT_VERSION = 524;
DEVELOPMENT_TEAM = 5N85PP82A9;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RNExample/Info.plist;
Expand Down Expand Up @@ -534,7 +534,7 @@
CODE_SIGN_ENTITLEMENTS = RNExample/RNExample.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 523;
CURRENT_PROJECT_VERSION = 524;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5N85PP82A9;
INFOPLIST_FILE = RNExample/Info.plist;
Expand Down Expand Up @@ -706,7 +706,7 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = RNExampleBroadcastUpload/RNExampleBroadcastUpload.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 523;
CURRENT_PROJECT_VERSION = 524;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 5N85PP82A9;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -748,7 +748,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 523;
CURRENT_PROJECT_VERSION = 524;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5N85PP82A9;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.4.73</string>
<string>2.4.74</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>523</string>
<string>524</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
Expand Down
84 changes: 55 additions & 29 deletions packages/react-native-room-kit/src/components/Modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,70 +34,96 @@ import { styles } from './styles';
import { CustomButton } from './CustomButton';
import { Menu, MenuItem } from './MenuModal';

import { changeHLSAspectRatio, changeShowStats } from '../redux/actions';
import {
addNotification,
changeHLSAspectRatio,
changeShowStats,
} from '../redux/actions';
import { getTime } from '../utils/functions';
import { ModalTypes, SUPPORTED_ASPECT_RATIOS } from '../utils/types';
import { COLORS } from '../utils/theme';
import type { RootState } from '../redux';
import { SwitchRow } from './SwitchRow';
import { useHMSConferencingScreenConfig, useHMSInstance } from '../hooks-util';
import { ChevronIcon } from '../Icons';
import { NotificationTypes } from '../types';

export const ChangeRoleModal = ({ cancelModal }: { cancelModal: Function }) => {
const instance = useHMSInstance();
const peer = useSelector((state: RootState) => state.app.peerToUpdate);
const roles = useSelector((state: RootState) => state.hmsStates.roles);

const [newRole, setNewRole] = useState<HMSRole>(peer?.role!);
const [visible, setVisible] = useState<boolean>(false);
const dispatch = useDispatch();
const allRoles = useSelector((state: RootState) => state.hmsStates.roles);
let peer = useSelector((state: RootState) => state.app.peerToUpdate);

const skipPreviewForRoleChange = useHMSConferencingScreenConfig(
(conferencingScreenConfig) => {
if (
conferencingScreenConfig?.elements &&
'on_stage_exp' in conferencingScreenConfig.elements
) {
return (
conferencingScreenConfig.elements.on_stage_exp
?.skip_preview_for_role_change || false
);
}
return false;
useEffect(() => {
let validRoles = allRoles.filter(
(role) =>
role.name !== peer?.role?.name && role.name !== '__internal_recorder'
);
setValidRoles(validRoles);
if (validRoles.length > 0) {
setNewRole(validRoles[0]);
}
}, [allRoles, peer]);

const [validRoles, setValidRoles] = useState<HMSRole[] | undefined>(
undefined
);
const [newRole, setNewRole] = useState<HMSRole | undefined>(undefined);

const [visible, setVisible] = useState<boolean>(false);

const hideMenu = () => setVisible(false);
const showMenu = () => setVisible(true);
const changeRole = () => {
instance
?.changeRoleOfPeer(peer!, newRole, skipPreviewForRoleChange)
.catch((e) => {
console.log('Change Role of Peer Error: ', e);
Toast.showWithGravity((e as Error).message, Toast.LONG, Toast.TOP);
const switchRole = () => {
if (newRole) {
instance?.changeRoleOfPeer(peer!, newRole, true).catch((e) => {
console.log('Switch Role of Peer Error: ', e);
dispatch(
addNotification({
id: Math.random().toString(16).slice(2),
type: NotificationTypes.ERROR,
title: e.message,
})
);
});
} else {
dispatch(
addNotification({
id: Math.random().toString(16).slice(2),
type: NotificationTypes.ERROR,
title: 'Please select a role',
})
);
}
cancelModal();
};

return (
<View style={styles.roleChangeModal}>
<Text style={styles.roleChangeModalHeading}>Change Role</Text>
<Text style={styles.roleChangeModalHeading}>Switch Role</Text>
<Text style={styles.roleChangeModalDescription}>
Change the role of '{peer?.name}' to
Switch the role of '{peer?.name}' from '{peer?.role?.name}' to
</Text>
<Menu
visible={visible}
anchor={
<TouchableOpacity
style={styles.participantChangeRoleContainer}
onPress={showMenu}
disabled={validRoles?.length <= 1}
>
<Text style={styles.participantFilterText} numberOfLines={1}>
{newRole?.name}
</Text>
{validRoles && validRoles?.length > 1 && (
<ChevronIcon direction={'down'} />
)}
</TouchableOpacity>
}
onRequestClose={hideMenu}
style={styles.participantsMenuContainer}
>
{roles?.map((knownRole) => {
{validRoles?.map((knownRole) => {
return (
<MenuItem
onPress={() => {
Expand All @@ -123,8 +149,8 @@ export const ChangeRoleModal = ({ cancelModal }: { cancelModal: Function }) => {
textStyle={styles.roleChangeModalButtonText}
/>
<CustomButton
title="Change"
onPress={changeRole}
title="Switch Role"
onPress={switchRole}
viewStyle={styles.roleChangeModalSuccessButton}
textStyle={styles.roleChangeModalButtonText}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import type { HMSLocalPeer, HMSPeer } from '@100mslive/react-native-hms';
import { HMSPeerType } from '@100mslive/react-native-hms';

import {
useHMSInstance,
useHMSLayoutConfig,
useHMSRoomStyleSheet,
useModalType,
} from '../../hooks-util';
import { CameraIcon, HandIcon, MicIcon, PersonIcon } from '../../Icons';
import { ParticipantsItemOption } from './ParticipantsItemOption';
import type { RootState } from '../../redux';
import { selectCanPublishTrackForRole } from '../../hooks-sdk-selectors';
import { parseMetadata } from '../../utils/functions';
import { ModalTypes } from '../../utils/types';
import { setPeerToUpdate } from '../../redux/actions';

interface ParticipantsItemOptionsProps {
insideHandRaiseGroup: boolean;
Expand All @@ -33,12 +36,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
(state: RootState) => state.hmsStates.localPeer?.role?.permissions
);

const roles = useSelector((state: RootState) => state.hmsStates.roles);

const localPeerCanMuteTrack =
localPeerPermissions && localPeerPermissions.mute;
const localPeerCanUnmuteTrack =
localPeerPermissions && localPeerPermissions.unmute;
const localPeerCanRemove =
localPeerPermissions && localPeerPermissions.removeOthers;
const localPeerCanChangeRole =
localPeerPermissions && localPeerPermissions.changeRole && roles.length > 1;

// Selected Peer Permissions related states
const peerCanPublishAudio = selectCanPublishTrackForRole(peer.role!, 'audio');
Expand Down Expand Up @@ -153,6 +160,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
onItemPress();
};

const { handleModalVisibleType: setModalVisible } = useModalType();

const dispatch = useDispatch();

const handleChangeRolePress = () => {
setModalVisible(ModalTypes.CHANGE_ROLE, true);
dispatch(setPeerToUpdate(peer));
onItemPress();
};

const showMuteAudioOption =
!insideHandRaiseGroup &&
localPeerCanMuteTrack &&
Expand Down Expand Up @@ -249,6 +266,16 @@ const _ParticipantsItemOptions: React.FC<ParticipantsItemOptionsProps> = ({
isActive: false,
hide: Boolean(!onStageRoleStr || peer.role?.name !== onStageRoleStr),
},
{
id: 'change-role',
icon: (
<PersonIcon type="rectangle" style={{ width: 20, height: 20 }} />
),
label: 'Switch Role',
pressHandler: handleChangeRolePress,
isActive: false,
hide: !localPeerCanChangeRole,
},
{
id: 'remove-participant',
icon: <PersonIcon type="left" style={{ width: 20, height: 20 }} />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { HMSPeerType, HMSTrack } from '@100mslive/react-native-hms';
import type { RootState } from '../redux';
import type { PeerTrackNode } from '../utils/types';
import { ModalTypes } from '../utils/types';
import { setInsetViewMinimized } from '../redux/actions';
import { setInsetViewMinimized, setPeerToUpdate } from '../redux/actions';
import { useHMSRoomStyle, useModalType } from '../hooks-util';
import {
CameraIcon,
Expand All @@ -40,6 +40,7 @@ export const PeerSettingsModalContent: React.FC<
> = ({ peerTrackNode, peerTrackNodesListEmpty, cancelModal }) => {
const dispatch = useDispatch();
const hmsInstance = useSelector((state: RootState) => state.user.hmsInstance);
const allRoles = useSelector((state: RootState) => state.hmsStates.roles);
const localPeer = useSelector(
(state: RootState) => state.hmsStates.localPeer
);
Expand Down Expand Up @@ -92,6 +93,11 @@ export const PeerSettingsModalContent: React.FC<
);
};

const switchRole = () => {
setModalVisible(ModalTypes.CHANGE_ROLE, true);
dispatch(setPeerToUpdate(peerTrackNode.peer));
};

const changeName = () => {
setModalVisible(ModalTypes.CHANGE_NAME, true);
};
Expand Down Expand Up @@ -194,6 +200,16 @@ export const PeerSettingsModalContent: React.FC<
</>
) : null}

{allRoles.length > 1 &&
!peer.isLocal &&
localPeerPermissions?.changeRole ? (
<SettingItem
text={'Switch Role'}
icon={<PersonIcon type="rectangle" style={styles.customIcon} />}
onPress={switchRole}
/>
) : null}

{!peer.isLocal && localPeerPermissions?.removeOthers ? (
<SettingItem
text="Remove Participant"
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-room-kit/src/components/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ const styles = StyleSheet.create({
padding: 8,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
marginTop: 24,
borderWidth: 1,
Expand Down
Loading

0 comments on commit 3d406db

Please sign in to comment.