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,6 +29,7 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
const [lobby, setLobby] = useState<Lobby | null>(null);
const [editName, setEditName] = useState<string>("");
const [socketUrl, setSocketUrl] = useState<string | null>(null);
const [creatingLobby, setCreatingLobby] = useState<boolean>(false);
const socket = useWebSocket(socketUrl, {
onOpen: () => console.log("app - WebSocket connection opened."),
@ -73,7 +74,7 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
}, [readyState]);
useEffect(() => {
if (!session || !lobbyName) {
if (!session || !lobbyName || creatingLobby || (lobby && lobby.name === lobbyName)) {
return;
}
const getLobby = async (lobbyName: string, session: Session) => {
@ -115,7 +116,10 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
setLobby(lobby);
};
getLobby(lobbyName, session);
setCreatingLobby(true);
getLobby(lobbyName, session).then(() => {
setCreatingLobby(false);
});
}, [session, lobbyName, setLobby, setError]);
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 {
display: flex;
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">
{users?.map((user) => (
<Box
key={user.name}
key={user.session_id}
sx={{ display: "flex", flexDirection: "column", alignItems: "center", border: "3px solid magenta" }}
className={`UserEntry ${user.local ? "UserSelf" : ""}`}
>
@ -106,7 +106,12 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
{user.name && !user.live && <div className="NoNetwork"></div>}
</div>
{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>
)}

View File

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

View File

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