Add support for leave call
This commit is contained in:
parent
ed4ddc8e8c
commit
d040a7b733
4 changed files with 81 additions and 19 deletions
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
29
src/Room.jsx
29
src/Room.jsx
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue