Join room view

This commit is contained in:
Robert Long 2021-12-06 18:00:34 -08:00
parent 94f42019df
commit db1fb064ca
4 changed files with 81 additions and 69 deletions

View file

@ -6,7 +6,7 @@ import { ReactComponent as CopyIcon } from "./icons/Copy.svg";
import classNames from "classnames"; import classNames from "classnames";
import styles from "./CopyButton.module.css"; import styles from "./CopyButton.module.css";
export function CopyButton({ value, className, ...rest }) { export function CopyButton({ value, className, children, ...rest }) {
const [isCopied, setCopied] = useClipboard(value, { successDuration: 3000 }); const [isCopied, setCopied] = useClipboard(value, { successDuration: 3000 });
const { buttonProps } = useButton({ const { buttonProps } = useButton({
onPress: () => setCopied(), onPress: () => setCopied(),
@ -28,7 +28,7 @@ export function CopyButton({ value, className, ...rest }) {
</> </>
) : ( ) : (
<> <>
<span>{value}</span> <span>{children || value}</span>
<CopyIcon /> <CopyIcon />
</> </>
)} )}

View file

@ -20,13 +20,7 @@ import {
useGroupCallRooms, useGroupCallRooms,
usePublicRooms, usePublicRooms,
} from "./ConferenceCallManagerHooks"; } from "./ConferenceCallManagerHooks";
import { import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
Header,
HeaderLogo,
LeftNav,
RightNav,
UserDropdownMenu,
} from "./Header";
import ColorHash from "color-hash"; import ColorHash from "color-hash";
import styles from "./Home.module.css"; import styles from "./Home.module.css";
import { FieldRow, InputField, Button, ErrorMessage } from "./Input"; import { FieldRow, InputField, Button, ErrorMessage } from "./Input";
@ -36,6 +30,7 @@ import {
GroupCallType, GroupCallType,
} from "matrix-js-sdk/src/browser-index"; } from "matrix-js-sdk/src/browser-index";
import { Facepile } from "./Facepile"; import { Facepile } from "./Facepile";
import { UserMenu } from "./UserMenu";
const colorHash = new ColorHash({ lightness: 0.3 }); const colorHash = new ColorHash({ lightness: 0.3 });
@ -132,9 +127,9 @@ export function Home({ client, onLogout }) {
<HeaderLogo /> <HeaderLogo />
</LeftNav> </LeftNav>
<RightNav> <RightNav>
<UserDropdownMenu <UserMenu
userName={client.getUserIdLocalpart()}
signedIn signedIn
userName={client.getUserIdLocalpart()}
onLogout={onLogout} onLogout={onLogout}
/> />
</RightNav> </RightNav>

View file

@ -16,13 +16,12 @@ limitations under the License.
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import styles from "./Room.module.css"; import styles from "./Room.module.css";
import { useLocation, useParams, useHistory } from "react-router-dom"; import { useLocation, useParams, useHistory, Link } from "react-router-dom";
import { import {
HangupButton, HangupButton,
MicButton, MicButton,
VideoButton, VideoButton,
ScreenshareButton, ScreenshareButton,
DropdownButton,
} from "./RoomButton"; } from "./RoomButton";
import { import {
Header, Header,
@ -30,7 +29,6 @@ import {
RightNav, RightNav,
RoomHeaderInfo, RoomHeaderInfo,
RoomSetupHeaderInfo, RoomSetupHeaderInfo,
UserDropdownMenu,
} from "./Header"; } from "./Header";
import { Button } from "./Input"; import { Button } from "./Input";
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall"; import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
@ -49,7 +47,7 @@ import * as Sentry from "@sentry/react";
import { OverflowMenu } from "./OverflowMenu"; import { OverflowMenu } from "./OverflowMenu";
import { GridLayoutMenu } from "./GridLayoutMenu"; import { GridLayoutMenu } from "./GridLayoutMenu";
import { UserMenu } from "./UserMenu"; import { UserMenu } from "./UserMenu";
import { useMediaHandler } from "./useMediaHandler"; import { CopyButton } from "./CopyButton";
const canScreenshare = "getDisplayMedia" in navigator.mediaDevices; const canScreenshare = "getDisplayMedia" in navigator.mediaDevices;
// There is currently a bug in Safari our our code with cloning and sending MediaStreams // There is currently a bug in Safari our our code with cloning and sending MediaStreams
@ -126,6 +124,7 @@ export function Room({ client, onLogout }) {
} }
export function GroupCallView({ client, groupCall, simpleGrid, onLogout }) { export function GroupCallView({ client, groupCall, simpleGrid, onLogout }) {
const [showInspector, setShowInspector] = useState(false);
const { const {
state, state,
error, error,
@ -200,6 +199,8 @@ export function GroupCallView({ client, groupCall, simpleGrid, onLogout }) {
localScreenshareFeed={localScreenshareFeed} localScreenshareFeed={localScreenshareFeed}
screenshareFeeds={screenshareFeeds} screenshareFeeds={screenshareFeeds}
simpleGrid={simpleGrid} simpleGrid={simpleGrid}
setShowInspector={setShowInspector}
showInspector={showInspector}
/> />
); );
} else if (state === GroupCallState.Entering) { } else if (state === GroupCallState.Entering) {
@ -219,6 +220,8 @@ export function GroupCallView({ client, groupCall, simpleGrid, onLogout }) {
localVideoMuted={localVideoMuted} localVideoMuted={localVideoMuted}
toggleLocalVideoMuted={toggleLocalVideoMuted} toggleLocalVideoMuted={toggleLocalVideoMuted}
toggleMicrophoneMuted={toggleMicrophoneMuted} toggleMicrophoneMuted={toggleMicrophoneMuted}
setShowInspector={setShowInspector}
showInspector={showInspector}
/> />
); );
} }
@ -257,20 +260,13 @@ function RoomSetupView({
toggleLocalVideoMuted, toggleLocalVideoMuted,
toggleMicrophoneMuted, toggleMicrophoneMuted,
hasLocalParticipant, hasLocalParticipant,
setShowInspector,
showInspector,
}) { }) {
const history = useHistory(); const history = useHistory();
const { stream } = useCallFeed(localCallFeed); const { stream } = useCallFeed(localCallFeed);
const videoRef = useMediaStream(stream, true); const videoRef = useMediaStream(stream, true);
const {
audioInput,
audioInputs,
setAudioInput,
videoInput,
videoInputs,
setVideoInput,
} = useMediaHandler(client);
useEffect(() => { useEffect(() => {
onInitLocalCallFeed(); onInitLocalCallFeed();
}, [onInitLocalCallFeed]); }, [onInitLocalCallFeed]);
@ -285,14 +281,15 @@ function RoomSetupView({
/> />
</LeftNav> </LeftNav>
<RightNav> <RightNav>
<UserDropdownMenu <UserMenu
userName={client.getUserIdLocalpart()}
signedIn signedIn
userName={client.getUserIdLocalpart()}
onLogout={onLogout} onLogout={onLogout}
/> />
</RightNav> </RightNav>
</Header> </Header>
<div className={styles.joinRoom}> <div className={styles.joinRoom}>
<h1>New Call</h1>
{hasLocalParticipant && ( {hasLocalParticipant && (
<p>Warning, you are signed into this call on another device.</p> <p>Warning, you are signed into this call on another device.</p>
)} )}
@ -308,43 +305,41 @@ function RoomSetupView({
</p> </p>
)} )}
<video ref={videoRef} muted playsInline disablePictureInPicture /> <video ref={videoRef} muted playsInline disablePictureInPicture />
</div>
{state === GroupCallState.LocalCallFeedInitialized && ( {state === GroupCallState.LocalCallFeedInitialized && (
<div className={styles.previewButtons}> <>
<DropdownButton
value={audioInput}
onChange={({ value }) => setAudioInput(value)}
options={audioInputs.map(({ label, deviceId }) => ({
label,
value: deviceId,
}))}
>
<MicButton
muted={microphoneMuted}
onClick={toggleMicrophoneMuted}
/>
</DropdownButton>
<DropdownButton
value={videoInput}
onChange={({ value }) => setVideoInput(value)}
options={videoInputs.map(({ label, deviceId }) => ({
label,
value: deviceId,
}))}
>
<VideoButton
muted={localVideoMuted}
onClick={toggleLocalVideoMuted}
/>
</DropdownButton>
</div>
)}
<Button <Button
className={styles.joinCallButton}
disabled={state !== GroupCallState.LocalCallFeedInitialized} disabled={state !== GroupCallState.LocalCallFeedInitialized}
onClick={onEnter} onClick={onEnter}
> >
Enter Call Join call now
</Button> </Button>
<div className={styles.previewButtons}>
<MicButton
muted={microphoneMuted}
onPress={toggleMicrophoneMuted}
/>
<VideoButton
muted={localVideoMuted}
onPress={toggleLocalVideoMuted}
/>
<OverflowMenu
roomUrl={window.location.href}
setShowInspector={setShowInspector}
showInspector={showInspector}
client={client}
/>
</div>
</>
)}
</div>
<p>Or</p>
<CopyButton value={window.location.href} className={styles.copyButton}>
Copy call link and join later
</CopyButton>
<Link className={styles.homeLink} to="/">
Take me Home
</Link>
</div> </div>
</> </>
); );
@ -366,9 +361,9 @@ function InRoomView({
isScreensharing, isScreensharing,
screenshareFeeds, screenshareFeeds,
simpleGrid, simpleGrid,
setShowInspector,
showInspector,
}) { }) {
const [showInspector, setShowInspector] = useState(false);
const [layout, setLayout] = useVideoGridLayout(); const [layout, setLayout] = useVideoGridLayout();
const items = useMemo(() => { const items = useMemo(() => {

View file

@ -32,10 +32,16 @@ limitations under the License.
margin-bottom: 20px; margin-bottom: 20px;
} }
.homeLink {
margin-top: 50px;
color: #0dbd8b;
text-decoration: none;
}
.preview { .preview {
position: relative; position: relative;
max-width: 400px; width: 100%;
max-height: 225px; max-width: 816px;
border-radius: 24px; border-radius: 24px;
overflow: hidden; overflow: hidden;
background-color: var(--bgColor3); background-color: var(--bgColor3);
@ -45,7 +51,8 @@ limitations under the License.
.preview video { .preview video {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: contain;
background-color: black;
} }
.webcamPermissions { .webcamPermissions {
@ -60,11 +67,26 @@ limitations under the License.
} }
.previewButtons { .previewButtons {
position: relative; position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 66px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-bottom: 20px; background-color: rgba(23, 25, 28, 0.9);
}
.joinCallButton {
position: absolute;
bottom: 86px;
left: 50%;
transform: translateX(-50%);
}
.copyButton {
width: auto !important;
} }
.previewButtons > * { .previewButtons > * {