import React, { useRef, useState } from 'react'; import { useClickAway } from 'react-use'; import { ConferencingScreen, DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt'; import { match } from 'ts-pattern'; import { HMSTranscriptionMode, selectIsConnectedToRoom, selectIsLocalVideoEnabled, selectIsTranscriptionAllowedByMode, selectIsTranscriptionEnabled, selectPeerCount, selectPermissions, useHMSActions, useHMSStore, useRecordingStreaming, } from '@100mslive/react-sdk'; import { BrbIcon, ClosedCaptionIcon, CrossIcon, EmojiIcon, HamburgerMenuIcon, HandIcon, HandRaiseSlashedIcon, InfoIcon, OpenCaptionIcon, PeopleIcon, QuizActiveIcon, QuizIcon, RecordIcon, SettingsIcon, VirtualBackgroundIcon, } from '@100mslive/react-icons'; import { Box, Loading, Tooltip } from '../../../..'; import { Sheet } from '../../../../Sheet'; // @ts-ignore: No implicit any import IconButton from '../../../IconButton'; import { NoiseCancellation } from '../../AudioVideoToggle'; // @ts-ignore: No implicit any import { EmojiReaction } from '../../EmojiReaction'; // @ts-ignore: No implicit any import { StopRecordingInSheet } from '../../Header/StreamActions'; // @ts-ignore: No implicit any import SettingsModal from '../../Settings/SettingsModal'; // @ts-ignore: No implicit any import { StatsForNerds } from '../../StatsForNerds'; // @ts-ignore: No implicit any import { ToastManager } from '../../Toast/ToastManager'; // @ts-ignore: No implicit any import { ActionTile } from '../ActionTile'; import { CaptionModal } from '../CaptionModal'; // @ts-ignore: No implicit any import { ChangeNameModal } from '../ChangeNameModal'; // @ts-ignore: No implicit any import { MuteAllModal } from '../MuteAllModal'; import { useRoomLayoutHeader } from '../../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen'; import { useSheetToggle } from '../../AppData/useSheet'; // @ts-ignore: No implicit any import { usePollViewToggle, useSidepaneToggle } from '../../AppData/useSidepane'; // @ts-ignore: No implicit Any import { useSetIsCaptionEnabled, useShowPolls } from '../../AppData/useUISettings'; // @ts-ignore: No implicit any import { useDropdownList } from '../../hooks/useDropdownList'; import { useMyMetadata } from '../../hooks/useMetadata'; import { useUnreadPollQuizPresent } from '../../hooks/useUnreadPollQuizPresent'; import { useLandscapeHLSStream, useMobileHLSStream, useRecordingHandler } from '../../../common/hooks'; // @ts-ignore: No implicit any import { getFormattedCount } from '../../../common/utils'; // @ts-ignore: No implicit any import { SHEET_OPTIONS, 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 MwebOptions = ({ elements, screenType, }: { elements: DefaultConferencingScreen_Elements; screenType: keyof ConferencingScreen; }) => { const hmsActions = useHMSActions(); const permissions = useHMSStore(selectPermissions); const isConnected = useHMSStore(selectIsConnectedToRoom); const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming(); const [openModals, setOpenModals] = useState(new Set()); const [openOptionsSheet, setOpenOptionsSheet] = useState(false); const [openSettingsSheet, setOpenSettingsSheet] = useState(false); const [openStatsForNerdsSheet, setOpenStatsForNerdsSheet] = useState(false); const [showEmojiCard, setShowEmojiCard] = useState(false); const [showRecordingOn, setShowRecordingOn] = useState(false); const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS); const { showPolls } = useShowPolls(); const togglePollView = usePollViewToggle(); const peerCount = useHMSStore(selectPeerCount); const emojiCardRef = useRef(null); const { isBRBOn, toggleBRB, isHandRaised, toggleHandRaise } = useMyMetadata(); const { unreadPollQuiz, setUnreadPollQuiz } = useUnreadPollQuizPresent(); const { title, description } = useRoomLayoutHeader(); const toggleDetailsSheet = useSheetToggle(SHEET_OPTIONS.ROOM_DETAILS); const isMobileHLSStream = useMobileHLSStream(); const isLandscapeHLSStream = useLandscapeHLSStream(); const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB); const isLocalVideoEnabled = useHMSStore(selectIsLocalVideoEnabled); const { startRecording, isRecordingLoading } = useRecordingHandler(); const isTranscriptionAllowed = useHMSStore(selectIsTranscriptionAllowedByMode(HMSTranscriptionMode.CAPTION)); const isTranscriptionEnabled = useHMSStore(selectIsTranscriptionEnabled); const [isCaptionEnabled] = useSetIsCaptionEnabled(); useDropdownList({ open: openModals.size > 0 || openOptionsSheet || openSettingsSheet, name: 'MoreSettings' }); const updateState = (modalName: string, value: boolean) => { setOpenModals(modals => { const copy = new Set(modals); if (value) { copy.add(modalName); } else { copy.delete(modalName); } return copy; }); }; useClickAway(emojiCardRef, () => setShowEmojiCard(false)); return ( <> Options {elements?.participant_list && ( { toggleParticipants(); setOpenOptionsSheet(false); }} > {getFormattedCount(peerCount)} Participants )} {elements.hand_raise ? ( { toggleHandRaise(); setOpenOptionsSheet(false); }} > {isHandRaised ? : } {isHandRaised ? 'Lower' : 'Raise'} Hand ) : null} {isTranscriptionAllowed ? ( { setOpenOptionsSheet(false); updateState(MODALS.CAPTION, true); }} > {isTranscriptionEnabled && isCaptionEnabled ? : } Closed Caption ) : null} {isLocalVideoEnabled && !!elements?.virtual_background ? ( { toggleVB(); setOpenOptionsSheet(false); }} > Virtual Background ) : null} {elements?.emoji_reactions && !(isLandscapeHLSStream || isMobileHLSStream) && ( { setShowEmojiCard(true); setOpenOptionsSheet(false); }} > Emoji Reactions )} {showPolls && ( { togglePollView(); setOpenOptionsSheet(false); setUnreadPollQuiz(false); }} > {unreadPollQuiz ? : } Polls and Quizzes )} {elements?.brb && ( { toggleBRB(); setOpenOptionsSheet(false); }} > Be Right Back )} { setOpenSettingsSheet(true); setOpenOptionsSheet(false); }} > Settings { setOpenStatsForNerdsSheet(true); setOpenOptionsSheet(false); }} > Stats For Nerds {isConnected && permissions?.browserRecording ? ( { if (isRecordingLoading) { return; } if (isBrowserRecordingOn || isStreamingOn) { setOpenOptionsSheet(false); setShowRecordingOn(true); } else { // start recording await startRecording(); setOpenOptionsSheet(false); } if (isHLSRunning) { setOpenOptionsSheet(false); } }} > {isRecordingLoading ? : } {match({ isBrowserRecordingOn, isRecordingLoading }) .with({ isBrowserRecordingOn: true, isRecordingLoading: false }, () => 'Recording On') .with({ isRecordingLoading: true }, () => 'Starting Recording') .with({ isRecordingLoading: false }, () => 'Start Recording') .otherwise(() => null)} ) : null} {title || description ? ( { setOpenOptionsSheet(false); toggleDetailsSheet(); }} > About Session ) : null} {openStatsForNerdsSheet && ( )} {openModals.has(MODALS.MUTE_ALL) && ( updateState(MODALS.MUTE_ALL, value)} isMobile /> )} {openModals.has(MODALS.CHANGE_NAME) && ( updateState(MODALS.CHANGE_NAME, value)} openParentSheet={() => setOpenOptionsSheet(true)} /> )} {openModals.has(MODALS.CAPTION) && ( updateState(MODALS.CAPTION, value)} /> )} {showEmojiCard && ( )} {showRecordingOn && ( setShowRecordingOn(false)} onStopRecording={async () => { try { await hmsActions.stopRTMPAndRecording(); setShowRecordingOn(false); } catch (error) { ToastManager.addToast({ // @ts-ignore title: error.message, variant: 'error', }); } }} /> )} ); };