import React, { Fragment, useState } from 'react'; import { HMSHLSPlayer } from '@100mslive/hls-player'; import { ConferencingScreen, DefaultConferencingScreen_Elements, HLSLiveStreamingScreen_Elements, } from '@100mslive/types-prebuilt'; import { match } from 'ts-pattern'; import { HMSTranscriptionMode, selectAppData, selectIsTranscriptionAllowedByMode, selectIsTranscriptionEnabled, selectLocalPeerID, useHMSActions, useHMSStore, } from '@100mslive/react-sdk'; import { BrbIcon, CheckIcon, HamburgerMenuIcon, InfoIcon, OpenCaptionIcon, PipIcon, SettingsIcon, } from '@100mslive/react-icons'; import { Checkbox, Dropdown, Flex, Switch, Text, Tooltip } from '../../../..'; import IconButton from '../../../IconButton'; // @ts-ignore: No implicit any import { PIP } from '../../PIP'; import { PIPChat } from '../../PIP/PIPChat'; // @ts-ignore: No implicit any import { PIPChatOption } from '../../PIP/PIPChatOption'; import { PictureInPicture } from '../../PIP/PIPManager'; import { PIPWindow } from '../../PIP/PIPWindow'; // @ts-ignore: No implicit any import { RoleChangeModal } from '../../RoleChangeModal'; // @ts-ignore: No implicit any import SettingsModal from '../../Settings/SettingsModal'; // @ts-ignore: No implicit any import StartRecording from '../../Settings/StartRecording'; // @ts-ignore: No implicit any import { StatsForNerds } from '../../StatsForNerds'; // @ts-ignore: No implicit any import { BulkRoleChangeModal } from '../BulkRoleChangeModal'; import { CaptionModal } from '../CaptionModal'; // @ts-ignore: No implicit any import { FullScreenItem } from '../FullScreenItem'; import { MuteAllModal } from '../MuteAllModal'; // @ts-ignore: No implicit any import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../../AppData/useSidepane'; // @ts-ignore: No implicit any import { useDropdownList } from '../../hooks/useDropdownList'; import { useMyMetadata } from '../../hooks/useMetadata'; // @ts-ignore: No implicit any import { usePIPChat } from '../../PIP/usePIPChat'; // @ts-ignore: No implicit any import { APP_DATA, isMacOS, SIDE_PANE_OPTIONS } from '../../../common/constants'; const MODALS = { CHANGE_NAME: 'changeName', SELF_ROLE_CHANGE: 'selfRoleChange', MORE_SETTINGS: 'moreSettings', START_RECORDING: 'startRecording', DEVICE_SETTINGS: 'deviceSettings', STATS_FOR_NERDS: 'statsForNerds', BULK_ROLE_CHANGE: 'bulkRoleChange', MUTE_ALL: 'muteAll', EMBED_URL: 'embedUrl', CAPTION: 'caption', }; export const DesktopOptions = ({ elements, screenType, }: { elements: DefaultConferencingScreen_Elements & HLSLiveStreamingScreen_Elements; screenType: keyof ConferencingScreen; }) => { const localPeerId = useHMSStore(selectLocalPeerID); const hmsActions = useHMSActions(); const enablHlsStats = useHMSStore(selectAppData(APP_DATA.hlsStats)); const [openModals, setOpenModals] = useState(new Set()); const { isBRBOn, toggleBRB } = useMyMetadata(); const isPipOn = PictureInPicture.isOn(); const isBRBEnabled = !!elements?.brb; const isTranscriptionAllowed = useHMSStore(selectIsTranscriptionAllowedByMode(HMSTranscriptionMode.CAPTION)); const isTranscriptionEnabled = useHMSStore(selectIsTranscriptionEnabled); const { isSupported, pipWindow, requestPipWindow } = usePIPChat(); const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT); const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT); // Hide if pip chat is already open const showPipChatOption = !!elements?.chat && isSupported && !pipWindow; useDropdownList({ open: openModals.size > 0, name: 'MoreSettings' }); const updateState = (modalName: string, value: boolean) => { setOpenModals(modals => { const copy = new Set(modals); if (value) { // avoiding extra set state trigger which removes currently open dialog by clearing set. copy.clear(); copy.add(modalName); } else { copy.delete(modalName); } return copy; }); }; return ( {isSupported && pipWindow ? ( ) : null} updateState(MODALS.MORE_SETTINGS, value)} modal={false} > { e.preventDefault(); }} align="end" css={{ py: '$0', maxHeight: 'unset', '@md': { w: '$64' }, "div[role='separator']:first-child": { display: 'none', }, }} > {isBRBEnabled && screenType !== 'hls_live_streaming' ? ( Be Right Back {isBRBOn ? : null} ) : null} {isTranscriptionAllowed ? ( { updateState(MODALS.CAPTION, true); }} > Closed Captions {isTranscriptionEnabled ? 'Enabled' : 'Disabled'} ) : null} {screenType !== 'hls_live_streaming' ? ( {isPipOn ? 'Disable' : 'Enable'} Picture-in-Picture } /> ) : null} { isChatOpen && toggleChat(); await requestPipWindow(350, 500); }} /> updateState(MODALS.DEVICE_SETTINGS, true)} data-testid="device_settings_btn"> Settings {match({ screenType, isSupported: HMSHLSPlayer.isSupported() }) .with({ screenType: 'hls_live_streaming', isSupported: false }, () => null) .with({ screenType: 'hls_live_streaming', isSupported: true }, () => { return ( hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)} data-testid="hls_stats" > hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)} > Show HLS Stats {`${isMacOS ? '⌘' : 'ctrl'} + ]`} ); }) .otherwise(() => ( updateState(MODALS.STATS_FOR_NERDS, true)} data-testid="stats_for_nerds_btn" > Stats for Nerds ))} {openModals.has(MODALS.BULK_ROLE_CHANGE) && ( updateState(MODALS.BULK_ROLE_CHANGE, value)} /> )} {openModals.has(MODALS.MUTE_ALL) && ( updateState(MODALS.MUTE_ALL, value)} /> )} {openModals.has(MODALS.START_RECORDING) && ( updateState(MODALS.START_RECORDING, value)} /> )} {openModals.has(MODALS.DEVICE_SETTINGS) && ( updateState(MODALS.DEVICE_SETTINGS, value)} screenType={screenType} /> )} {openModals.has(MODALS.STATS_FOR_NERDS) && ( updateState(MODALS.STATS_FOR_NERDS, value)} /> )} {openModals.has(MODALS.SELF_ROLE_CHANGE) && ( updateState(MODALS.SELF_ROLE_CHANGE, value)} /> )} {openModals.has(MODALS.CAPTION) && ( updateState(MODALS.CAPTION, value)} /> )} {/* {openModals.has(MODALS.EMBED_URL) && ( updateState(MODALS.EMBED_URL, value)} /> )} */} ); };