Add call setup ui
This commit is contained in:
parent
b45eacec28
commit
476fe87b31
3 changed files with 113 additions and 15 deletions
|
@ -221,11 +221,22 @@ export function useVideoRoom(manager, roomId, timeout = 5000) {
|
|||
}, timeout);
|
||||
}
|
||||
|
||||
function onLeaveCall() {
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
videoMuted: manager.videoMuted,
|
||||
micMuted: manager.micMuted,
|
||||
}));
|
||||
}
|
||||
|
||||
manager.on("left", onLeaveCall);
|
||||
|
||||
return () => {
|
||||
manager.client.removeListener("Room", roomCallback);
|
||||
manager.removeListener("participants_changed", onParticipantsChanged);
|
||||
clearTimeout(timeoutId);
|
||||
manager.leaveCall();
|
||||
manager.removeListener("left", onLeaveCall);
|
||||
};
|
||||
}, [manager, roomId]);
|
||||
|
||||
|
|
75
src/Room.jsx
75
src/Room.jsx
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
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 { useParams, useLocation } from "react-router-dom";
|
||||
import { useVideoRoom } from "./ConferenceCallManagerHooks";
|
||||
|
@ -95,17 +95,15 @@ export function Room({ manager }) {
|
|||
)}
|
||||
{error && <div className={styles.centerMessage}>{error.message}</div>}
|
||||
{!loading && room && !joined && (
|
||||
<div className={styles.joinRoom}>
|
||||
<h3>Members:</h3>
|
||||
<ul>
|
||||
{room.getMembers().map((member) => (
|
||||
<li key={member.userId}>{member.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
<Button disabled={joining} onClick={joinCall}>
|
||||
Join Call
|
||||
</Button>
|
||||
</div>
|
||||
<JoinRoom
|
||||
manager={manager}
|
||||
joining={joining}
|
||||
joinCall={joinCall}
|
||||
toggleMuteVideo={toggleMuteVideo}
|
||||
toggleMuteMic={toggleMuteMic}
|
||||
videoMuted={videoMuted}
|
||||
micMuted={micMuted}
|
||||
/>
|
||||
)}
|
||||
{!loading && room && joined && participants.length === 0 && (
|
||||
<div className={styles.centerMessage}>
|
||||
|
@ -126,3 +124,56 @@ export function Room({ manager }) {
|
|||
</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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,9 +30,45 @@ limitations under the License.
|
|||
flex: 1;
|
||||
}
|
||||
|
||||
.joinRoom ul {
|
||||
margin-top: 0;
|
||||
padding-left: 0;
|
||||
.preview {
|
||||
position: relative;
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue