import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import {isValidRoomID, isValidPartialRoomID} from './generateNewRoomID'; import {useCallback, useEffect, useState} from 'react'; import Button from '@mui/material/Button'; import {useSocket} from './useSocket'; import FormGroup from '@mui/material/FormGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import {RoomState} from './types/RoomState'; import setURLParam from './setURLParam'; import {getURLParams} from './URLParams'; import { JoinRoomConfig, Roles, ServerState, StreamingStatus, } from './types/StreamingTypes'; import Alert from '@mui/material/Alert'; function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } type Props = { roomState: RoomState | null; serverState: ServerState | null; onJoinRoomOrUpdateRoles?: () => void; streamingStatus: StreamingStatus; }; export default function RoomConfig({ roomState, serverState, onJoinRoomOrUpdateRoles, streamingStatus, }: Props) { const {socket, clientID} = useSocket(); const urlParams = getURLParams(); const roomIDParam = urlParams.roomID; const autoJoinRoom = urlParams.autoJoin; const [roomID, setRoomID] = useState( (roomIDParam ?? '').toUpperCase(), ); const [roomIDError, setRoomIDError] = useState(false); const [roles, setRoles] = useState<{speaker: boolean; listener: boolean}>({ speaker: true, listener: true, }); const [lockServer, setLockServer] = useState(false); const [lockServerName, setLockServerName] = useState(''); const [joinInProgress, setJoinInProgress] = useState(false); const [didAttemptAutoJoin, setDidAttemptAutoJoin] = useState(false); const isValidServerLock = lockServer === false || (lockServerName != null && lockServerName.length > 0); const isValidRoles = Object.values(roles).filter(Boolean).length > 0; const isValidAllInputs = isValidRoomID(roomID) && isValidRoles && isValidServerLock; const roomIDFromServer = roomState?.room_id ?? null; const onJoinRoom = useCallback( (createNewRoom: boolean) => { if (socket == null) { console.error('Socket is null, cannot join room'); return; } console.debug(`Attempting to join roomID ${roomID}...`); const lockServerValidated: string | null = lockServer && roles['speaker'] ? lockServerName : null; // TODO: Show error state if roomID isn't valid setJoinInProgress(true); const configObject: JoinRoomConfig = { roles: (Object.keys(roles) as Array).filter( (role) => roles[role] === true, ), lockServerName: lockServerValidated, }; socket.emit( 'join_room', clientID, createNewRoom ? null : roomID, configObject, (result) => { console.log('join_room result:', result); if (createNewRoom) { setRoomID(result.roomID); } if (onJoinRoomOrUpdateRoles != null) { onJoinRoomOrUpdateRoles(); } setURLParam('roomID', result.roomID); setJoinInProgress(false); }, ); }, [ clientID, lockServer, lockServerName, onJoinRoomOrUpdateRoles, roles, roomID, socket, ], ); useEffect(() => { if ( autoJoinRoom === true && didAttemptAutoJoin === false && socket != null ) { // We want to consider this an attempt whether or not we actually try to join, because // we only want auto-join to happen on initial load setDidAttemptAutoJoin(true); if ( isValidAllInputs && joinInProgress === false && roomIDFromServer == null ) { console.debug('Attempting to auto-join room...'); onJoinRoom(false); } else { console.debug('Unable to auto-join room', { isValidAllInputs, joinInProgress, roomIDFromServer, }); } } }, [ autoJoinRoom, didAttemptAutoJoin, isValidAllInputs, joinInProgress, onJoinRoom, roomIDFromServer, socket, ]); return ( { const id = e.target.value.toUpperCase(); if (isValidPartialRoomID(id)) { setRoomIDError(false); setRoomID(id); } else { setRoomIDError(true); } }} sx={{width: '8em'}} />
{roomState?.room_id == null && (
)}
{Object.keys(roles).map((role) => { return ( ) => { setRoles((prevRoles) => ({ ...prevRoles, [role]: event.target.checked, })); }} /> } label={capitalize(role)} /> ); })} {urlParams.enableServerLock && roles['speaker'] === true && ( <> ) => { setLockServer(event.target.checked); }} /> } label="Lock Server (prevent other users from streaming)" /> )} {urlParams.enableServerLock && roles['speaker'] === true && lockServer && ( ) => { setLockServerName(event.target.value); }} helperText="Locking the server will prevent anyone else from using it until you close the page, in order to maximize server performance. Please only use this for live demos." /> )} {serverState?.serverLock != null && serverState.serverLock.clientID === clientID && ( {`The server is now locked for your use (${serverState?.serverLock?.name}). Close this window to release the lock so that others may use the server.`} )}
); }