A/V almost working

This commit is contained in:
James Ketr 2025-08-29 16:15:47 -07:00
parent 19c5e03ab2
commit 43937dea43
6 changed files with 799 additions and 581 deletions

View File

@ -29,7 +29,8 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
const [lobby, setLobby] = useState<Lobby | null>(null); const [lobby, setLobby] = useState<Lobby | null>(null);
const [editName, setEditName] = useState<string>(""); const [editName, setEditName] = useState<string>("");
const [socketUrl, setSocketUrl] = useState<string | null>(null); const [socketUrl, setSocketUrl] = useState<string | null>(null);
const [creatingLobby, setCreatingLobby] = useState<boolean>(false);
const socket = useWebSocket(socketUrl, { const socket = useWebSocket(socketUrl, {
onOpen: () => console.log("app - WebSocket connection opened."), onOpen: () => console.log("app - WebSocket connection opened."),
onClose: () => console.log("app - WebSocket connection closed."), onClose: () => console.log("app - WebSocket connection closed."),
@ -73,7 +74,7 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
}, [readyState]); }, [readyState]);
useEffect(() => { useEffect(() => {
if (!session || !lobbyName) { if (!session || !lobbyName || creatingLobby || (lobby && lobby.name === lobbyName)) {
return; return;
} }
const getLobby = async (lobbyName: string, session: Session) => { const getLobby = async (lobbyName: string, session: Session) => {
@ -115,7 +116,10 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
setLobby(lobby); setLobby(lobby);
}; };
getLobby(lobbyName, session); setCreatingLobby(true);
getLobby(lobbyName, session).then(() => {
setCreatingLobby(false);
});
}, [session, lobbyName, setLobby, setError]); }, [session, lobbyName, setLobby, setError]);
const setName = (name: string) => { const setName = (name: string) => {

View File

@ -1,3 +1,12 @@
.Video {
opacity: 0;
transition: opacity 0.8s ease-in-out;
}
.Video.fade-in {
opacity: 1;
}
.MediaControlSpacer { .MediaControlSpacer {
display: flex; display: flex;
width: 5rem; width: 5rem;

File diff suppressed because it is too large Load Diff

View File

@ -97,7 +97,7 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
<List className="UserSelector"> <List className="UserSelector">
{users?.map((user) => ( {users?.map((user) => (
<Box <Box
key={user.name} key={user.session_id}
sx={{ display: "flex", flexDirection: "column", alignItems: "center", border: "3px solid magenta" }} sx={{ display: "flex", flexDirection: "column", alignItems: "center", border: "3px solid magenta" }}
className={`UserEntry ${user.local ? "UserSelf" : ""}`} className={`UserEntry ${user.local ? "UserSelf" : ""}`}
> >
@ -106,7 +106,12 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
{user.name && !user.live && <div className="NoNetwork"></div>} {user.name && !user.live && <div className="NoNetwork"></div>}
</div> </div>
{user.name && user.live && peers[user.session_id] ? ( {user.name && user.live && peers[user.session_id] ? (
<MediaControl className={videoClass} peer={peers[user.session_id]} isSelf={user.local} /> <MediaControl
className={videoClass}
key={user.session_id}
peer={peers[user.session_id]}
isSelf={user.local}
/>
) : ( ) : (
<video className="Video"></video> <video className="Video"></video>
)} )}

View File

@ -7,7 +7,7 @@ import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render( root.render(
<React.StrictMode> // <React.StrictMode>
<App /> <App />
</React.StrictMode> // </React.StrictMode>
); );

View File

@ -136,7 +136,7 @@ class Session:
await self.ws.send_json( await self.ws.send_json(
{ {
"type": "join_status", "type": "join_status",
"status": "Error", "status": "Joined",
"message": f"Already joined to lobby {lobby.getName()}", "message": f"Already joined to lobby {lobby.getName()}",
} }
) )
@ -167,7 +167,7 @@ class Session:
peer_session.lobby_peers[lobby.id].append(self.id) peer_session.lobby_peers[lobby.id].append(self.id)
logger.info( logger.info(
f"{self.getName()} -> addPeer({peer_session.getName(), lobby.getName()}, should_create_offer=False)" f"{self.getName()} -> {peer_session.getName()}:addPeer({self.getName(), lobby.getName()}, should_create_offer=False)"
) )
await peer_session.ws.send_json( await peer_session.ws.send_json(
{ {
@ -182,7 +182,7 @@ class Session:
# Add each other peer to the caller # Add each other peer to the caller
logger.info( logger.info(
f"{self.getName()} -> addPeer({peer_session.getName(), lobby.getName()}, should_create_offer=True)" f"{self.getName()} -> {self.getName()}:addPeer({peer_session.getName(), lobby.getName()}, should_create_offer=True)"
) )
await self.ws.send_json( await self.ws.send_json(
{ {
@ -233,7 +233,10 @@ class Session:
continue continue
logger.info(f"{peer_session.getName()} <- remove_peer({self.getName()})") logger.info(f"{peer_session.getName()} <- remove_peer({self.getName()})")
await peer_session.ws.send_json( await peer_session.ws.send_json(
{"type": "remove_peer", "data": {"peer_id": self.id}} {
"type": "removePeer",
"data": {"peer_name": self.name, "peer_id": self.id},
}
) )
if not self.ws: if not self.ws:
@ -245,7 +248,13 @@ class Session:
logger.info(f"{self.getName()} <- remove_peer({peer_session.getName()})") logger.info(f"{self.getName()} <- remove_peer({peer_session.getName()})")
await self.ws.send_json( await self.ws.send_json(
{"type": "remove_peer", "data": {"peer_id": peer_session.id}} {
"type": "removePeer",
"data": {
"peer_name": peer_session.name,
"peer_id": peer_session.id,
},
}
) )
await lobby.removeSession(self) await lobby.removeSession(self)
@ -421,10 +430,12 @@ async def lobby_create(
return {"error": "Invalid request type"} return {"error": "Invalid request type"}
data = create_request.data data = create_request.data
logger.info(f"lobby_create: {data.name} (private={data.private})")
session = getSession(session_id) session = getSession(session_id)
if not session: if not session:
return {"error": f"Session not found ({session_id})"} return {"error": f"Session not found ({session_id})"}
logger.info(
f"{session.getName()} lobby_create: {data.name} (private={data.private})"
)
lobby = getLobbyByName(data.name) lobby = getLobbyByName(data.name)
if not lobby: if not lobby:
@ -608,7 +619,11 @@ async def lobby_join(
message: dict[str, Any] = { message: dict[str, Any] = {
"type": "iceCandidate", "type": "iceCandidate",
"data": {"peer_id": session.id, "candidate": candidate}, "data": {
"peer_id": session.id,
"peer_name": session.name,
"candidate": candidate,
},
} }
peer_session = lobby.getSession(peer_id) peer_session = lobby.getSession(peer_id)
@ -686,6 +701,7 @@ async def lobby_join(
"type": "sessionDescription", "type": "sessionDescription",
"data": { "data": {
"peer_id": session.id, "peer_id": session.id,
"peer_name": session.name,
"session_description": session_description, "session_description": session_description,
}, },
} }