Split out lobby view

This commit is contained in:
Robert Long 2022-01-05 13:09:12 -08:00
parent 3ec01293e6
commit 8be578763d
3 changed files with 216 additions and 94 deletions

View file

@ -52,6 +52,7 @@ import { UserMenu } from "./UserMenu";
import classNames from "classnames";
import { Avatar } from "./Avatar";
import { UserMenuContainer } from "./UserMenuContainer";
import { LobbyView } from "./room/LobbyView";
const canScreenshare = "getDisplayMedia" in navigator.mediaDevices;
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
@ -218,7 +219,7 @@ export function GroupCallView({
}
} else {
return (
<RoomSetupView
<LobbyView
client={client}
hasLocalParticipant={hasLocalParticipant}
roomName={groupCall.room.name}
@ -254,99 +255,6 @@ export function EnteringRoomView() {
);
}
function RoomSetupView({
client,
roomName,
state,
onInitLocalCallFeed,
onEnter,
localCallFeed,
microphoneMuted,
localVideoMuted,
toggleLocalVideoMuted,
toggleMicrophoneMuted,
setShowInspector,
showInspector,
roomId,
}) {
const { stream } = useCallFeed(localCallFeed);
const videoRef = useMediaStream(stream, true);
useEffect(() => {
onInitLocalCallFeed();
}, [onInitLocalCallFeed]);
return (
<div className={styles.room}>
<Header>
<LeftNav>
<RoomHeaderInfo roomName={roomName} />
</LeftNav>
<RightNav>
<UserMenuContainer />
</RightNav>
</Header>
<div className={styles.joinRoom}>
<div className={styles.joinRoomContent}>
<div className={styles.preview}>
<video ref={videoRef} muted playsInline disablePictureInPicture />
{state === GroupCallState.LocalCallFeedUninitialized && (
<p className={styles.webcamPermissions}>
Webcam/microphone permissions needed to join the call.
</p>
)}
{state === GroupCallState.InitializingLocalCallFeed && (
<p className={styles.webcamPermissions}>
Accept webcam/microphone permissions to join the call.
</p>
)}
{state === GroupCallState.LocalCallFeedInitialized && (
<>
<Button
className={styles.joinCallButton}
disabled={state !== GroupCallState.LocalCallFeedInitialized}
onPress={onEnter}
>
Join call now
</Button>
<div className={styles.previewButtons}>
<MicButton
muted={microphoneMuted}
onPress={toggleMicrophoneMuted}
/>
<VideoButton
muted={localVideoMuted}
onPress={toggleLocalVideoMuted}
/>
<OverflowMenu
roomId={roomId}
setShowInspector={setShowInspector}
showInspector={showInspector}
client={client}
/>
</div>
</>
)}
</div>
<p>Or</p>
<CopyButton
value={getRoomUrl(roomId)}
className={styles.copyButton}
copiedMessage="Call link copied"
>
Copy call link and join later
</CopyButton>
</div>
<div className={styles.joinRoomFooter}>
<Link className={styles.homeLink} to="/">
Take me Home
</Link>
</div>
</div>
</div>
);
}
function InRoomView({
client,
groupCall,

104
src/room/LobbyView.jsx Normal file
View file

@ -0,0 +1,104 @@
import React, { useEffect } from "react";
import styles from "./LobbyView.module.css";
import { Button, CopyButton, MicButton, VideoButton } from "../button";
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
import { useCallFeed } from "matrix-react-sdk/src/hooks/useCallFeed";
import { useMediaStream } from "matrix-react-sdk/src/hooks/useMediaStream";
import { getRoomUrl } from "../ConferenceCallManagerHooks";
import { OverflowMenu } from "../OverflowMenu";
import { UserMenuContainer } from "../UserMenuContainer";
import { Body, Link } from "../typography/Typography";
export function LobbyView({
client,
roomName,
state,
onInitLocalCallFeed,
onEnter,
localCallFeed,
microphoneMuted,
localVideoMuted,
toggleLocalVideoMuted,
toggleMicrophoneMuted,
setShowInspector,
showInspector,
roomId,
}) {
const { stream } = useCallFeed(localCallFeed);
const videoRef = useMediaStream(stream, true);
useEffect(() => {
onInitLocalCallFeed();
}, [onInitLocalCallFeed]);
return (
<div className={styles.room}>
<Header>
<LeftNav>
<RoomHeaderInfo roomName={roomName} />
</LeftNav>
<RightNav>
<UserMenuContainer />
</RightNav>
</Header>
<div className={styles.joinRoom}>
<div className={styles.joinRoomContent}>
<div className={styles.preview}>
<video ref={videoRef} muted playsInline disablePictureInPicture />
{state === GroupCallState.LocalCallFeedUninitialized && (
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
Webcam/microphone permissions needed to join the call.
</Body>
)}
{state === GroupCallState.InitializingLocalCallFeed && (
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
Accept webcam/microphone permissions to join the call.
</Body>
)}
{state === GroupCallState.LocalCallFeedInitialized && (
<>
<Button
className={styles.joinCallButton}
disabled={state !== GroupCallState.LocalCallFeedInitialized}
onPress={onEnter}
>
Join call now
</Button>
<div className={styles.previewButtons}>
<MicButton
muted={microphoneMuted}
onPress={toggleMicrophoneMuted}
/>
<VideoButton
muted={localVideoMuted}
onPress={toggleLocalVideoMuted}
/>
<OverflowMenu
roomId={roomId}
setShowInspector={setShowInspector}
showInspector={showInspector}
client={client}
/>
</div>
</>
)}
</div>
<Body>Or</Body>
<CopyButton
value={getRoomUrl(roomId)}
className={styles.copyButton}
copiedMessage="Call link copied"
>
Copy call link and join later
</CopyButton>
</div>
<Body className={styles.joinRoomFooter}>
<Link color="primary" to="/">
Take me Home
</Link>
</Body>
</div>
</div>
);
}

View file

@ -0,0 +1,110 @@
/*
Copyright 2021 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.room {
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 100%;
}
.joinRoom {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
overflow: hidden;
height: 100%;
}
.joinRoomContent {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.joinRoomFooter {
margin: 20px 0;
}
.homeLink {
margin-top: 50px;
}
.preview {
position: relative;
min-height: 280px;
height: 50vh;
border-radius: 24px;
overflow: hidden;
background-color: var(--bgColor3);
margin: 40px 20px 20px 20px;
}
.preview video {
width: 100%;
height: 100%;
object-fit: contain;
background-color: black;
transform: scaleX(-1);
}
.webcamPermissions {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
text-align: center;
}
.previewButtons {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 66px;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(23, 25, 28, 0.9);
}
.joinCallButton {
position: absolute;
width: 100%;
max-width: 222px;
height: 40px;
bottom: 86px;
left: 50%;
font-weight: 600;
font-size: 15px;
transform: translateX(-50%);
}
.copyButton {
width: 320px !important;
}
.previewButtons > * {
margin-right: 30px;
}
.previewButtons > :last-child {
margin-right: 0px;
}