import React, { useState, useEffect, KeyboardEvent } from "react"; import { Input, Paper, Typography } from "@mui/material"; import { Session } from "./GlobalContext"; import { UserList } from "./UserList"; import "./App.css"; import { ws_base, base } from "./Common"; import { Box, Button } from "@mui/material"; import { BrowserRouter as Router, Route, Routes, useParams } from "react-router-dom"; import useWebSocket, { ReadyState } from "react-use-websocket"; console.log(`AI Voice Chat Build: ${process.env.REACT_APP_AI_VOICECHAT_BUILD}`); type LobbyProps = { session: Session; setSession: React.Dispatch>; setError: React.Dispatch>; }; type Lobby = { id: string; name: string; private: boolean; }; const LobbyView: React.FC = (props: LobbyProps) => { const { session, setSession, setError } = props; const { lobbyName = "default" } = useParams<{ lobbyName: string }>(); const [lobby, setLobby] = useState(null); const [editName, setEditName] = useState(""); const [socketUrl, setSocketUrl] = useState(null); const [creatingLobby, setCreatingLobby] = useState(false); const socket = useWebSocket(socketUrl, { onOpen: () => console.log("app - WebSocket connection opened."), onClose: () => console.log("app - WebSocket connection closed."), onError: (event) => console.error("app - WebSocket error observed:", event), // onMessage: (event) => console.log("WebSocket message received:"), // shouldReconnect: (closeEvent) => true, // Will attempt to reconnect on all close events. reconnectInterval: 3000, share: true, }); const { sendJsonMessage, lastJsonMessage, readyState } = socket; useEffect(() => { if (lobby && session) { setSocketUrl(`${ws_base}/${lobby.id}/${session.id}`); } }, [lobby, session]); useEffect(() => { if (!lastJsonMessage || !session) { return; } const data: any = lastJsonMessage; switch (data.type) { case "update": if ("name" in data) { console.log(`Lobby - name set to ${data.name}`); setSession((s) => (s ? { ...s, name: data.name } : null)); } break; case "error": console.error(`Lobby - Server error: ${data.error}`); setError(data.error); break; default: break; } }, [lastJsonMessage, session, setError, setSession]); useEffect(() => { console.log("app - WebSocket connection status: ", readyState); }, [readyState]); useEffect(() => { if (!session || !lobbyName || creatingLobby || (lobby && lobby.name === lobbyName)) { return; } const getLobby = async (lobbyName: string, session: Session) => { const res = await fetch(`${base}/api/lobby/${session.id}`, { method: "POST", cache: "no-cache", credentials: "same-origin", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ type: "lobby_create", data: { name: lobbyName, private: false, }, }), }); if (res.status >= 400) { const error = `Unable to connect to AI Voice Chat server! Try refreshing your browser in a few seconds.`; console.error(error); setError(error); } const data = await res.json(); if (data.error) { console.error(`Lobby - Server error: ${data.error}`); setError(data.error); return; } if (data.type !== "lobby_created") { console.error(`Lobby - Unexpected response type: ${data.type}`); setError(`Unexpected response from server`); return; } const lobby: Lobby = data.data; console.log(`Lobby - Joined lobby`, lobby); setLobby(lobby); }; setCreatingLobby(true); getLobby(lobbyName, session).then(() => { setCreatingLobby(false); }); }, [session, lobbyName, setLobby, setError]); const setName = (name: string) => { sendJsonMessage({ type: "set_name", data: { name }, }); }; const handleKeyDown = (event: KeyboardEvent): void => { if (event.key === "Enter") { event.preventDefault(); const newName = editName.trim(); if (!newName || session?.name === newName) { return; } setName(newName); setEditName(""); } }; return ( {readyState !== ReadyState.OPEN || !session ? (

Connecting to server...

) : ( <> AI Voice Chat Lobby: {lobbyName} {session.name && You are logged in as: {session.name}} {!session.name && ( Enter your name to join: { setEditName(e.target.value); }} onKeyDown={handleKeyDown} placeholder="Your name" /> )} {session.name && ( <> {/* {session.lobbies.map((lobby: string) => ( ))} */} {session && socketUrl && } )} )}
); }; const App = () => { const [session, setSession] = useState(null); const [error, setError] = useState(null); useEffect(() => { if (error) { setTimeout(() => setError(null), 5000); } }, [error]); useEffect(() => { if (!session) { return; } console.log(`App - sessionId`, session.id); }, [session]); useEffect(() => { if (session) { return; } const getSession = async () => { const res = await fetch(`${base}/api/session`, { method: "GET", cache: "no-cache", credentials: "same-origin", headers: { "Content-Type": "application/json", }, }); if (res.status >= 400) { const error = `Unable to connect to AI Voice Chat server! Try refreshing your browser in a few seconds.`; console.error(error); setError(error); return; } const data = await res.json(); if (data.error) { console.error(`App - Server error: ${data.error}`); setError(data.error); return; } setSession(data); }; getSession(); }, [session, setSession]); return ( {!session &&

Connecting to server...

} {session && ( } path={`${base}/:lobbyName`} /> } path={`${base}`} /> )} {error && ( {error} )}
); }; export default App;