diff --git a/client/src/App.tsx b/client/src/App.tsx index 7bcc43b..7538a43 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -174,7 +174,7 @@ const LobbyView: React.FC = (props: LobbyProps) => { getLobby(lobbyName, session).finally(() => { setCreatingLobby(false); }); - }, [session, lobbyName, lobby, setLobby, setError]); + }, [session, lobbyName, lobby, setLobby, setError, creatingLobby]); const setName = (name: string) => { sendJsonMessage({ type: "set_name", diff --git a/client/src/LobbyChat.tsx b/client/src/LobbyChat.tsx index c7c21cc..3822e9a 100644 --- a/client/src/LobbyChat.tsx +++ b/client/src/LobbyChat.tsx @@ -1,15 +1,5 @@ import React, { useState, useEffect, useRef, KeyboardEvent } from "react"; -import { - Paper, - TextField, - Button, - List, - ListItem, - ListItemText, - Typography, - Box, - IconButton, -} from "@mui/material"; +import { Paper, TextField, List, ListItem, ListItemText, Typography, Box, IconButton } from "@mui/material"; import SendIcon from "@mui/icons-material/Send"; import useWebSocket from "react-use-websocket"; import { Session } from "./GlobalContext"; diff --git a/client/src/MediaControl.tsx b/client/src/MediaControl.tsx index f7370bf..53d8580 100644 --- a/client/src/MediaControl.tsx +++ b/client/src/MediaControl.tsx @@ -1,6 +1,4 @@ import React, { useState, useEffect, useRef, useCallback } from "react"; -import Moveable from "react-moveable"; -import { flushSync } from "react-dom"; import "./MediaControl.css"; import VolumeOff from "@mui/icons-material/VolumeOff"; import VolumeUp from "@mui/icons-material/VolumeUp"; @@ -333,19 +331,22 @@ const MediaAgent = (props: MediaAgentProps) => { const pendingIceCandidatesRef = useRef>(new Map()); // Update peer states when connection state changes - const updatePeerConnectionState = useCallback((peerId: string, connectionState: string, isNegotiating: boolean = false) => { - setPeers(prevPeers => { - const updatedPeers = { ...prevPeers }; - if (updatedPeers[peerId]) { - updatedPeers[peerId] = { - ...updatedPeers[peerId], - connectionState, - isNegotiating - }; - } - return updatedPeers; - }); - }, [setPeers]); + const updatePeerConnectionState = useCallback( + (peerId: string, connectionState: string, isNegotiating: boolean = false) => { + setPeers((prevPeers) => { + const updatedPeers = { ...prevPeers }; + if (updatedPeers[peerId]) { + updatedPeers[peerId] = { + ...updatedPeers[peerId], + connectionState, + isNegotiating, + }; + } + return updatedPeers; + }); + }, + [setPeers] + ); const { sendJsonMessage, lastJsonMessage, readyState } = useWebSocket(socketUrl, { share: true, @@ -410,7 +411,6 @@ const MediaAgent = (props: MediaAgentProps) => { // Queue peer if we need local media but don't have it yet // Only queue if we're expected to provide media (local user has media) const localUserHasMedia = session?.has_media !== false; // Default to true for backward compatibility - const peerHasMedia = config.has_media !== false; // Default to true for backward compatibility // Only need to wait for media if we (local user) are supposed to provide it if (!media && localUserHasMedia) { @@ -730,7 +730,7 @@ const MediaAgent = (props: MediaAgentProps) => { } } }, - [peers, setPeers, media, sendJsonMessage] + [peers, setPeers, media, sendJsonMessage, session?.has_media, updatePeerConnectionState] ); // Process queued peers when media becomes available @@ -826,7 +826,7 @@ const MediaAgent = (props: MediaAgentProps) => { } } }, - [peers, sendJsonMessage] + [peers, sendJsonMessage, updatePeerConnectionState] ); const removePeer = useCallback( @@ -1074,6 +1074,9 @@ const MediaAgent = (props: MediaAgentProps) => { if (mediaStreamRef.current || readyState !== ReadyState.OPEN) return; + // Capture the connections at effect setup time + const connectionsToCleanup = connectionsRef.current; + if (localUserHasMedia) { console.log(`media-agent - Setting up local media`); setup_local_media().then((mediaStream) => { @@ -1111,9 +1114,9 @@ const MediaAgent = (props: MediaAgentProps) => { mediaStreamRef.current = null; } - // Clean up connections - connectionsRef.current.forEach((connection) => connection.close()); - connectionsRef.current.clear(); + // Clean up connections using the captured ref value + connectionsToCleanup.forEach((connection) => connection.close()); + connectionsToCleanup.clear(); }; }, [readyState, setup_local_media, session]); diff --git a/client/src/api-client.ts b/client/src/api-client.ts index 667b59d..973710e 100644 --- a/client/src/api-client.ts +++ b/client/src/api-client.ts @@ -1,5 +1,5 @@ // TypeScript API client for AI Voicebot server -import { components, paths } from "./api-types"; +import { components } from "./api-types"; import { base } from "./Common"; // Re-export commonly used types from the generated schema