mirror of
https://github.com/vector-im/element-call.git
synced 2024-11-15 00:04:59 +08:00
Finish splitting up components
This commit is contained in:
parent
14ad312181
commit
4b0bb13f1e
229
src/App.jsx
229
src/App.jsx
@ -14,22 +14,17 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import styles from "./App.module.css";
|
||||
import React from "react";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Switch,
|
||||
Route,
|
||||
useHistory,
|
||||
useParams,
|
||||
Link,
|
||||
Redirect,
|
||||
} from "react-router-dom";
|
||||
import {
|
||||
useConferenceCallManager,
|
||||
useVideoRoom,
|
||||
useRooms,
|
||||
} from "./ConferenceCallManagerHooks";
|
||||
import { useConferenceCallManager } from "./ConferenceCallManagerHooks";
|
||||
import { JoinOrCreateRoom } from "./JoinOrCreateRoom";
|
||||
import { LoginOrRegister } from "./LoginOrRegister";
|
||||
import { Room } from "./Room";
|
||||
|
||||
export default function App() {
|
||||
const { protocol, host } = window.location;
|
||||
@ -40,7 +35,7 @@ export default function App() {
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<div className={styles.app}>
|
||||
<div>
|
||||
{error && <p>{error.message}</p>}
|
||||
{loading ? (
|
||||
<p>Loading...</p>
|
||||
@ -66,215 +61,3 @@ export default function App() {
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
function LoginOrRegister({ onRegister, onLogin }) {
|
||||
const registerUsernameRef = useRef();
|
||||
const registerPasswordRef = useRef();
|
||||
const loginUsernameRef = useRef();
|
||||
const loginPasswordRef = useRef();
|
||||
|
||||
const onSubmitRegisterForm = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
onRegister(usernameRef.current.value, passwordRef.current.value);
|
||||
});
|
||||
|
||||
const onSubmitLoginForm = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
onLogin(usernameRef.current.value, passwordRef.current.value);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<h1>Matrix Video Chat</h1>
|
||||
<h2>Register</h2>
|
||||
<form onSubmit={onSubmitRegisterForm}>
|
||||
<input
|
||||
type="text"
|
||||
ref={registerUsernameRef}
|
||||
placeholder="Username"
|
||||
></input>
|
||||
<input
|
||||
type="password"
|
||||
ref={registerPasswordRef}
|
||||
placeholder="Password"
|
||||
></input>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<h2>Login</h2>
|
||||
<form onSubmit={onSubmitLoginForm}>
|
||||
<input
|
||||
type="text"
|
||||
ref={loginUsernameRef}
|
||||
placeholder="Username"
|
||||
></input>
|
||||
<input
|
||||
type="password"
|
||||
ref={loginPasswordRef}
|
||||
placeholder="Password"
|
||||
></input>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function JoinOrCreateRoom({ manager }) {
|
||||
const history = useHistory();
|
||||
const roomNameRef = useRef();
|
||||
const roomIdRef = useRef();
|
||||
const [createRoomError, setCreateRoomError] = useState();
|
||||
const [joinRoomError, setJoinRoomError] = useState();
|
||||
const rooms = useRooms(manager);
|
||||
|
||||
const onCreateRoom = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
setCreateRoomError(undefined);
|
||||
|
||||
manager.client
|
||||
.createRoom({
|
||||
visibility: "private",
|
||||
preset: "public_chat",
|
||||
name: roomNameRef.current.value,
|
||||
})
|
||||
.then(({ room_id }) => {
|
||||
history.push(`/room/${room_id}`);
|
||||
})
|
||||
.catch(setCreateRoomError);
|
||||
},
|
||||
[manager]
|
||||
);
|
||||
|
||||
const onJoinRoom = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
setJoinRoomError(undefined);
|
||||
|
||||
manager.client
|
||||
.joinRoom(roomIdRef.current.value)
|
||||
.then(({ roomId }) => {
|
||||
history.push(`/room/${roomId}`);
|
||||
})
|
||||
.catch(setJoinRoomError);
|
||||
},
|
||||
[manager]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<h1>Matrix Video Chat</h1>
|
||||
<form onSubmit={onCreateRoom}>
|
||||
<h2>Create New Room</h2>
|
||||
<input
|
||||
id="roomName"
|
||||
name="roomName"
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
placeholder="Room Name"
|
||||
ref={roomNameRef}
|
||||
></input>
|
||||
{createRoomError && <p>{createRoomError.message}</p>}
|
||||
<button type="submit">Create Room</button>
|
||||
</form>
|
||||
<form onSubmit={onJoinRoom}>
|
||||
<h2>Join Existing Room</h2>
|
||||
<input
|
||||
id="roomId"
|
||||
name="roomId"
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
placeholder="Room ID"
|
||||
ref={roomIdRef}
|
||||
></input>
|
||||
{joinRoomError && <p>{joinRoomError.message}</p>}
|
||||
<button type="submit">Join Room</button>
|
||||
</form>
|
||||
<h2>Rooms:</h2>
|
||||
<ul>
|
||||
{rooms.map((room) => (
|
||||
<li key={room.roomId}>
|
||||
<Link to={`/room/${room.roomId}`}>{room.name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Room({ manager }) {
|
||||
const { roomId } = useParams();
|
||||
const { loading, joined, room, participants, error, joinCall } = useVideoRoom(
|
||||
manager,
|
||||
roomId
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
{!loading && room && (
|
||||
<div className={styles.header}>
|
||||
<h3>{room.name}</h3>
|
||||
<div className={styles.userNav}>
|
||||
<h5>{manager.client.getUserId()}</h5>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{loading && (
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Loading room...</p>
|
||||
</div>
|
||||
)}
|
||||
{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 onClick={joinCall}>Join Call</button>
|
||||
</div>
|
||||
)}
|
||||
{!loading && room && joined && participants.length === 0 && (
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Waiting for other participants...</p>
|
||||
</div>
|
||||
)}
|
||||
{!loading && room && joined && participants.length > 0 && (
|
||||
<div className={styles.roomContainer}>
|
||||
{participants.map((participant) => (
|
||||
<Participant key={participant.userId} participant={participant} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Participant({ participant }) {
|
||||
const videoRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
if (participant.feed) {
|
||||
if (participant.muted) {
|
||||
videoRef.current.muted = true;
|
||||
}
|
||||
|
||||
videoRef.current.srcObject = participant.feed.stream;
|
||||
videoRef.current.play();
|
||||
}
|
||||
}, [participant.feed]);
|
||||
|
||||
return (
|
||||
<div className={styles.participant}>
|
||||
<video ref={videoRef}></video>
|
||||
<div className={styles.participantLabel}>
|
||||
<p>
|
||||
{participant.userId} {participant.local && "(You)"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import EventEmitter from "events";
|
||||
|
||||
const CONF_ROOM = "me.robertlong.conf";
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { ConferenceCallManager } from "./ConferenceCallManager";
|
||||
|
||||
|
104
src/JoinOrCreateRoom.jsx
Normal file
104
src/JoinOrCreateRoom.jsx
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useRef, useState } from "react";
|
||||
import { useHistory, Link } from "react-router-dom";
|
||||
import { useRooms } from "./ConferenceCallManagerHooks";
|
||||
|
||||
export function JoinOrCreateRoom({ manager }) {
|
||||
const history = useHistory();
|
||||
const roomNameRef = useRef();
|
||||
const roomIdRef = useRef();
|
||||
const [createRoomError, setCreateRoomError] = useState();
|
||||
const [joinRoomError, setJoinRoomError] = useState();
|
||||
const rooms = useRooms(manager);
|
||||
|
||||
const onCreateRoom = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
setCreateRoomError(undefined);
|
||||
|
||||
manager.client
|
||||
.createRoom({
|
||||
visibility: "private",
|
||||
preset: "public_chat",
|
||||
name: roomNameRef.current.value,
|
||||
})
|
||||
.then(({ room_id }) => {
|
||||
history.push(`/room/${room_id}`);
|
||||
})
|
||||
.catch(setCreateRoomError);
|
||||
},
|
||||
[manager]
|
||||
);
|
||||
|
||||
const onJoinRoom = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
setJoinRoomError(undefined);
|
||||
|
||||
manager.client
|
||||
.joinRoom(roomIdRef.current.value)
|
||||
.then(({ roomId }) => {
|
||||
history.push(`/room/${roomId}`);
|
||||
})
|
||||
.catch(setJoinRoomError);
|
||||
},
|
||||
[manager]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="page">
|
||||
<h1>Matrix Video Chat</h1>
|
||||
<form onSubmit={onCreateRoom}>
|
||||
<h2>Create New Room</h2>
|
||||
<input
|
||||
id="roomName"
|
||||
name="roomName"
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
placeholder="Room Name"
|
||||
ref={roomNameRef}
|
||||
></input>
|
||||
{createRoomError && <p>{createRoomError.message}</p>}
|
||||
<button type="submit">Create Room</button>
|
||||
</form>
|
||||
<form onSubmit={onJoinRoom}>
|
||||
<h2>Join Existing Room</h2>
|
||||
<input
|
||||
id="roomId"
|
||||
name="roomId"
|
||||
type="text"
|
||||
required
|
||||
autoComplete="off"
|
||||
placeholder="Room ID"
|
||||
ref={roomIdRef}
|
||||
></input>
|
||||
{joinRoomError && <p>{joinRoomError.message}</p>}
|
||||
<button type="submit">Join Room</button>
|
||||
</form>
|
||||
<h2>Rooms:</h2>
|
||||
<ul>
|
||||
{rooms.map((room) => (
|
||||
<li key={room.roomId}>
|
||||
<Link to={`/room/${room.roomId}`}>{room.name}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
68
src/LoginOrRegister.jsx
Normal file
68
src/LoginOrRegister.jsx
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useRef } from "react";
|
||||
|
||||
export function LoginOrRegister({ onRegister, onLogin }) {
|
||||
const registerUsernameRef = useRef();
|
||||
const registerPasswordRef = useRef();
|
||||
const loginUsernameRef = useRef();
|
||||
const loginPasswordRef = useRef();
|
||||
|
||||
const onSubmitRegisterForm = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
onRegister(usernameRef.current.value, passwordRef.current.value);
|
||||
});
|
||||
|
||||
const onSubmitLoginForm = useCallback((e) => {
|
||||
e.preventDefault();
|
||||
onLogin(usernameRef.current.value, passwordRef.current.value);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="page">
|
||||
<h1>Matrix Video Chat</h1>
|
||||
<h2>Register</h2>
|
||||
<form onSubmit={onSubmitRegisterForm}>
|
||||
<input
|
||||
type="text"
|
||||
ref={registerUsernameRef}
|
||||
placeholder="Username"
|
||||
></input>
|
||||
<input
|
||||
type="password"
|
||||
ref={registerPasswordRef}
|
||||
placeholder="Password"
|
||||
></input>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<h2>Login</h2>
|
||||
<form onSubmit={onSubmitLoginForm}>
|
||||
<input
|
||||
type="text"
|
||||
ref={loginUsernameRef}
|
||||
placeholder="Username"
|
||||
></input>
|
||||
<input
|
||||
type="password"
|
||||
ref={loginPasswordRef}
|
||||
placeholder="Password"
|
||||
></input>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
96
src/Room.jsx
Normal file
96
src/Room.jsx
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import styles from "./Room.module.css";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useVideoRoom } from "./ConferenceCallManagerHooks";
|
||||
|
||||
export function Room({ manager }) {
|
||||
const { roomId } = useParams();
|
||||
const { loading, joined, room, participants, error, joinCall } = useVideoRoom(
|
||||
manager,
|
||||
roomId
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
{!loading && room && (
|
||||
<div className={styles.header}>
|
||||
<h3>{room.name}</h3>
|
||||
<div className={styles.userNav}>
|
||||
<h5>{manager.client.getUserId()}</h5>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{loading && (
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Loading room...</p>
|
||||
</div>
|
||||
)}
|
||||
{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 onClick={joinCall}>Join Call</button>
|
||||
</div>
|
||||
)}
|
||||
{!loading && room && joined && participants.length === 0 && (
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Waiting for other participants...</p>
|
||||
</div>
|
||||
)}
|
||||
{!loading && room && joined && participants.length > 0 && (
|
||||
<div className={styles.roomContainer}>
|
||||
{participants.map((participant) => (
|
||||
<Participant key={participant.userId} participant={participant} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Participant({ participant }) {
|
||||
const videoRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
if (participant.feed) {
|
||||
if (participant.muted) {
|
||||
videoRef.current.muted = true;
|
||||
}
|
||||
|
||||
videoRef.current.srcObject = participant.feed.stream;
|
||||
videoRef.current.play();
|
||||
}
|
||||
}, [participant.feed]);
|
||||
|
||||
return (
|
||||
<div className={styles.participant}>
|
||||
<video ref={videoRef}></video>
|
||||
<div className={styles.participantLabel}>
|
||||
<p>
|
||||
{participant.userId} {participant.local && "(You)"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -14,25 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.page {
|
||||
margin: 0 auto;
|
||||
max-width: 960px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.page input {
|
||||
padding: 8px 4px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #888;
|
||||
}
|
||||
|
||||
.page input, .page button {
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.room {
|
||||
position: fixed;
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
body {
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
@ -31,4 +47,24 @@ a {
|
||||
|
||||
a:hover, a:active {
|
||||
color: rgb(76, 134, 173);
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
margin: 0 auto;
|
||||
max-width: 960px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.page input {
|
||||
padding: 8px 4px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #888;
|
||||
}
|
||||
|
||||
.page input, .page button {
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user