import React, { useState } from 'react'; import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt'; import { match } from 'ts-pattern'; import { HMSPeer, selectPermissions, selectRoleByRoleName, selectTracksMap, useHMSActions, useHMSStore, } from '@100mslive/react-sdk'; import { MicOffIcon, MicOnIcon, PersonRectangleIcon, RemoveUserIcon, VerticalMenuIcon, VideoOffIcon, VideoOnIcon, } from '@100mslive/react-icons'; import { Dropdown } from '../../../Dropdown'; import { Flex } from '../../../Layout'; import { Text } from '../../../Text'; import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen'; // @ts-ignore: No implicit Any import { getMetadata } from '../../common/utils'; const dropdownItemCSS = { backgroundColor: '$surface_default', gap: '$4', p: '$8' }; const optionTextCSS = { fontWeight: '$semiBold', color: '$on_surface_high', textTransform: 'none', whiteSpace: 'nowrap', }; const DropdownWrapper = ({ children }: { children: React.ReactNode }) => { const [openOptions, setOpenOptions] = useState(false); if (React.Children.toArray(children).length === 0) { return null; } return ( e.stopPropagation()} className="role_actions" asChild css={{ p: '$1', r: '$0', c: '$on_surface_high', visibility: openOptions ? 'visible' : 'hidden', '&:hover': { c: '$on_surface_medium', }, '@md': { visibility: 'visible', }, }} > e.stopPropagation()} css={{ w: 'max-content', bg: '$surface_default', py: 0 }} align="end" > {children} ); }; export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList: HMSPeer[] }) => { const permissions = useHMSStore(selectPermissions); const hmsActions = useHMSActions(); const { elements } = useRoomLayoutConferencingScreen(); const { on_stage_role, off_stage_roles = [] } = (elements as DefaultConferencingScreen_Elements)?.on_stage_exp || {}; const canRemoveRoleFromStage = permissions?.changeRole && roleName === on_stage_role; const role = useHMSStore(selectRoleByRoleName(roleName)); const tracks = useHMSStore(selectTracksMap); if (!role) { return null; } const canPublishAudio = role.publishParams.allowed.includes('audio'); const canPublishVideo = role.publishParams.allowed.includes('video'); let isVideoOnForSomePeers = false; let isAudioOnForSomePeers = false; peerList.forEach(peer => { if (peer.isLocal) { return; } const isAudioOn = !!peer.audioTrack && tracks[peer.audioTrack]?.enabled; const isVideoOn = !!peer.videoTrack && tracks[peer.videoTrack]?.enabled; isAudioOnForSomePeers = isAudioOnForSomePeers || isAudioOn; isVideoOnForSomePeers = isVideoOnForSomePeers || isVideoOn; }); const setTrackEnabled = async (type: 'audio' | 'video', enabled = false) => { try { await hmsActions.setRemoteTracksEnabled({ roles: [roleName], source: 'regular', type, enabled }); } catch (e) { console.error(e); } }; // on stage and off stage roles const canRemoveRoleFromRoom = permissions?.removeOthers && (on_stage_role === roleName || off_stage_roles?.includes(roleName)); if ( peerList.length === 0 || // if only local peer is present no need to show any options (peerList.length === 1 && peerList[0].isLocal) || !role ) { return null; } const removeAllFromStage = () => { peerList.forEach(peer => { const prevRole = getMetadata(peer.metadata).prevRole; if (prevRole) { hmsActions.changeRoleOfPeer(peer.id, prevRole, true); } }); }; const removePeersFromRoom = async () => { try { peerList.forEach(async peer => { await hmsActions.removePeer(peer.id, ''); }); } catch (e) { console.error(e); } }; return ( {canRemoveRoleFromStage ? ( Remove all from Stage ) : null} {match({ canPublishAudio, isAudioOnForSomePeers, canMute: permissions?.mute, canUnmute: permissions?.unmute }) .with({ canPublishAudio: true, isAudioOnForSomePeers: true, canMute: true }, () => { return ( setTrackEnabled('audio', false)}> Mute Audio for All ); }) .with({ canPublishAudio: true, isAudioOnForSomePeers: false, canUnmute: true }, () => { return ( setTrackEnabled('audio', true)}> Request to Unmute Audio for All ); }) .otherwise(() => null)} {match({ canPublishVideo, isVideoOnForSomePeers, canMute: permissions?.mute, canUnmute: permissions?.unmute }) .with({ canPublishVideo: true, isVideoOnForSomePeers: true, canMute: true }, () => { return ( setTrackEnabled('video', false)}> Mute Video for All ); }) .with({ canPublishVideo: true, isVideoOnForSomePeers: false, canUnmute: true }, () => { return ( setTrackEnabled('video', true)}> Request to Unmute Video for All ); }) .otherwise(() => null)} {canRemoveRoleFromRoom ? ( Remove all from Room ) : null} ); };