UNPKG

mediasfu-reactnative-expo

Version:

mediasfu-reactnative-expo – Expo-managed React Native WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms on iOS, Android, and web. Prebuilt r

773 lines 193 kB
import { StatusBar } from "expo-status-bar"; import React, { useEffect, useState, useRef } from "react"; import { Text, View, Platform, Dimensions } from "react-native"; import Orientation from "react-native-orientation-locker"; import { SafeAreaProvider } from "react-native-safe-area-context"; import Constants from "expo-constants"; import { Camera } from "expo-camera"; import { FontAwesome5, MaterialIcons } from "@expo/vector-icons"; // initial values import { initialValuesState } from "../../methods/utils/initialValuesState"; // import components for display (samples) import MainAspectComponent from "../../components/displayComponents/MainAspectComponent"; import LoadingModal from "../../components/displayComponents/LoadingModal"; import ControlButtonsComponent from "../../components/displayComponents/ControlButtonsComponent"; import ControlButtonsAltComponent from "../../components/displayComponents/ControlButtonsAltComponent"; import OthergridComponent from "../../components/displayComponents/OtherGridComponent"; import MainScreenComponent from "../../components/displayComponents/MainScreenComponent"; import MainGridComponent from "../../components/displayComponents/MainGridComponent"; import SubAspectComponent from "../../components/displayComponents/SubAspectComponent"; import MainContainerComponent from "../../components/displayComponents/MainContainerComponent"; import AlertComponent from "../../components/displayComponents/AlertComponent"; import MenuModal from "../../components/menuComponents/MenuModal"; import RecordingModal from "../../components/recordingComponents/RecordingModal"; import RequestsModal from "../../components/requestsComponents/RequestsModal"; import WaitingRoomModal from "../../components/waitingComponents/WaitingModal"; import DisplaySettingsModal from "../../components/displaySettingsComponents/DisplaySettingsModal"; import EventSettingsModal from "../../components/eventSettingsComponents/EventSettingsModal"; import CoHostModal from "../../components/coHostComponents/CoHostModal"; import ParticipantsModal from "../../components/participantsComponents/ParticipantsModal"; import MessagesModal from "../../components/messageComponents/MessagesModal"; import MediaSettingsModal from "../../components/mediaSettingsComponents/MediaSettingsModal"; import ConfirmExitModal from "../../components/exitComponents/ConfirmExitModal"; import ConfirmHereModal from "../../components/miscComponents/ConfirmHereModal"; import ShareEventModal from "../../components/miscComponents/ShareEventModal"; import WelcomePage from "../../components/miscComponents/WelcomePage"; import PollModal from "../../components/pollsComponents/PollModal"; import BreakoutRoomsModal from "../../components/breakoutComponents/BreakoutRoomsModal"; import ConfigureWhiteboardModal from "../../components/whiteboardComponents/ConfigureWhiteboardModal"; import Whiteboard from "../../components/whiteboardComponents/Whiteboard"; import Screenboard from "../../components/screenboardComponents/Screenboard"; import ScreenboardModal from "../../components/screenboardComponents/ScreenboardModal"; // pagination and display of media (samples) import Pagination from "../../components/displayComponents/Pagination"; import FlexibleGrid from "../../components/displayComponents/FlexibleGrid"; import FlexibleVideo from "../../components/displayComponents/FlexibleVideo"; import AudioGrid from "../../components/displayComponents/AudioGrid"; // import methods for control (samples) import { launchMenuModal } from "../../methods/menuMethods/launchMenuModal"; import { launchRecording } from "../../methods/recordingMethods/launchRecording"; import { startRecording } from "../../methods/recordingMethods/startRecording"; import { confirmRecording } from "../../methods/recordingMethods/confirmRecording"; import { launchWaiting } from "../../methods/waitingMethods/launchWaiting"; import { launchCoHost } from "../../methods/coHostMethods/launchCoHost"; import { launchMediaSettings } from "../../methods/mediaSettingsMethods/launchMediaSettings"; import { launchDisplaySettings } from "../../methods/displaySettingsMethods/launchDisplaySettings"; import { launchSettings } from "../../methods/settingsMethods/launchSettings"; import { launchRequests } from "../../methods/requestsMethods/launchRequests"; import { launchParticipants } from "../../methods/participantsMethods/launchParticipants"; import { launchMessages } from "../../methods/messageMethods/launchMessages"; import { launchConfirmExit } from "../../methods/exitMethods/launchConfirmExit"; import { launchPoll } from "../../methods/pollsMethods/launchPoll"; import { launchBreakoutRooms } from "../../methods/breakoutRoomsMethods/launchBreakoutRooms"; // Import the platform-specific WebRTC module (options are for ios, android, web) import { mediaDevices, registerGlobals, MediaStream as NativeMediaStream, MediaStreamTrack, } from "../../methods/utils/webrtc/webrtc"; // mediasfu functions -- examples import { connectSocket, connectLocalSocket } from "../../sockets/SocketManager"; import { joinRoomClient } from "../../ProducerClient/producerClientEmits/joinRoomClient"; import { joinLocalRoom } from "../../producers/producerEmits/joinLocalRoom"; import { updateRoomParametersClient } from "../../ProducerClient/producerClientEmits/updateRoomParametersClient"; import { createDeviceClient } from "../../ProducerClient/producerClientEmits/createDeviceClient"; import { clickVideo } from "../../methods/streamMethods/clickVideo"; import { clickAudio } from "../../methods/streamMethods/clickAudio"; import { clickScreenShare } from "../../methods/streamMethods/clickScreenShare"; import { streamSuccessVideo } from "../../consumers/streamSuccessVideo"; import { streamSuccessAudio } from "../../consumers/streamSuccessAudio"; import { streamSuccessScreen } from "../../consumers/streamSuccessScreen"; import { streamSuccessAudioSwitch } from "../../consumers/streamSuccessAudioSwitch"; import { checkPermission } from "../../consumers/checkPermission"; // mediasfu functions import { updateMiniCardsGrid } from "../../consumers/updateMiniCardsGrid"; import { mixStreams } from "../../consumers/mixStreams"; import { dispStreams } from "../../consumers/dispStreams"; import { stopShareScreen } from "../../consumers/stopShareScreen"; import { checkScreenShare } from "../../consumers/checkScreenShare"; import { startShareScreen } from "../../consumers/startShareScreen"; import { requestScreenShare } from "../../consumers/requestScreenShare"; import { reorderStreams } from "../../consumers/reorderStreams"; import { prepopulateUserMedia } from "../../consumers/prepopulateUserMedia"; import { getVideos } from "../../consumers/getVideos"; import { rePort } from "../../consumers/rePort"; import { trigger } from "../../consumers/trigger"; import { consumerResume } from "../../consumers/consumerResume"; import { connectSendTransportAudio } from "../../consumers/connectSendTransportAudio"; import { connectSendTransportVideo } from "../../consumers/connectSendTransportVideo"; import { connectSendTransportScreen } from "../../consumers/connectSendTransportScreen"; import { processConsumerTransports } from "../../consumers/processConsumerTransports"; import { resumePauseStreams } from "../../consumers/resumePauseStreams"; import { readjust } from "../../consumers/readjust"; import { checkGrid } from "../../consumers/checkGrid"; import { getEstimate } from "../../consumers/getEstimate"; import { calculateRowsAndColumns } from "../../consumers/calculateRowsAndColumns"; import { addVideosGrid } from "../../consumers/addVideosGrid"; import { onScreenChanges } from "../../consumers/onScreenChanges"; import { sleep } from "../../methods/utils/sleep"; import { changeVids } from "../../consumers/changeVids"; import { compareActiveNames } from "../../consumers/compareActiveNames"; import { compareScreenStates } from "../../consumers/compareScreenStates"; import { createSendTransport } from "../../consumers/createSendTransport"; import { resumeSendTransportAudio } from "../../consumers/resumeSendTransportAudio"; import { receiveAllPipedTransports } from "../../consumers/receiveAllPipedTransports"; import { disconnectSendTransportVideo } from "../../consumers/disconnectSendTransportVideo"; import { disconnectSendTransportAudio } from "../../consumers/disconnectSendTransportAudio"; import { disconnectSendTransportScreen } from "../../consumers/disconnectSendTransportScreen"; import { connectSendTransport } from "../../consumers/connectSendTransport"; import { getPipedProducersAlt } from "../../consumers/getPipedProducersAlt"; import { signalNewConsumerTransport } from "../../consumers/signalNewConsumerTransport"; import { connectRecvTransport } from "../../consumers/connectRecvTransport"; import { reUpdateInter } from "../../consumers/reUpdateInter"; import { updateParticipantAudioDecibels } from "../../consumers/updateParticipantAudioDecibels"; import { closeAndResize } from "../../consumers/closeAndResize"; import { autoAdjust } from "../../consumers/autoAdjust"; import { switchUserVideoAlt } from "../../consumers/switchUserVideoAlt"; import { switchUserVideo } from "../../consumers/switchUserVideo"; import { switchUserAudio } from "../../consumers/switchUserAudio"; import { receiveRoomMessages } from "../../consumers/receiveRoomMessages"; import { formatNumber } from "../../methods/utils/formatNumber"; import { connectIps } from "../../consumers/connectIps"; import { connectLocalIps } from "../../consumers/connectLocalIps"; import { pollUpdated } from "../../methods/pollsMethods/pollUpdated"; import { handleCreatePoll } from "../../methods/pollsMethods/handleCreatePoll"; import { handleEndPoll } from "../../methods/pollsMethods/handleEndPoll"; import { handleVotePoll } from "../../methods/pollsMethods/handleVotePoll"; import { breakoutRoomUpdated } from "../../methods/breakoutRoomsMethods/breakoutRoomUpdated"; import { startMeetingProgressTimer } from "../../methods/utils/meetingTimer/startMeetingProgressTimer"; import { updateRecording } from "../../methods/recordingMethods/updateRecording"; import { stopRecording } from "../../methods/recordingMethods/stopRecording"; import { userWaiting } from "../../producers/socketReceiveMethods/userWaiting"; import { personJoined } from "../../producers/socketReceiveMethods/personJoined"; import { allWaitingRoomMembers } from "../../producers/socketReceiveMethods/allWaitingRoomMembers"; import { roomRecordParams } from "../../producers/socketReceiveMethods/roomRecordParams"; import { banParticipant } from "../../producers/socketReceiveMethods/banParticipant"; import { updatedCoHost } from "../../producers/socketReceiveMethods/updatedCoHost"; import { participantRequested } from "../../producers/socketReceiveMethods/participantRequested"; import { screenProducerId } from "../../producers/socketReceiveMethods/screenProducerId"; import { updateMediaSettings } from "../../producers/socketReceiveMethods/updateMediaSettings"; import { producerMediaPaused } from "../../producers/socketReceiveMethods/producerMediaPaused"; import { producerMediaResumed } from "../../producers/socketReceiveMethods/producerMediaResumed"; import { producerMediaClosed } from "../../producers/socketReceiveMethods/producerMediaClosed"; import { controlMediaHost } from "../../producers/socketReceiveMethods/controlMediaHost"; import { meetingEnded } from "../../producers/socketReceiveMethods/meetingEnded"; import { disconnectUserSelf } from "../../producers/socketReceiveMethods/disconnectUserSelf"; import { receiveMessage } from "../../producers/socketReceiveMethods/receiveMessage"; import { meetingTimeRemaining } from "../../producers/socketReceiveMethods/meetingTimeRemaining"; import { meetingStillThere } from "../../producers/socketReceiveMethods/meetingStillThere"; import { startRecords } from "../../producers/socketReceiveMethods/startRecords"; import { reInitiateRecording } from "../../producers/socketReceiveMethods/reInitiateRecording"; import { getDomains } from "../../producers/socketReceiveMethods/getDomains"; import { updateConsumingDomains } from "../../producers/socketReceiveMethods/updateConsumingDomains"; import { recordingNotice } from "../../producers/socketReceiveMethods/recordingNotice"; import { timeLeftRecording } from "../../producers/socketReceiveMethods/timeLeftRecording"; import { stoppedRecording } from "../../producers/socketReceiveMethods/stoppedRecording"; import { hostRequestResponse } from "../../producers/socketReceiveMethods/hostRequestResponse"; import { allMembers } from "../../producers/socketReceiveMethods/allMembers"; import { allMembersRest } from "../../producers/socketReceiveMethods/allMembersRest"; import { disconnect } from "../../producers/socketReceiveMethods/disconnect"; import { captureCanvasStream } from "../../methods/whiteboardMethods/captureCanvasStream"; import { resumePauseAudioStreams } from "../../consumers/resumePauseAudioStreams"; import { processConsumerTransportsAudio } from "../../consumers/processConsumerTransportsAudio"; import { withOverride, withFunctionOverride } from "./overrideHelpers"; import { createResponseJoinRoom } from "../../methods/utils/createResponseJoinRoom"; /** * MediasfuConference component optimizes the media experience for conferences. * Participants can share media (audio, video, screen share) with each other. * Participants can chat with each other and engage in polls and breakout rooms, share screens, and more during the conference. * * @typedef {Object} MediasfuConferenceOptions * @property {function} [PrejoinPage=WelcomePage] - Function to render the prejoin page. * @property {string} [localLink=""] - Local link for the media server (if using Community Edition). * @property {boolean} [connectMediaSFU=true] - Flag to connect to the MediaSFU server (if using Community Edition and still need to connect to the server) * @property {Object} [credentials={ apiUserName: "", apiKey: "" }] - API credentials. * @property {boolean} [useLocalUIMode=false] - Flag to use local UI mode. * @property {SeedData} [seedData={}] - Seed data for initial state. * @property {boolean} [useSeed=false] - Flag to use seed data. * @property {string} [imgSrc="https://mediasfu.com/images/logo192.png"] - Image source URL. * @property {Object} [sourceParameters={}] - Source parameters. * @property {function} [updateSourceParameters] - Function to update source parameters. * @property {boolean} [returnUI=true] - Flag to return the UI. * @property {CreateMediaSFURoomOptions | JoinMediaSFURoomOptions} [noUIPreJoinOptions] - Options for the prejoin page. * @property {JoinRoomOnMediaSFUType} [joinMediaSFURoom] - Function to join a room on MediaSFU. * @property {CreateRoomOnMediaSFUType} [createMediaSFURoom] - Function to create a room on MediaSFU. * @property {CustomVideoCardType} [customVideoCard] - Custom video card component. * @property {CustomAudioCardType} [customAudioCard] - Custom audio card component. * @property {CustomMiniCardType} [customMiniCard] - Custom mini card component. * @property {React.ReactNode} [customComponent] - Custom main component to replace the entire UI. * * @typedef {Object} SeedData - Data structure to populate initial state in the MediasfuConference. * @property {string} [member] - The member name. * @property {string} [host] - The host name. * @property {EventType} [eventType] - The type of event. * @property {Participant[]} [participants] - The list of participants. * @property {Message[]} [messages] - The list of messages. * @property {Poll[]} [polls] - The list of polls. * @property {BreakoutParticipant[][]} [breakoutRooms] - The list of breakout rooms. * @property {Request[]} [requests] - The list of requests. * @property {WaitingRoomParticipant[]} [waitingList] - The list of waiting room participants. * @property {WhiteboardUser[]} [whiteboardUsers] - The list of whiteboard users. * * @component * @param {MediasfuConferenceOptions} props - Component properties. * @returns {React.FC<MediasfuConferenceOptions>} The MediasfuConference component. * * @example * ```tsx * <MediasfuConference * PrejoinPage={WelcomePage} * credentials={{ apiUserName: "username", apiKey: "apikey" }} * useLocalUIMode={false} * seedData={{}} * useSeed={false} * imgSrc="https://mediasfu.com/images/logo192.png" * sourceParameters={{ key: value }} * updateSourceParameters={updateSourceParameters} * returnUI={true} * noUIPreJoinOptions={customPreJoinOptions} * joinMediaSFURoom={joinRoomOnMediaSFU} * createMediaSFURoom={createRoomOnMediaSFU} * /> * ``` * * @description * This component handles the main logic for joining a media conference room using WebRTC and Mediasoup. * It manages the state and references for various parameters required for the conference, including * user credentials, room details, media settings, and recording options. * * The component also provides methods for updating state to initial values, joining a room using a socket, * and handling various media and room-related functionalities. */ const MediasfuConference = ({ PrejoinPage = WelcomePage, localLink = "", connectMediaSFU = true, credentials = { apiUserName: "", apiKey: "" }, useLocalUIMode = false, seedData = {}, useSeed = false, imgSrc = "https://mediasfu.com/images/logo192.png", sourceParameters, updateSourceParameters, returnUI = true, noUIPreJoinOptions, joinMediaSFURoom, createMediaSFURoom, customVideoCard, customAudioCard, customMiniCard, customComponent, containerStyle, uiOverrides, }) => { // ========== UI Override Components (same pattern as MediasfuGeneric) ========== const MainContainer = React.useMemo(() => withOverride(uiOverrides?.mainContainer, MainContainerComponent), [uiOverrides?.mainContainer]); const MainAspect = React.useMemo(() => withOverride(uiOverrides?.mainAspect, MainAspectComponent), [uiOverrides?.mainAspect]); const MainScreen = React.useMemo(() => withOverride(uiOverrides?.mainScreen, MainScreenComponent), [uiOverrides?.mainScreen]); const MainGrid = React.useMemo(() => withOverride(uiOverrides?.mainGrid, MainGridComponent), [uiOverrides?.mainGrid]); const SubAspect = React.useMemo(() => withOverride(uiOverrides?.subAspect, SubAspectComponent), [uiOverrides?.subAspect]); const OtherGrid = React.useMemo(() => withOverride(uiOverrides?.otherGrid, OthergridComponent), [uiOverrides?.otherGrid]); const FlexibleVideoComponent = React.useMemo(() => withOverride(uiOverrides?.flexibleVideo, FlexibleVideo), [uiOverrides?.flexibleVideo]); const FlexibleGridPrimary = React.useMemo(() => withOverride(uiOverrides?.flexibleGrid, FlexibleGrid), [uiOverrides?.flexibleGrid]); const AudioGridComponent = React.useMemo(() => withOverride(uiOverrides?.audioGrid, AudioGrid), [uiOverrides?.audioGrid]); const PaginationComponent = React.useMemo(() => withOverride(uiOverrides?.pagination, Pagination), [uiOverrides?.pagination]); const ControlButtons = React.useMemo(() => withOverride(uiOverrides?.controlButtons, ControlButtonsComponent), [uiOverrides?.controlButtons]); const ControlButtonsAlt = React.useMemo(() => withOverride(uiOverrides?.controlButtonsAlt, ControlButtonsAltComponent), [uiOverrides?.controlButtonsAlt]); const LoadingModalComponent = React.useMemo(() => withOverride(uiOverrides?.loadingModal, LoadingModal), [uiOverrides?.loadingModal]); const AlertComponentOverride = React.useMemo(() => withOverride(uiOverrides?.alert, AlertComponent), [uiOverrides?.alert]); const MenuModalComponent = React.useMemo(() => withOverride(uiOverrides?.menuModal, MenuModal), [uiOverrides?.menuModal]); const RecordingModalComponent = React.useMemo(() => withOverride(uiOverrides?.recordingModal, RecordingModal), [uiOverrides?.recordingModal]); const RequestsModalComponent = React.useMemo(() => withOverride(uiOverrides?.requestsModal, RequestsModal), [uiOverrides?.requestsModal]); const WaitingRoomModalComponent = React.useMemo(() => withOverride(uiOverrides?.waitingRoomModal, WaitingRoomModal), [uiOverrides?.waitingRoomModal]); const CoHostModalComponent = React.useMemo(() => withOverride(uiOverrides?.coHostModal, CoHostModal), [uiOverrides?.coHostModal]); const MediaSettingsModalComponent = React.useMemo(() => withOverride(uiOverrides?.mediaSettingsModal, MediaSettingsModal), [uiOverrides?.mediaSettingsModal]); const DisplaySettingsModalComponent = React.useMemo(() => withOverride(uiOverrides?.displaySettingsModal, DisplaySettingsModal), [uiOverrides?.displaySettingsModal]); const EventSettingsModalComponent = React.useMemo(() => withOverride(uiOverrides?.eventSettingsModal, EventSettingsModal), [uiOverrides?.eventSettingsModal]); const ParticipantsModalComponent = React.useMemo(() => withOverride(uiOverrides?.participantsModal, ParticipantsModal), [uiOverrides?.participantsModal]); const MessagesModalComponent = React.useMemo(() => withOverride(uiOverrides?.messagesModal, MessagesModal), [uiOverrides?.messagesModal]); const ConfirmExitModalComponent = React.useMemo(() => withOverride(uiOverrides?.confirmExitModal, ConfirmExitModal), [uiOverrides?.confirmExitModal]); const ConfirmHereModalComponent = React.useMemo(() => withOverride(uiOverrides?.confirmHereModal, ConfirmHereModal), [uiOverrides?.confirmHereModal]); const ShareEventModalComponent = React.useMemo(() => withOverride(uiOverrides?.shareEventModal, ShareEventModal), [uiOverrides?.shareEventModal]); const PollModalComponent = React.useMemo(() => withOverride(uiOverrides?.pollModal, PollModal), [uiOverrides?.pollModal]); const BreakoutRoomsModalComponent = React.useMemo(() => withOverride(uiOverrides?.breakoutRoomsModal, BreakoutRoomsModal), [uiOverrides?.breakoutRoomsModal]); const ConfigureWhiteboardModalComponent = React.useMemo(() => withOverride(uiOverrides?.configureWhiteboardModal, ConfigureWhiteboardModal), [uiOverrides?.configureWhiteboardModal]); const WhiteboardComponent = React.useMemo(() => withOverride(uiOverrides?.whiteboard, Whiteboard), [uiOverrides?.whiteboard]); const ScreenboardComponent = React.useMemo(() => withOverride(uiOverrides?.screenboard, Screenboard), [uiOverrides?.screenboard]); const ScreenboardModalComponent = React.useMemo(() => withOverride(uiOverrides?.screenboardModal, ScreenboardModal), [uiOverrides?.screenboardModal]); const consumerResumeFn = React.useMemo(() => withFunctionOverride(uiOverrides?.consumerResume, consumerResume), [uiOverrides?.consumerResume]); const addVideosGridFn = React.useMemo(() => withFunctionOverride(uiOverrides?.addVideosGrid, addVideosGrid), [uiOverrides?.addVideosGrid]); const updateStatesToInitialValues = async () => { const initialValues = initialValuesState; const updateFunctions = getAllParams(); for (const key in initialValues) { if (Object.prototype.hasOwnProperty.call(initialValues, key)) { const updateFunctionName = `update${key.charAt(0).toUpperCase() + key.slice(1)}`; const updateFunction = updateFunctions[updateFunctionName]; if (typeof updateFunction === "function") { try { updateFunction(initialValues[key]); } catch { // Do nothing } } } } }; //logic to join room using socket async function joinRoom(data) { const { socket, roomName, islevel, member, sec, apiUserName } = data; try { // Emit the joinRoom event to the server using the provided socket const response = await joinRoomClient({ socket, roomName, islevel, member, sec, apiUserName, }); return response; } catch (error) { // Handle and log errors during the joinRoom process console.log("error", error); throw new Error("Failed to join the room. Please check your connection and try again."); // throw new Error('Failed to join the room. Please check your connection and try again.'); } } registerGlobals(); // Register globals for WebRTC //validated is true if the user has entered the correct details and checked from the server const [validated, setValidated] = useState(useLocalUIMode); // Validated state as boolean // UseRef hooks with type annotations const localUIMode = useRef(useLocalUIMode); // Local UI mode (desktop or touch) as boolean const socket = useRef({}); // Socket for the media server, type Socket or null const localSocket = useRef(null); // Local socket for the media server, type Socket or null const roomData = useRef(null); // Room data, type ResponseJoinRoom or null const device = useRef(null); // Mediasoup Device, type Device or null // String references with useRef const apiUserName = useRef(""); // API username, type string const apiToken = useRef(""); // API token, type string const link = useRef(""); // Link to the media server, type string //Room Details const roomName = useRef(""); // Room name as string const member = useRef(useSeed && seedData?.member ? seedData?.member : ""); // Member name as string const adminPasscode = useRef(""); // Admin passcode as string const islevel = useRef(useSeed && seedData?.member ? seedData.member === seedData?.host ? "2" : "1" : "1"); // Level of the user as string const coHost = useRef(""); // Co-host as string const coHostResponsibility = useRef([ { name: "participants", value: false, dedicated: false }, { name: "media", value: false, dedicated: false }, { name: "waiting", value: false, dedicated: false }, { name: "chat", value: false, dedicated: false }, ]); // Array of co-host responsibilities const youAreCoHost = useRef(coHost.current ? coHost.current === member.current : false); // True if the user is a co-host as boolean const youAreHost = useRef(islevel ? islevel.current === "2" : false); // True if the user is a host as boolean const confirmedToRecord = useRef(false); // True if the user has confirmed to record as boolean const meetingDisplayType = useRef("media"); // Meeting display type as string const meetingVideoOptimized = useRef(false); // True if the meeting video is optimized as boolean const eventType = useRef(useSeed && seedData?.eventType ? seedData?.eventType : "conference"); // Event type as string const participants = useRef(useSeed && seedData?.participants ? seedData?.participants : []); // Array of participants const filteredParticipants = useRef(participants.current); // Filtered participants as array of Participant const participantsCounter = useRef(0); // Participants counter as number const participantsFilter = useRef(""); // Participants filter as string // Media and Room Details const consume_sockets = useRef([]); // Array of consume sockets const rtpCapabilities = useRef(null); // RTP capabilities from MediaSoup, type RtpCapabilities or null const roomRecvIPs = useRef([]); // Receiving IPs (domains) for the room consumer as strings const meetingRoomParams = useRef(null); // Room parameters for the meeting/event room, type MeetingRoomParams or null const itemPageLimit = useRef(4); // Number of items to show per page in the media display as number const audioOnlyRoom = useRef(false); // True if the room is audio-only and does not support video as boolean const addForBasic = useRef(false); // True if the room supports few producers as boolean const screenPageLimit = useRef(4); // Number of people on the side-view of screen share as number const shareScreenStarted = useRef(false); // True if screen share has started and started remotely as boolean const shared = useRef(false); // True if screen share has started and started locally as boolean const targetOrientation = useRef("landscape"); // Orientation of the media to be captured as string const targetResolution = useRef("sd"); // Resolution of the media to be captured as string const targetResolutionHost = useRef("sd"); // Resolution of the host media to be captured as string const vidCons = useRef({ width: 640, height: 360 }); // Constraints for video capture as array of VidConsType const frameRate = useRef(10); // Frame rate for video capture as number const hParams = useRef({}); // Host video encoding parameters, type HParamsType or null const vParams = useRef({}); // Rest of members video encoding parameters, type VParamsType or null const screenParams = useRef({}); // Screen share encoding parameters, type ScreenParamsType or null const aParams = useRef({}); // Audio encoding parameters, type AParamsType or null //more room details // Room Details - Recording const recordingAudioPausesLimit = useRef(0); // Number of pauses allowed for audio recording const recordingAudioPausesCount = useRef(0); // Number of pauses for audio recording const recordingAudioSupport = useRef(false); // True if the room supports audio recording const recordingAudioPeopleLimit = useRef(0); // Number of people allowed for audio recording const recordingAudioParticipantsTimeLimit = useRef(0); // Time limit for audio recording const recordingVideoPausesCount = useRef(0); // Number of pauses for video recording const recordingVideoPausesLimit = useRef(0); // Number of pauses allowed for video recording const recordingVideoSupport = useRef(false); // True if the room supports video recording const recordingVideoPeopleLimit = useRef(0); // Number of people allowed for video recording const recordingVideoParticipantsTimeLimit = useRef(0); // Time limit for video recording const recordingAllParticipantsSupport = useRef(false); // True if the room supports recording all participants const recordingVideoParticipantsSupport = useRef(false); // True if the room supports recording video participants const recordingAllParticipantsFullRoomSupport = useRef(false); // True if the room supports recording all participants in full room const recordingVideoParticipantsFullRoomSupport = useRef(false); // True if the room supports recording video participants in full room const recordingPreferredOrientation = useRef("landscape"); // Preferred orientation for recording const recordingSupportForOtherOrientation = useRef(false); // True if the room supports recording for other orientations const recordingMultiFormatsSupport = useRef(false); // True if the room supports recording multiple formats // User Recording Parameters const userRecordingParams = useRef({ mainSpecs: { mediaOptions: "video", // 'audio', 'video', audioOptions: "all", // 'all', 'onScreen', 'host' videoOptions: "all", // 'all', 'mainScreen' videoType: "fullDisplay", // 'all', 'bestDisplay', 'fullDisplay' videoOptimized: false, // true, false recordingDisplayType: "media", // 'media', 'video', 'all' addHLS: false, // true, false }, dispSpecs: { nameTags: true, // true, false backgroundColor: "#000000", // '#000000', '#ffffff' nameTagsColor: "#ffffff", // '#000000', '#ffffff' orientationVideo: "portrait", // 'landscape', 'portrait', 'all' }, }); // User recording parameters with type UserRecordingParams // More Room Details - Recording const canRecord = useRef(false); // True if the user can record const startReport = useRef(false); // True if the user has started recording const endReport = useRef(false); // True if the user has stopped recording const recordTimerInterval = useRef(null); // Interval for the recording timer const recordStartTime = useRef(0); // Start time for the recording timer as timestamp or null const recordElapsedTime = useRef(0); // Elapsed time for the recording timer const isTimerRunning = useRef(false); // True if the recording timer is running const canPauseResume = useRef(false); // True if the user can pause/resume recording const recordChangeSeconds = useRef(15000); // Number of seconds to change the recording timer by const pauseLimit = useRef(0); // Number of pauses allowed for recording const pauseRecordCount = useRef(0); // Number of pauses for recording const canLaunchRecord = useRef(true); // True if the user can launch recording const stopLaunchRecord = useRef(false); // True if the user can stop recording //misc variables // State and references with type annotations const firstAll = useRef(false); // True if it is the first time getting all parameters const updateMainWindow = useRef(false); // Update main window const first_round = useRef(false); // True if it is the first round of screen share const landScaped = useRef(false); // True if the screen share is in landscape mode const lock_screen = useRef(false); // True if the screen is locked in place for screen share const screenId = useRef(""); // Screen share producer ID const allVideoStreams = useRef([]); // Array of all video streams const newLimitedStreams = useRef([]); // Array of new limited streams const newLimitedStreamsIDs = useRef([]); // Array of new limited stream IDs const activeSounds = useRef([]); // Array of active sounds const screenShareIDStream = useRef(""); // Screen share stream ID const screenShareNameStream = useRef(""); // Screen share stream name const adminIDStream = useRef(""); // Admin stream ID const adminNameStream = useRef(""); // Admin stream name const youYouStream = useRef([]); // YouYou (own) stream const youYouStreamIDs = useRef([]); // Array of YouYou (own) stream IDs const localStream = useRef(null); // Local stream const recordStarted = useRef(false); // True if recording has started const recordResumed = useRef(false); // True if recording has resumed const recordPaused = useRef(false); // True if recording has paused const recordStopped = useRef(false); // True if recording has stopped const adminRestrictSetting = useRef(false); // Admin's restrict setting const videoRequestState = useRef(null); // Video request state as string or null const videoRequestTime = useRef(0); // Video request time const videoAction = useRef(false); // Video action as string const localStreamVideo = useRef(null); // Local stream video const userDefaultVideoInputDevice = useRef(""); // User's default video input device const currentFacingMode = useRef("user"); // Current facing mode of the video input device const prevFacingMode = useRef("user"); // Previous facing mode of the video input device const defVideoID = useRef(""); // Default video ID const allowed = useRef(false); // True if the user is allowed to turn on their camera const dispActiveNames = useRef([]); // Display active names const p_dispActiveNames = useRef([]); // Display active names (previous) const activeNames = useRef([]); // Active names const prevActiveNames = useRef([]); // Active names (previous) const p_activeNames = useRef([]); // Active names (previous) const membersReceived = useRef(false); // True if members have been received const deferScreenReceived = useRef(false); // True if receiving the screen share has been deferred const hostFirstSwitch = useRef(false); // True if the host has switched to the main screen const micAction = useRef(false); // True if the user has requested to unmute const screenAction = useRef(false); // True if the user has requested to share their screen const chatAction = useRef(false); // True if the user has requested to chat const audioRequestState = useRef(null); // Audio request state as string or null const screenRequestState = useRef(null); // Screen request state as string or null const chatRequestState = useRef(null); // Chat request state as string or null const audioRequestTime = useRef(0); // Audio request time const screenRequestTime = useRef(0); // Screen request time const chatRequestTime = useRef(0); // Chat request time const updateRequestIntervalSeconds = useRef(240); // Update request interval in seconds const oldSoundIds = useRef([]); // Array of old sound IDs const hostLabel = useRef("Host"); // Host label as string const mainScreenFilled = useRef(false); // True if the main screen is filled const localStreamScreen = useRef(null); // Local stream screen const [screenAlreadyOn, setScreenAlreadyOn] = useState(false); // True if the screen is already on const [chatAlreadyOn, setChatAlreadyOn] = useState(false); // True if the chat is already on const redirectURL = useRef(""); // Redirect URL as string or null const oldAllStreams = useRef([]); // Array of old all streams const adminVidID = useRef(""); // Admin video ID as string or null const streamNames = useRef([]); // Array of stream names const non_alVideoStreams = useRef([]); // Array of non-al video streams const sortAudioLoudness = useRef(false); // True if audio loudness is sorted const audioDecibels = useRef([]); // Array of audio decibels const mixed_alVideoStreams = useRef([]); // Array of mixed al video streams const non_alVideoStreams_muted = useRef([]); // Array of non-al video streams muted const paginatedStreams = useRef([]); // Array of paginated streams const localStreamAudio = useRef(null); // Local stream audio const defAudioID = useRef(""); // Default audio ID as string or null const userDefaultAudioInputDevice = useRef(""); // User's default audio input device const userDefaultAudioOutputDevice = useRef(""); // User's default audio output device const prevAudioInputDevice = useRef(""); // Previous audio input device const prevVideoInputDevice = useRef(""); // Previous video input device const audioPaused = useRef(false); // True if audio is paused const mainScreenPerson = useRef(""); // Main screen person as string const adminOnMainScreen = useRef(false); // True if the admin is on the main screen const screenStates = useRef([ { mainScreenPerson: "", mainScreenProducerId: "", mainScreenFilled: false, adminOnMainScreen: false, }, ]); // Array of screen states const prevScreenStates = useRef([ { mainScreenPerson: "", mainScreenProducerId: "", mainScreenFilled: false, adminOnMainScreen: false, }, ]); // Array of previous screen states const updateDateState = useRef(null); // Date state for updating the screen states as number or null const lastUpdate = useRef(null); // Last update time for updating the screen states as number or null const nForReadjustRecord = useRef(0); // Number of times for readjusting the recording const fixedPageLimit = useRef(4); // Fixed page limit for pagination const removeAltGrid = useRef(false); // True if the alt grid should be removed const nForReadjust = useRef(0); // Number of times for readjusting the recording const reorderInterval = useRef(30000); // Reorder interval in milliseconds const fastReorderInterval = useRef(10000); // Fast reorder interval in milliseconds const lastReorderTime = useRef(0); // Last reorder time in milliseconds const audStreamNames = useRef([]); // Array of audio stream names as strings const currentUserPage = useRef(0); // Current user page const [mainHeightWidth, setMainHeightWidth] = useState(eventType.current === "webinar" ? 67 : eventType.current === "broadcast" ? 100 : 0); // Main height and width as number const prevMainHeightWidth = useRef(mainHeightWidth); // Previous main height and width const prevDoPaginate = useRef(false); // Previous doPaginate as boolean const doPaginate = useRef(false); // Do paginate as boolean const shareEnded = useRef(false); // True if the share has ended const lStreams = useRef([]); // Array of limited streams const chatRefStreams = useRef([]); // Array of chat ref streams const [controlHeight, setControlHeight] = useState(0); // Control height as number const isWideScreen = useRef(false); // True if the screen is wide const isMediumScreen = useRef(false); // True if the screen is medium const isSmallScreen = useRef(false); // True if the screen is small const addGrid = useRef(false); // True if the grid should be added const addAltGrid = useRef(false); // True if the alt grid should be added const [gridRows, setGridRows] = useState(0); // Grid rows as number const [gridCols, setGridCols] = useState(0); // Grid columns as number const [altGridRows, setAltGridRows] = useState(0); // Alt grid rows as number const [altGridCols, setAltGridCols] = useState(0); // Alt grid columns as number const [numberPages, setNumberPages] = useState(0); // Number of pages as number const currentStreams = useRef([]); // Array of current streams const [showMiniView, setShowMiniView] = useState(false); // True if the mini view should be shown const nStream = useRef(null); // New stream as MediaStream or null const defer_receive = useRef(false); // True if receiving the stream has been deferred const allAudioStreams = useRef([]); // Array of all audio streams const remoteScreenStream = useRef([]); // Array of remote screen streams const screenProducer = useRef(null); // Screen producer as Producer or null const localScreenProducer = useRef(null); // Local screen producer as Producer or null const gotAllVids = useRef(false); // True if all videos have been received const paginationHeightWidth = useRef(40); // Pagination height/width as number const paginationDirection = useRef("horizontal"); // Pagination direction as string const gridSizes = useRef({ gridWidth: 0, gridHeight: 0, altGridWidth: 0, altGridHeight: 0, }); // Grid sizes with type GridSizes const screenForceFullDisplay = useRef(false); // True if the screen should be forced to full display const mainGridStream = useRef([]); // Array of main grid streams as JSX.Element[] const [otherGridStreams, setOtherGridStreams] = useState([ [], [], ]); // Other grid streams as 2D array of JSX.Element[] const audioOnlyStreams = useRef([]); // Array of audio-only streams const [videoInputs, setVideoInputs] = useState([]); // Video inputs as array of MediaDeviceInfo const [audioInputs, setAudioInputs] = useState([]); // Audio inputs as array of MediaDeviceInfo const [meetingProgressTime, setMeetingProgressTime] = useState("00:00:00"); // Meeting progress time as string const meetingElapsedTime = useRef(0); // Meeting elapsed time as number const ref_participants = useRef([]); // Array of participants as Participant[] // All Participants - Room Details const participantsAll = useRef([]); // All participants as an array of Participant //update Room Details Functions const updateValidated = (value) => { setValidated(value); }; const updateSocket = (value) => { socket.current = value; }; const updateLocalSocket = (value) => { localSocket.current = value; }; const updateDevice = (value) => { device.current = value; }; const updateApiUserName = (value) => { apiUserName.current = value; }; const updateApiToken = (value) => { apiToken.current = value; }; const updateLink = (value) => { link.current = value; }; const updateRoomName = (value) => { roomName.current = value; }; const updateMember = (value) => { if (value.length > 0 && value.includes("_")) { updateIslevel(value.split("_")[1]); value = value.split("_")[0]; } member.current = value; }; const updateAdminPasscode = (value) => { adminPasscode.current = value; }; const updateIslevel = (value) => { islevel.current = value; }; const updateCoHost = (value) => { coHost.current = value; }; const updateCoHostResponsibility = (value) => { coHostResponsibility.current = value; }; const updateYouAreCoHost = (value) => { youAreCoHost.current = value; }; const updateYouAreHost = (value) => { youAreHost.current = value; }; const updateConfirmedToRecord = (value) => { confirmedToRecord.current = value; }; const updateMeetingDisplayType = (value) => { meetingDisplayType.current = value; }; const updateMeetingVideoOptimized = (value) => { meetingVideoOptimized.current = value; }; const updateEventType = (value) => { eventType.current = value; if (value !== "none" && value !== "chat" && value !== "broadcast") { //update the display type try { setTimeout(() => { onResize(); }, 1000); } catch { // Do nothing } } }; const updateParticipants = (value) => { participants.current = value; filteredParticipants.current = value; participantsCounter.current = value.length; }; const updateParticipantsCounter = (value) => { participantsCounter.current = value; }; const updateParticipantsFilter = (value) => { participantsFilter.current = value; }; const updateRecordingAudioPausesLimit = (value) => { recordingAudioPausesLimit.current = value; }; const updateRecordingAudioPausesCount = (value) => { recordingAudioPausesCount.current = value; }; const updateRecordingAudioSupport = (value) => { recordingAudioSupport.current = value; }; const updateRecordingAudioPeopleLimit = (value) => { recordingAudioPeopleLimit.current = value; }; const updateRecordingAudioParticipantsTimeLimit = (value) => { recordingAudioParticipantsTimeLimit.current = value; }; const updateRecordingVideoPausesCount = (value) => { recordingVideoPausesCount.current = value; }; const updateRecordingVideoPausesLimit = (value) => { recordingVideoPausesLimit.current = value; }; const updateRecordingVideoSupport = (value) => { recordingVideoSupport.current = value; }; const updateRecordingVideoPeopleLimit = (value) => { recordingVideoPeopleLimit.current = value; }; const updateRecordingVideoParticipantsTimeLimit = (value) => { recordingVideoParticipantsTimeLimit.current = value; }; const updateRecordingAllParticipantsSupport = (value) => { recordingAllParticipantsSupport.current = value; }; const updateRecordingVideoParticipantsSupport = (value) => { recordingVideoParticipantsSupport.current = value; }; const updateRecordingAllParticipantsFullRoomSupport = (value) => { recordingAllParticipantsFullRoomSupport.current = value; }; const updateRecordingVideoParticipantsFullRoomSupport = (value) => { recordingVideoParticipantsFullRoomSupport.current = value; }; const updateRecordingPreferredOrientation = (value) => { recordingPreferredOrientation.current = value; }; const updateRecordingSupportForOtherOrientation = (value) => { recordingSupportForOtherOrientation.current = value; }; const updateRecordingMultiFormatsSupport = (value) => { recordingMultiFormatsSupport.current = value; }; const updateUserRecordingParams = (value) => { userRecordingParams.current = value; }; const updateCanRecord = (value) => { canRecord.current = value; }; const updateStartReport = (value) => { startReport.current = value; }; const updateEndReport = (value) => { endReport.current = value; }; const updateRecordTimerInterval = (value) => { recordTimerInterval.current = value; }; const updateRecordStartTime = (value) => { recordStartTime.current = value; }; const updateRecordElapsedTime = (value) => { recordElapsedTime.current = value; }; const updateIsTimerRunning = (value) => { isTimerRunning.current = value; }; const updateCanPauseResume = (value) => { canPauseResume.current = value; }; const updateRecordChangeSeconds = (value) => { recordChangeSeconds.current = value; }; const updatePauseLimit = (value) => { pauseLimit.current = value; }; const updatePauseRecordCount = (value) => { pauseRecordCount.current = value; }; const updateCanLaunchRecord = (value) => { canLaunchRecord.current = value; }; const updateStopLaunchRecord = (value) => { stopLaunchRecord.current = value; }; const updateParticipantsAll = (value) => { participantsAll.current = value; }; const updateConsume_sockets = (value) => { consume_sockets.current = value; }; const updateRtpCapabilities = (value) => { rtpCapabilities.current = value; }; const updateRoomRecvIPs = (value) => { roomRecvIPs.current = value; }; const updateMeetingRoomParams = (value) => { meetingRoomParams.current = value; }; const updateItemPage