UNPKG

mediasfu-reactnative

Version:
907 lines 195 kB
import React, { useEffect, useState, useRef } from 'react'; import { Text, View, Platform, Dimensions, StatusBar } from 'react-native'; import Orientation from 'react-native-orientation-locker'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { getStatusBarHeight } from 'react-native-status-bar-height'; import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'; import { request, PERMISSIONS, RESULTS } from 'react-native-permissions'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; // 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 (_a) { // 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 === null || seedData === void 0 ? void 0 : seedData.member) ? seedData === null || seedData === void 0 ? void 0 : seedData.member : ''); // Member name as string const adminPasscode = useRef(''); // Admin passcode as string const islevel = useRef(useSeed && (seedData === null || seedData === void 0 ? void 0 : seedData.member) ? seedData.member === (seedData === null || seedData === void 0 ? void 0 : 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 === null || seedData === void 0 ? void 0 : seedData.eventType) ? seedData === null || seedData === void 0 ? void 0 : seedData.eventType : 'webinar'); // Event type as string const participants = useRef(useSeed && (seedData === null || seedData === void 0 ? void 0 : seedData.participants) ? seedData === null || seedData === void 0 ? void 0 : 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 (_a) { // 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; }; co