hotdub / streaming-react-app /src /RoomConfig.tsx
aman-ht's picture
Disable : room creation for listener
b94afa9
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";
import { Paper, Typography } from "@mui/material";
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<string>(
(roomIDParam ?? "").toUpperCase()
);
const [roomIDError, setRoomIDError] = useState<boolean>(false);
const [roles, setRoles] = useState<{ speaker: boolean; listener: boolean }>({
speaker: false,
listener: false,
});
const [lockServer, setLockServer] = useState<boolean>(false);
const [lockServerName, setLockServerName] = useState<string>("");
const [joinInProgress, setJoinInProgress] = useState<boolean>(false);
const [didAttemptAutoJoin, setDidAttemptAutoJoin] = useState<boolean>(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;
setJoinInProgress(true);
const configObject: JoinRoomConfig = {
roles: (Object.keys(roles) as Array<Roles>).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 (
<Stack direction="column" spacing="12px" sx={{ width: "80%" }}>
<Stack spacing={2}>
<Paper
elevation={3}
style={{
padding: "1em",
borderRadius: "15px",
border: "1px solid #ccc",
}}
>
<Stack
direction="column"
spacing={1}
sx={{ alignItems: "center", width: "100%" }}
>
<Typography fontWeight={600}>Join an Existing Room</Typography>
<Typography variant="body2">
Join an existing room by entering the room code provided by the
host.
</Typography>
<TextField
size="small"
label="Room Code"
placeholder="Enter Room Code"
variant="outlined"
disabled={roomState?.room_id != null}
value={roomID}
error={roomIDError}
onChange={(e) => {
const id = e.target.value.toUpperCase();
if (isValidPartialRoomID(id)) {
setRoomIDError(false);
setRoomID(id);
} else {
setRoomIDError(true);
}
}}
sx={{ width: "100%" }}
/>
<div>
<Button
sx={{borderRadius: "20px"}}
variant="contained"
disabled={
isValidAllInputs === false ||
joinInProgress ||
streamingStatus !== "stopped"
}
onClick={() => onJoinRoom(false)}
>
{roomState?.room_id != null ? "Update Roles" : "Join Room"}
</Button>
</div>
</Stack>
</Paper>
<Paper
elevation={3}
style={{
padding: "1em",
borderRadius: "15px",
border: "1px solid #ccc",
}}
>
<Stack
direction="column"
spacing={1}
sx={{ alignItems: "center", width: "100%" }}
>
<Typography fontWeight={600}>Create a New Room</Typography>
<Typography variant="body2">
Start a new room and invite others to join you in collaborative
sessions or discussions.
</Typography>
{roomState?.room_id == null && (
<div>
<Button
sx={{borderRadius: "20px"}}
variant="contained"
disabled={
roomState?.room_id != null ||
joinInProgress ||
streamingStatus !== "stopped" || !roles["speaker"]
}
onClick={() => onJoinRoom(true)}
>
{"Create New Room"}
</Button>
</div>
)}
</Stack>
</Paper>
</Stack>
<FormGroup>
<Stack direction="row" justifyContent="space-between">
{Object.keys(roles).map((role) => {
return (
<FormControlLabel
disabled={streamingStatus !== "stopped"}
key={role}
control={
<Checkbox
checked={roles[role]}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setRoles((prevRoles) => ({
...prevRoles,
[role]: event.target.checked,
}));
}}
/>
}
label={capitalize(role)}
/>
);
})}
</Stack>
{urlParams.enableServerLock && roles["speaker"] === true && (
<>
<FormControlLabel
disabled={streamingStatus !== "stopped"}
control={
<Checkbox
checked={lockServer}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setLockServer(event.target.checked);
}}
/>
}
label="Lock Server (prevent other users from streaming)"
/>
</>
)}
</FormGroup>
{urlParams.enableServerLock &&
roles["speaker"] === true &&
lockServer && (
<TextField
disabled={streamingStatus !== "stopped"}
label="Enter Your Name + Expected Lock End Time"
variant="outlined"
value={lockServerName}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
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 && (
<Alert severity="success">{`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.`}</Alert>
)}
</Stack>
);
}