Disallow joining multiple times and properly clean up event listeners

This commit is contained in:
Robert Long 2021-08-09 13:54:23 -07:00
parent d7a5211a94
commit cc5279fc05
2 changed files with 60 additions and 42 deletions

View file

@ -131,8 +131,10 @@ export function useConferenceCallManager(homeserverUrl) {
} }
export function useVideoRoom(manager, roomId, timeout = 5000) { export function useVideoRoom(manager, roomId, timeout = 5000) {
const [{ loading, joined, room, participants, error }, setState] = useState({ const [{ loading, joined, joining, room, participants, error }, setState] =
useState({
loading: true, loading: true,
joining: false,
joined: false, joined: false,
room: undefined, room: undefined,
participants: [], participants: [],
@ -140,6 +142,13 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
}); });
useEffect(() => { useEffect(() => {
setState((prevState) => ({
...prevState,
loading: true,
room: undefined,
error: undefined,
}));
function onBeforeUnload(event) { function onBeforeUnload(event) {
manager.leaveCall(); manager.leaveCall();
} }
@ -149,19 +158,14 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
window.addEventListener(unloadEvent, onBeforeUnload); window.addEventListener(unloadEvent, onBeforeUnload);
return () => { const onParticipantsChanged = () => {
window.removeEventListener(unloadEvent, onBeforeUnload);
manager.leaveCall();
};
}, [manager]);
useEffect(() => {
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
loading: true, participants: manager.participants,
room: undefined,
error: undefined,
})); }));
};
manager.on("participants_changed", onParticipantsChanged);
manager.client.joinRoom(roomId).catch((err) => { manager.client.joinRoom(roomId).catch((err) => {
setState((prevState) => ({ ...prevState, loading: false, error: err })); setState((prevState) => ({ ...prevState, loading: false, error: err }));
@ -208,47 +212,41 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
return () => { return () => {
manager.client.removeListener("Room", roomCallback); manager.client.removeListener("Room", roomCallback);
manager.leaveCall(); manager.removeListener("participants_changed", onParticipantsChanged);
window.removeEventListener(unloadEvent, onBeforeUnload);
clearTimeout(timeoutId); clearTimeout(timeoutId);
manager.leaveCall();
}; };
}, [roomId]); }, [manager, roomId]);
const joinCall = useCallback(() => { const joinCall = useCallback(() => {
const onParticipantsChanged = () => { if (joining || joined) {
return;
}
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
participants: manager.participants, joining: true,
})); }));
};
manager.on("participants_changed", onParticipantsChanged);
manager manager
.enter(roomId) .enter(roomId)
.then(() => { .then(() => {
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
joining: false,
joined: true, joined: true,
})); }));
}) })
.catch((error) => { .catch((error) => {
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
joining: false,
joined: false, joined: false,
error, error,
})); }));
}); });
}, [manager, roomId, joining, joined]);
return () => {
manager.removeListener("participants_changed", onParticipantsChanged);
setState((prevState) => ({
...prevState,
joined: false,
participants: [],
}));
};
}, [manager, roomId]);
const leaveCall = useCallback(() => { const leaveCall = useCallback(() => {
manager.leaveCall(); manager.leaveCall();
@ -257,10 +255,20 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
...prevState, ...prevState,
participants: manager.participants, participants: manager.participants,
joined: false, joined: false,
joining: false,
})); }));
}, [manager]); }, [manager]);
return { loading, joined, room, participants, error, joinCall, leaveCall }; return {
loading,
joined,
joining,
room,
participants,
error,
joinCall,
leaveCall,
};
} }
export function useRooms(manager) { export function useRooms(manager) {

View file

@ -28,8 +28,16 @@ function useQuery() {
export function Room({ manager }) { export function Room({ manager }) {
const { roomId } = useParams(); const { roomId } = useParams();
const query = useQuery(); const query = useQuery();
const { loading, joined, room, participants, error, joinCall, leaveCall } = const {
useVideoRoom(manager, roomId); loading,
joined,
joining,
room,
participants,
error,
joinCall,
leaveCall,
} = useVideoRoom(manager, roomId);
const debugStr = query.get("debug"); const debugStr = query.get("debug");
const [debug, setDebug] = useState(debugStr === "" || debugStr === "true"); const [debug, setDebug] = useState(debugStr === "" || debugStr === "true");
@ -77,7 +85,9 @@ export function Room({ manager }) {
<li key={member.userId}>{member.name}</li> <li key={member.userId}>{member.name}</li>
))} ))}
</ul> </ul>
<button onClick={joinCall}>Join Call</button> <button disabled={joining} onClick={joinCall}>
Join Call
</button>
</div> </div>
)} )}
{!loading && room && joined && participants.length === 0 && ( {!loading && room && joined && participants.length === 0 && (