UNPKG

mediasfu-reactnative-expo

Version:
923 lines 194 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 ControlButtonsComponentTouch from "../../components/displayComponents/ControlButtonsComponentTouch"; 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"; // 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 { switchVideoAlt } from "../../methods/streamMethods/switchVideoAlt"; 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 { createResponseJoinRoom } from "../../methods/utils/createResponseJoinRoom"; /** * MediasfuGeneric 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} MediasfuGenericOptions * @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. * * @typedef {Object} SeedData - Data structure to populate initial state in the MediasfuGeneric. * @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 {MediasfuGenericOptions} props - Component properties. * @returns {React.FC<MediasfuGenericOptions>} - React functional component. * * @example * ```tsx * <MediasfuGeneric * 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 generic functionalities for MediaSFU, including joining rooms, * managing participants, and handling media streams. It uses various hooks and methods to * manage state and perform actions such as joining a room, updating initial values, and * handling media streams. * */ const MediasfuGeneric = ({ 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, }) => { 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 : "webinar"); // 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 updateItemPageLimit = (value) => { itemPageLimit.current = value; }; const updateAudioOnlyRoom = (value) => { audioOnlyRoom.current = value; }; const updateAddForBasic = (value) => { addForBasic.current = value; }; const updateScreenPageLimit = (value) => { screenPageLimit.current = value; }; const updateShareScreenStarted = (value) => { shareScreenStarted.current = value; }; const updateShared = (value) => { shared.current = value; setScreenShareActive(value); }; const updateTargetOrientation = (value) => { targetOrientation.current = value; }; const updateTargetResolution = (value) => { targetResolution.current = value; }; const updateTargetResolutionHost = (value) => { targetResolutionHost.current = value; }; const updateVidCons = (value) => { vidCons.current = value; }; const updateFrameRate = (value) => { frameRate.current = value; }; const updateHParams = (value) => { hParams.current = value; }; const updateVParams = (value) => { vParams.current = value; }; const updateScreenParams = (value) => { screenParams.current = value; }; const updateAParams = (value) => { aParams.current = value; }; const updateFirstAll = (value) => { firstAll.current = value; }; const updateUpdateMainWindow = (value) => { updateMainWindow.current = value; }; const updateFirst_round = (value) => { first_round.current = value; }; const updateLandScaped = (value) => { landScaped.current = value; }; const updateLock_screen = (value) => { lock_screen.current = value; }; const updateScreenId = (value) => { screenId.current = value; }; const updateAllVideoStreams = (value) => { allVideoStreams.current = value; }; const updateNewLimitedStreams = (value) => { newLimitedStreams.current = value; }; const updateNewLimitedStreamsIDs = (value) => { newLimitedStreamsIDs.current = value; }; const updateActiveSounds = (value) => { activeSounds.current = value; }; const updateScreenShareIDStream = (value) => { screenShareIDStream.current = value; }; const updateScreenShareNameStream = (value) => { screenShareNameStream.current = value; }; const updateAdminIDStream = (value) => { adminIDStream.current = value; }; const updateAdminNameStream = (value) => { adminNameStream.current = value; }; const updateYouYouStream = (value) => { youYouStream.current = value; }; const updateYouYouStreamIDs = (value) => { youYouStreamIDs.current = value; }; const updateLocalStream = (value) => { localStream.current = value; }; const updateRecordStarted = (value) => { recordStarted.current = value; }; const updateRecordResumed = (value) => { recordResumed.current = value; }; const updateRecordPaused = (value) => { recordPaused.current = value; }; const updateRecordStopped = (value) => { recordStopped.current = value; }; const updateAdminRestrictSetting = (value) => { adminRestrictSetting.current = value; }; const updateVideoRequestState = (value) => { videoRequestState.current = value; }; const updateVideoRequestTime = (value) => { videoRequestTime.current = value; }; const updateVideoAction = (value) => { videoAction.current = value; }; const updateLocalStreamVideo = (value) => { localStreamVideo.current = value; }; const updateUserDefaultVideoInputDevice = (value) => { userDefaultVideoInputDevice.current = value; }; const updateCurrentFacingMode = (value) => { currentFacingMode.current = value; }; const updatePrevFacingMode = (value) => { prevFacingMode.current = value; }; const updateDefVideoID = (value) => { defVideoID.current = value; }; const updateAllowed = (value) => { allowed.current = value; }; const updateDispActiveNames = (value) => { dispActiveNames.current = value; }; const updateP_dispActiveNames = (value) => { p_dispActiveNames.current = value; }; const updateActiveNames = (value) => { activeNames.current = value; }; const updatePrevActiveNames = (value) => { prevActiveNames.current = value; }; const updateP_activeNames = (value) => { p_activeNames.current = value; }; const updateMembersReceived = (value) => { membersReceived.current = value; }; const updateDeferScreenReceived = (value) => { deferScreenReceived.current = value; }; const updateHostFirstSwitch = (value) => { hostFirstSwitch.current = value; }; const updateMicAction = (value) => { micAction.current = value; }; const updateScreenAction = (value) => { screenAction.current = value; }; const updateChatAction = (value) => { chatAction.current = value; }; const updateAudioRequestState = (value) => { audioRequestState.current = value; }; const updateScreenRequestState = (value) => { screenRequestState.current = value; }; const updateChatRequestState = (value) => { chatRequestState.current = value; }; const updateAudioRequestTime = (value) => { audioRequestTime.current = value; }; const updateScreenRequestTime = (value) => { screenRequestTime.current = value; }; const updateChatRequestTime = (value) => { chatRequestTime.current = value; }; const updateOldSoundIds = (value) => { oldSoundIds.current = value; }; const updatehostLabel = (value) => { hostLabel.c