Add call setup ui

This commit is contained in:
Robert Long 2021-08-20 17:02:47 -07:00
parent b45eacec28
commit 476fe87b31
3 changed files with 113 additions and 15 deletions

View file

@ -221,11 +221,22 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
}, timeout); }, timeout);
} }
function onLeaveCall() {
setState((prevState) => ({
...prevState,
videoMuted: manager.videoMuted,
micMuted: manager.micMuted,
}));
}
manager.on("left", onLeaveCall);
return () => { return () => {
manager.client.removeListener("Room", roomCallback); manager.client.removeListener("Room", roomCallback);
manager.removeListener("participants_changed", onParticipantsChanged); manager.removeListener("participants_changed", onParticipantsChanged);
clearTimeout(timeoutId); clearTimeout(timeoutId);
manager.leaveCall(); manager.leaveCall();
manager.removeListener("left", onLeaveCall);
}; };
}, [manager, roomId]); }, [manager, roomId]);

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState, useRef } from "react";
import styles from "./Room.module.css"; import styles from "./Room.module.css";
import { useParams, useLocation } from "react-router-dom"; import { useParams, useLocation } from "react-router-dom";
import { useVideoRoom } from "./ConferenceCallManagerHooks"; import { useVideoRoom } from "./ConferenceCallManagerHooks";
@ -95,17 +95,15 @@ export function Room({ manager }) {
)} )}
{error && <div className={styles.centerMessage}>{error.message}</div>} {error && <div className={styles.centerMessage}>{error.message}</div>}
{!loading && room && !joined && ( {!loading && room && !joined && (
<div className={styles.joinRoom}> <JoinRoom
<h3>Members:</h3> manager={manager}
<ul> joining={joining}
{room.getMembers().map((member) => ( joinCall={joinCall}
<li key={member.userId}>{member.name}</li> toggleMuteVideo={toggleMuteVideo}
))} toggleMuteMic={toggleMuteMic}
</ul> videoMuted={videoMuted}
<Button disabled={joining} onClick={joinCall}> micMuted={micMuted}
Join Call />
</Button>
</div>
)} )}
{!loading && room && joined && participants.length === 0 && ( {!loading && room && joined && participants.length === 0 && (
<div className={styles.centerMessage}> <div className={styles.centerMessage}>
@ -126,3 +124,56 @@ export function Room({ manager }) {
</div> </div>
); );
} }
function JoinRoom({
joining,
joinCall,
manager,
toggleMuteVideo,
toggleMuteMic,
videoMuted,
micMuted,
}) {
const videoRef = useRef();
const [hasPermissions, setHasPermissions] = useState(false);
const [needsPermissions, setNeedsPermissions] = useState(false);
useEffect(() => {
manager.client
.getLocalVideoStream()
.then((stream) => {
if (videoRef.current) {
videoRef.current.srcObject = stream;
videoRef.current.play();
setHasPermissions(true);
}
})
.catch(() => {
if (videoRef.current) {
setNeedsPermissions(true);
}
});
}, [manager]);
return (
<div className={styles.joinRoom}>
<div className={styles.preview}>
{needsPermissions && (
<p className={styles.webcamPermissions}>
Webcam permissions needed to join the call.
</p>
)}
<video ref={videoRef} muted playsInline disablePictureInPicture />
</div>
{hasPermissions && (
<div className={styles.previewButtons}>
<MicButton muted={micMuted} onClick={toggleMuteMic} />
<VideoButton enabled={videoMuted} onClick={toggleMuteVideo} />
</div>
)}
<Button disabled={!hasPermissions || joining} onClick={joinCall}>
Join Call
</Button>
</div>
);
}

View file

@ -30,9 +30,45 @@ limitations under the License.
flex: 1; flex: 1;
} }
.joinRoom ul { .preview {
margin-top: 0; position: relative;
padding-left: 0; max-width: 400px;
border-radius: 24px;
overflow: hidden;
background-color: #444;
margin: 40px 20px 20px 20px;
}
.preview video {
width: 100%;
height: 100%;
object-fit: cover;
}
.webcamPermissions {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
font-size: 13px;
font-weight: 600;
}
.previewButtons {
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.previewButtons > * {
margin-right: 30px;
}
.previewButtons > :last-child {
margin-right: 0px;
} }
.centerMessage { .centerMessage {