Moving to matrix-js-sdk

This commit is contained in:
Robert Long
2021-09-10 12:20:17 -07:00
parent 4d7e5583eb
commit d813509541
13 changed files with 821 additions and 2519 deletions

View File

@@ -23,7 +23,7 @@ import React, {
} from "react";
import styles from "./Room.module.css";
import { useParams, useLocation, useHistory, Link } from "react-router-dom";
import { useVideoRoom } from "./ConferenceCallManagerHooks";
import { useGroupCall } from "./ConferenceCallManagerHooks";
import { DevTools } from "./DevTools";
import { VideoGrid } from "./VideoGrid";
import {
@@ -42,25 +42,16 @@ function useQuery() {
return useMemo(() => new URLSearchParams(location.search), [location.search]);
}
export function Room({ manager }) {
const { roomId } = useParams();
function useDebugMode() {
const query = useQuery();
const {
loading,
joined,
joining,
room,
participants,
error,
joinCall,
leaveCall,
toggleMuteVideo,
toggleMuteAudio,
videoMuted,
audioMuted,
} = useVideoRoom(manager, roomId);
const debugStr = query.get("debug");
const [debug, setDebug] = useState(debugStr === "" || debugStr === "true");
const [debugMode, setDebugMode] = useState(
debugStr === "" || debugStr === "true"
);
const toggleDebugMode = useCallback(() => {
setDebugMode((prevDebugMode) => !prevDebugMode);
}, []);
useEffect(() => {
function onKeyDown(event) {
@@ -68,7 +59,7 @@ export function Room({ manager }) {
document.activeElement.tagName !== "input" &&
event.code === "Backquote"
) {
setDebug((prevDebug) => !prevDebug);
toggleDebugMode();
}
}
@@ -79,190 +70,237 @@ export function Room({ manager }) {
};
}, []);
return [debugMode, toggleDebugMode];
}
function useRoomLayout() {
const [layout, setLayout] = useState("gallery");
const toggleLayout = useCallback(() => {
setLayout(layout === "spotlight" ? "gallery" : "spotlight");
}, [layout]);
return (
<div className={styles.room}>
{!loading && room && (
<Header>
<LeftNav />
<CenterNav>
<h3>{room.name}</h3>
</CenterNav>
<RightNav>
{!loading && room && joined && (
<LayoutToggleButton
title={layout === "spotlight" ? "Spotlight" : "Gallery"}
layout={layout}
onClick={toggleLayout}
/>
)}
<SettingsButton
title={debug ? "Disable DevTools" : "Enable DevTools"}
on={debug}
onClick={() => setDebug((debug) => !debug)}
/>
</RightNav>
</Header>
)}
{loading && (
<div className={styles.centerMessage}>
<p>Loading room...</p>
</div>
)}
{error && <div className={styles.centerMessage}>{error.message}</div>}
{!loading && room && !joined && (
<JoinRoom
manager={manager}
joining={joining}
joinCall={joinCall}
toggleMuteVideo={toggleMuteVideo}
toggleMuteAudio={toggleMuteAudio}
videoMuted={videoMuted}
audioMuted={audioMuted}
return [layout, toggleLayout];
}
export function Room({ client }) {
const { roomId } = useParams();
const {
loading,
entered,
entering,
roomName,
participants,
groupCall,
microphoneMuted,
localVideoMuted,
error,
initLocalParticipant,
enter,
leave,
toggleLocalVideoMuted,
toggleMicrophoneMuted,
} = useGroupCall(client, roomId);
const content = () => {
if (error) {
return <LoadingErrorView error={error} />;
}
if (loading) {
return <LoadingRoomView />;
}
if (entering) {
return <EnteringRoomView />;
}
if (!entered) {
return (
<RoomSetupView
roomName={roomName}
onInitLocalParticipant={initLocalParticipant}
onEnter={enter}
microphoneMuted={microphoneMuted}
localVideoMuted={localVideoMuted}
toggleLocalVideoMuted={toggleLocalVideoMuted}
toggleMicrophoneMuted={toggleMicrophoneMuted}
/>
)}
{!loading && room && joined && participants.length === 0 && (
<div className={styles.centerMessage}>
<p>Waiting for other participants...</p>
</div>
)}
{!loading && room && joined && participants.length > 0 && (
<VideoGrid participants={participants} layout={layout} />
)}
{!loading && room && joined && (
<div className={styles.footer}>
<MicButton muted={audioMuted} onClick={toggleMuteAudio} />
<VideoButton enabled={videoMuted} onClick={toggleMuteVideo} />
<HangupButton onClick={leaveCall} />
</div>
)}
{debug && <DevTools manager={manager} />}
</div>
);
} else {
return (
<InRoomView
roomName={roomName}
microphoneMuted={microphoneMuted}
localVideoMuted={localVideoMuted}
toggleLocalVideoMuted={toggleLocalVideoMuted}
toggleMicrophoneMuted={toggleMicrophoneMuted}
participants={participants}
onLeave={leave}
groupCall={groupCall}
/>
);
}
};
return <div className={styles.room}>{content()}</div>;
}
export function LoadingRoomView() {
return (
<>
<div className={styles.centerMessage}>
<p>Loading room...</p>
</div>
</>
);
}
export function RoomAuth({ onLoginAsGuest, error }) {
const displayNameRef = useRef();
const history = useHistory();
const location = useLocation();
const onSubmitLoginForm = useCallback(
(e) => {
e.preventDefault();
onLoginAsGuest(displayNameRef.current.value);
},
[onLoginAsGuest, location, history]
export function EnteringRoomView() {
return (
<>
<div className={styles.centerMessage}>
<p>Entering room...</p>
</div>
</>
);
}
export function LoadingErrorView({ error }) {
return (
<>
<div className={styles.centerMessage}>
<ErrorMessage>{error.message}</ErrorMessage>
</div>
</>
);
}
const PermissionState = {
Waiting: "waiting",
Granted: "granted",
Denied: "denied",
};
function RoomSetupView({
roomName,
onInitLocalParticipant,
onEnter,
microphoneMuted,
localVideoMuted,
toggleLocalVideoMuted,
toggleMicrophoneMuted,
groupCall,
}) {
const videoRef = useRef();
const [permissionState, setPermissionState] = useState(
PermissionState.Waiting
);
useEffect(() => {
onInitLocalParticipant()
.then((localParticipant) => {
if (videoRef.current) {
videoRef.current.srcObject = localParticipant.usermediaStream;
videoRef.current.play();
setPermissionState(PermissionState.Granted);
}
})
.catch(() => {
if (videoRef.current) {
setPermissionState(PermissionState.Denied);
}
});
}, [onInitLocalParticipant]);
return (
<>
<Header>
<LeftNav />
<CenterNav>
<h3>{roomName}</h3>
</CenterNav>
</Header>
<Content>
<Center>
<Modal>
<h2>Login As Guest</h2>
<form onSubmit={onSubmitLoginForm}>
<FieldRow>
<InputField
type="text"
ref={displayNameRef}
placeholder="Display Name"
label="Display Name"
autoCorrect="off"
autoCapitalize="none"
/>
</FieldRow>
{error && (
<FieldRow>
<ErrorMessage>{error.message}</ErrorMessage>
</FieldRow>
)}
<FieldRow rightAlign>
<Button type="submit">Login as guest</Button>
</FieldRow>
</form>
<Info>
<Link
to={{
pathname: "/login",
state: location.state,
}}
>
Sign in
</Link>
{" or "}
<Link
to={{
pathname: "/register",
state: location.state,
}}
>
Create account
</Link>
</Info>
</Modal>
</Center>
</Content>
<div className={styles.joinRoom}>
<div className={styles.preview}>
{permissionState === PermissionState.Denied && (
<p className={styles.webcamPermissions}>
Webcam permissions needed to join the call.
</p>
)}
<video ref={videoRef} muted playsInline disablePictureInPicture />
</div>
{permissionState === PermissionState.Granted && (
<div className={styles.previewButtons}>
<MicButton
muted={microphoneMuted}
onClick={toggleMicrophoneMuted}
/>
<VideoButton
enabled={localVideoMuted}
onClick={toggleLocalVideoMuted}
/>
</div>
)}
<Button
disabled={permissionState !== PermissionState.Granted}
onClick={onEnter}
>
Enter Call
</Button>
</div>
</>
);
}
function JoinRoom({
joining,
joinCall,
manager,
toggleMuteVideo,
toggleMuteAudio,
videoMuted,
audioMuted,
function InRoomView({
roomName,
microphoneMuted,
localVideoMuted,
toggleLocalVideoMuted,
toggleMicrophoneMuted,
participants,
onLeave,
groupCall,
}) {
const videoRef = useRef();
const [hasPermissions, setHasPermissions] = useState(false);
const [needsPermissions, setNeedsPermissions] = useState(false);
useEffect(() => {
manager
.getLocalVideoStream()
.then((stream) => {
if (videoRef.current) {
videoRef.current.srcObject = stream;
videoRef.current.play();
setHasPermissions(true);
}
})
.catch(() => {
if (videoRef.current) {
setNeedsPermissions(true);
}
});
}, [manager]);
const [debugMode, toggleDebugMode] = useDebugMode();
const [roomLayout, toggleRoomLayout] = useRoomLayout();
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={audioMuted} onClick={toggleMuteAudio} />
<VideoButton enabled={videoMuted} onClick={toggleMuteVideo} />
<>
<Header>
<LeftNav />
<CenterNav>
<h3>{roomName}</h3>
</CenterNav>
<RightNav>
<LayoutToggleButton
title={roomLayout === "spotlight" ? "Spotlight" : "Gallery"}
layout={roomLayout}
onClick={toggleRoomLayout}
/>
<SettingsButton
title={debugMode ? "Disable DevTools" : "Enable DevTools"}
onClick={toggleDebugMode}
/>
</RightNav>
</Header>
{participants.length === 0 ? (
<div className={styles.centerMessage}>
<p>Waiting for other participants...</p>
</div>
) : (
<VideoGrid participants={participants} layout={roomLayout} />
)}
<Button disabled={!hasPermissions || joining} onClick={joinCall}>
Join Call
</Button>
</div>
<div className={styles.footer}>
<MicButton muted={microphoneMuted} onClick={toggleMicrophoneMuted} />
<VideoButton
enabled={localVideoMuted}
onClick={toggleLocalVideoMuted}
/>
<HangupButton onClick={onLeave} />
</div>
{debugMode && <DevTools groupCall={groupCall} />}
</>
);
}