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
		Add a link
		
	
		Reference in a new issue