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);
|
}, 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]);
|
||||||
|
|
||||||
|
|
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.
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue