Add support for leave call

This commit is contained in:
Robert Long 2021-07-27 13:26:18 -07:00
parent ed4ddc8e8c
commit d040a7b733
4 changed files with 81 additions and 19 deletions

View file

@ -140,7 +140,6 @@ export class ConferenceCallManager extends EventEmitter {
feed: null,
call: null,
muted: true,
calls: [],
};
this.participants = [this.localParticipant];
@ -284,7 +283,7 @@ export class ConferenceCallManager extends EventEmitter {
_addCall(call, userId) {
const existingCall = this.participants.find(
(p) => p.call && p.call.callId === call.callId
(p) => !p.local && p.call && p.call.callId === call.callId
);
if (existingCall) {
@ -299,7 +298,6 @@ export class ConferenceCallManager extends EventEmitter {
userId,
feed: null,
call,
calls: [call],
});
console.debug("_addCall", `Added new participant ${userId}`);
@ -324,12 +322,15 @@ export class ConferenceCallManager extends EventEmitter {
let participantsChanged = false;
if (!this.localParticipant.feed && localFeeds.length > 0) {
this.localParticipant.call = call;
this.localParticipant.feed = localFeeds[0];
participantsChanged = true;
}
const remoteFeeds = call.getRemoteFeeds();
const remoteParticipant = this.participants.find((p) => p.call === call);
const remoteParticipant = this.participants.find(
(p) => !p.local && p.call === call
);
if (remoteFeeds.length > 0 && remoteParticipant.feed !== remoteFeeds[0]) {
remoteParticipant.feed = remoteFeeds[0];
@ -349,7 +350,7 @@ export class ConferenceCallManager extends EventEmitter {
}
const participantIndex = this.participants.findIndex(
(p) => p.call === call
(p) => !p.local && p.call === call
);
if (participantIndex === -1) {
@ -358,6 +359,27 @@ export class ConferenceCallManager extends EventEmitter {
this.participants.splice(participantIndex, 1);
if (this.localParticipant.call === call) {
const newLocalCallParticipant = this.participants.find(
(p) => !p.local && p.call
);
if (newLocalCallParticipant) {
const localFeeds = call.getLocalFeeds();
if (localFeeds.length > 0) {
this.localParticipant.call = call;
this.localParticipant.feed = localFeeds[0];
} else {
this.localParticipant.call = null;
this.localParticipant.feed = null;
}
} else {
this.localParticipant.call = null;
this.localParticipant.feed = null;
}
}
this.emit("participants_changed");
};
@ -367,10 +389,11 @@ export class ConferenceCallManager extends EventEmitter {
`Call ${call.callId} replaced with ${newCall.callId}`
);
const remoteParticipant = this.participants.find((p) => p.call === call);
const remoteParticipant = this.participants.find(
(p) => !p.local && p.call === call
);
remoteParticipant.call = newCall;
remoteParticipant.calls.push(newCall);
newCall.on("feeds_changed", () => this._onCallFeedsChanged(newCall));
newCall.on("hangup", () => this._onCallHangup(newCall));
@ -381,4 +404,18 @@ export class ConferenceCallManager extends EventEmitter {
this.emit("participants_changed");
};
leaveCall() {
for (const participant of this.participants) {
if (!participant.local && participant.call) {
participant.call.hangup("user_hangup", false);
}
}
this.joined = false;
this.participants = [this.localParticipant];
this.localParticipant.feed = null;
this.localParticipant.call = null;
this.emit("participants_changed");
}
}

View file

@ -201,7 +201,17 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
};
}, [manager, roomId]);
return { loading, joined, room, participants, error, joinCall };
const leaveCall = useCallback(() => {
manager.leaveCall();
setState((prevState) => ({
...prevState,
participants: manager.participants,
joined: false,
}));
}, [manager]);
return { loading, joined, room, participants, error, joinCall, leaveCall };
}
export function useRooms(manager) {

View file

@ -21,10 +21,8 @@ import { useVideoRoom } from "./ConferenceCallManagerHooks";
export function Room({ manager }) {
const { roomId } = useParams();
const { loading, joined, room, participants, error, joinCall } = useVideoRoom(
manager,
roomId
);
const { loading, joined, room, participants, error, joinCall, leaveCall } =
useVideoRoom(manager, roomId);
return (
<div className={styles.room}>
@ -61,34 +59,43 @@ export function Room({ manager }) {
{!loading && room && joined && participants.length > 0 && (
<div className={styles.roomContainer}>
{participants.map((participant) => (
<Participant key={participant.userId} participant={participant} />
<Participant key={participant.userId} {...participant} />
))}
</div>
)}
{!loading && room && joined && (
<div className={styles.footer}>
<button className={styles.leaveButton} onClick={leaveCall}>
Leave Call
</button>
</div>
)}
</div>
);
}
function Participant({ participant }) {
function Participant({ userId, feed, muted, local }) {
const videoRef = useRef();
useEffect(() => {
if (participant.feed) {
if (participant.muted) {
if (feed) {
if (muted) {
videoRef.current.muted = true;
}
videoRef.current.srcObject = participant.feed.stream;
videoRef.current.srcObject = feed.stream;
videoRef.current.play();
} else {
videoRef.current.srcObject = null;
}
}, [participant.feed]);
}, [feed]);
return (
<div className={styles.participant}>
<video ref={videoRef}></video>
<div className={styles.participantLabel}>
<p>
{participant.userId} {participant.local && "(You)"}
{userId} {local && "(You)"}
</p>
</div>
</div>

View file

@ -107,6 +107,14 @@ limitations under the License.
background: rgba(0, 0, 0, 0.2);
}
.footer {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 64px;
}
@media(min-width: 800px) {
.roomContainer {
flex-direction: row;