Move restore/register/login into ConferenceCallManager
This commit is contained in:
parent
f456265f0c
commit
02d511c0b2
3 changed files with 324 additions and 287 deletions
306
src/App.jsx
306
src/App.jsx
|
@ -25,14 +25,17 @@ import {
|
||||||
Link,
|
Link,
|
||||||
Redirect,
|
Redirect,
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import { ConferenceCall } from "./ConferenceCall";
|
import {
|
||||||
|
useConferenceCallManager,
|
||||||
|
useVideoRoom,
|
||||||
|
} from "./ConferenceCallManagerHooks";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const { protocol, host } = window.location;
|
const { protocol, host } = window.location;
|
||||||
// Assume homeserver is hosted on same domain (proxied in development by vite)
|
// Assume homeserver is hosted on same domain (proxied in development by vite)
|
||||||
const homeserverUrl = `${protocol}//${host}`;
|
const homeserverUrl = `${protocol}//${host}`;
|
||||||
const { loading, authenticated, error, client, login, register } =
|
const { loading, authenticated, error, manager, login, register } =
|
||||||
useClient(homeserverUrl);
|
useConferenceCallManager(homeserverUrl);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
|
@ -44,7 +47,7 @@ export default function App() {
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
{authenticated ? (
|
{authenticated ? (
|
||||||
<JoinOrCreateRoom client={client} />
|
<JoinOrCreateRoom manager={manager} />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
|
@ -56,7 +59,11 @@ export default function App() {
|
||||||
)}
|
)}
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/room/:roomId">
|
<Route path="/room/:roomId">
|
||||||
{!authenticated ? <Redirect to="/" /> : <Room client={client} />}
|
{!authenticated ? (
|
||||||
|
<Redirect to="/" />
|
||||||
|
) : (
|
||||||
|
<Room manager={manager} />
|
||||||
|
)}
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
)}
|
)}
|
||||||
|
@ -65,166 +72,6 @@ export default function App() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForSync(client) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const onSync = (state) => {
|
|
||||||
if (state === "PREPARED") {
|
|
||||||
resolve();
|
|
||||||
client.removeListener("sync", onSync);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
client.on("sync", onSync);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function useClient(homeserverUrl) {
|
|
||||||
const [{ loading, authenticated, client, error }, setState] = useState({
|
|
||||||
loading: true,
|
|
||||||
authenticated: false,
|
|
||||||
client: undefined,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function restoreClient() {
|
|
||||||
try {
|
|
||||||
const authStore = localStorage.getItem("matrix-auth-store");
|
|
||||||
|
|
||||||
if (authStore) {
|
|
||||||
const { user_id, device_id, access_token } = JSON.parse(authStore);
|
|
||||||
|
|
||||||
const client = matrixcs.createClient({
|
|
||||||
baseUrl: homeserverUrl,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.startClient();
|
|
||||||
|
|
||||||
await waitForSync(client);
|
|
||||||
|
|
||||||
setState({
|
|
||||||
client,
|
|
||||||
loading: false,
|
|
||||||
authenticated: true,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState({
|
|
||||||
client: undefined,
|
|
||||||
loading: false,
|
|
||||||
authenticated: false,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
localStorage.removeItem("matrix-auth-store");
|
|
||||||
setState({
|
|
||||||
client: undefined,
|
|
||||||
loading: false,
|
|
||||||
authenticated: false,
|
|
||||||
error: err,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
restoreClient();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const login = useCallback(async (username, password) => {
|
|
||||||
try {
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
authenticated: false,
|
|
||||||
error: undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const registrationClient = matrixcs.createClient(homeserverUrl);
|
|
||||||
|
|
||||||
const { user_id, device_id, access_token } =
|
|
||||||
await registrationClient.loginWithPassword(username, password);
|
|
||||||
|
|
||||||
const client = matrixcs.createClient({
|
|
||||||
baseUrl: homeserverUrl,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.startClient();
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
"matrix-auth-store",
|
|
||||||
JSON.stringify({ user_id, device_id, access_token })
|
|
||||||
);
|
|
||||||
setState({
|
|
||||||
client,
|
|
||||||
loading: false,
|
|
||||||
authenticated: true,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
localStorage.removeItem("matrix-auth-store");
|
|
||||||
setState({
|
|
||||||
client: undefined,
|
|
||||||
loading: false,
|
|
||||||
authenticated: false,
|
|
||||||
error: err,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const register = useCallback(async (username, password) => {
|
|
||||||
try {
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
authenticated: false,
|
|
||||||
error: undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const registrationClient = matrixcs.createClient(homeserverUrl);
|
|
||||||
|
|
||||||
const { user_id, device_id, access_token } =
|
|
||||||
await registrationClient.register(username, password, null, {
|
|
||||||
type: "m.login.dummy",
|
|
||||||
});
|
|
||||||
|
|
||||||
const client = matrixcs.createClient({
|
|
||||||
baseUrl: homeserverUrl,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.startClient();
|
|
||||||
|
|
||||||
localStorage.setItem(
|
|
||||||
"matrix-auth-store",
|
|
||||||
JSON.stringify({ user_id, device_id, access_token })
|
|
||||||
);
|
|
||||||
setState({
|
|
||||||
client,
|
|
||||||
loading: false,
|
|
||||||
authenticated: true,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
localStorage.removeItem("matrix-auth-store");
|
|
||||||
setState({
|
|
||||||
client: undefined,
|
|
||||||
loading: false,
|
|
||||||
authenticated: false,
|
|
||||||
error: err,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return { loading, authenticated, client, error, login, register };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Register({ onRegister }) {
|
function Register({ onRegister }) {
|
||||||
const usernameRef = useRef();
|
const usernameRef = useRef();
|
||||||
const passwordRef = useRef();
|
const passwordRef = useRef();
|
||||||
|
@ -267,7 +114,7 @@ function Login({ onLogin }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function JoinOrCreateRoom({ client }) {
|
function JoinOrCreateRoom({ manager }) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const roomNameRef = useRef();
|
const roomNameRef = useRef();
|
||||||
const roomIdRef = useRef();
|
const roomIdRef = useRef();
|
||||||
|
@ -277,15 +124,15 @@ function JoinOrCreateRoom({ client }) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function updateRooms() {
|
function updateRooms() {
|
||||||
setRooms(client.getRooms());
|
setRooms(manager.client.getRooms());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRooms();
|
updateRooms();
|
||||||
|
|
||||||
client.on("Room", updateRooms);
|
manager.client.on("Room", updateRooms);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
client.removeListener("Room", updateRooms);
|
manager.client.removeListener("Room", updateRooms);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -294,7 +141,7 @@ function JoinOrCreateRoom({ client }) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setCreateRoomError(undefined);
|
setCreateRoomError(undefined);
|
||||||
|
|
||||||
client
|
manager.client
|
||||||
.createRoom({
|
.createRoom({
|
||||||
visibility: "private",
|
visibility: "private",
|
||||||
preset: "public_chat",
|
preset: "public_chat",
|
||||||
|
@ -305,7 +152,7 @@ function JoinOrCreateRoom({ client }) {
|
||||||
})
|
})
|
||||||
.catch(setCreateRoomError);
|
.catch(setCreateRoomError);
|
||||||
},
|
},
|
||||||
[client]
|
[manager]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onJoinRoom = useCallback(
|
const onJoinRoom = useCallback(
|
||||||
|
@ -313,14 +160,14 @@ function JoinOrCreateRoom({ client }) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setJoinRoomError(undefined);
|
setJoinRoomError(undefined);
|
||||||
|
|
||||||
client
|
manager.client
|
||||||
.joinRoom(roomIdRef.current.value)
|
.joinRoom(roomIdRef.current.value)
|
||||||
.then(({ roomId }) => {
|
.then(({ roomId }) => {
|
||||||
history.push(`/room/${roomId}`);
|
history.push(`/room/${roomId}`);
|
||||||
})
|
})
|
||||||
.catch(setJoinRoomError);
|
.catch(setJoinRoomError);
|
||||||
},
|
},
|
||||||
[client]
|
[manager]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -366,117 +213,10 @@ function JoinOrCreateRoom({ client }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useVideoRoom(client, roomId, timeout = 5000) {
|
function Room({ manager }) {
|
||||||
const [
|
|
||||||
{ loading, joined, room, conferenceCall, participants, error },
|
|
||||||
setState,
|
|
||||||
] = useState({
|
|
||||||
loading: true,
|
|
||||||
joined: false,
|
|
||||||
room: undefined,
|
|
||||||
participants: [],
|
|
||||||
error: undefined,
|
|
||||||
conferenceCall: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const conferenceCall = new ConferenceCall(client, roomId);
|
|
||||||
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
conferenceCall,
|
|
||||||
loading: true,
|
|
||||||
room: undefined,
|
|
||||||
error: undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
client.joinRoom(roomId).catch((err) => {
|
|
||||||
setState((prevState) => ({ ...prevState, loading: false, error: err }));
|
|
||||||
});
|
|
||||||
|
|
||||||
let initialRoom = client.getRoom(roomId);
|
|
||||||
|
|
||||||
if (initialRoom) {
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
loading: false,
|
|
||||||
room: initialRoom,
|
|
||||||
error: undefined,
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let timeoutId;
|
|
||||||
|
|
||||||
function roomCallback(room) {
|
|
||||||
if (room && room.roomId === roomId) {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
client.removeListener("Room", roomCallback);
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
loading: false,
|
|
||||||
room,
|
|
||||||
error: undefined,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client.on("Room", roomCallback);
|
|
||||||
|
|
||||||
timeoutId = setTimeout(() => {
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
loading: false,
|
|
||||||
room: undefined,
|
|
||||||
error: new Error("Room could not be found."),
|
|
||||||
}));
|
|
||||||
client.removeListener("Room", roomCallback);
|
|
||||||
}, timeout);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
client.removeListener("Room", roomCallback);
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
};
|
|
||||||
}, [roomId]);
|
|
||||||
|
|
||||||
const joinCall = useCallback(() => {
|
|
||||||
const onParticipantsChanged = () => {
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
participants: conferenceCall.participants,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
conferenceCall.on("participants_changed", onParticipantsChanged);
|
|
||||||
|
|
||||||
conferenceCall.join();
|
|
||||||
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
joined: true,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
conferenceCall.removeListener(
|
|
||||||
"participants_changed",
|
|
||||||
onParticipantsChanged
|
|
||||||
);
|
|
||||||
|
|
||||||
setState((prevState) => ({
|
|
||||||
...prevState,
|
|
||||||
joined: false,
|
|
||||||
participants: [],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
}, [client, conferenceCall, roomId]);
|
|
||||||
|
|
||||||
return { loading, joined, room, participants, error, joinCall };
|
|
||||||
}
|
|
||||||
|
|
||||||
function Room({ client }) {
|
|
||||||
const { roomId } = useParams();
|
const { roomId } = useParams();
|
||||||
const { loading, joined, room, participants, error, joinCall } = useVideoRoom(
|
const { loading, joined, room, participants, error, joinCall } = useVideoRoom(
|
||||||
client,
|
manager,
|
||||||
roomId
|
roomId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -486,7 +226,7 @@ function Room({ client }) {
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<h3>{room.name}</h3>
|
<h3>{room.name}</h3>
|
||||||
<div className={styles.userNav}>
|
<div className={styles.userNav}>
|
||||||
<h5>{client.getUserId()}</h5>
|
<h5>{manager.client.getUserId()}</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -4,11 +4,118 @@ const CONF_ROOM = "me.robertlong.conf";
|
||||||
const CONF_PARTICIPANT = "me.robertlong.conf.participant";
|
const CONF_PARTICIPANT = "me.robertlong.conf.participant";
|
||||||
const PARTICIPANT_TIMEOUT = 1000 * 5;
|
const PARTICIPANT_TIMEOUT = 1000 * 5;
|
||||||
|
|
||||||
export class ConferenceCall extends EventEmitter {
|
function waitForSync(client) {
|
||||||
constructor(client, roomId) {
|
return new Promise((resolve, reject) => {
|
||||||
|
const onSync = (state) => {
|
||||||
|
if (state === "PREPARED") {
|
||||||
|
resolve();
|
||||||
|
client.removeListener("sync", onSync);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
client.on("sync", onSync);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ConferenceCallManager extends EventEmitter {
|
||||||
|
static async restore(homeserverUrl) {
|
||||||
|
try {
|
||||||
|
const authStore = localStorage.getItem("matrix-auth-store");
|
||||||
|
|
||||||
|
if (authStore) {
|
||||||
|
const { user_id, device_id, access_token } = JSON.parse(authStore);
|
||||||
|
|
||||||
|
const client = matrixcs.createClient({
|
||||||
|
baseUrl: homeserverUrl,
|
||||||
|
accessToken: access_token,
|
||||||
|
userId: user_id,
|
||||||
|
deviceId: device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const manager = new ConferenceCallManager(client);
|
||||||
|
|
||||||
|
await client.startClient();
|
||||||
|
|
||||||
|
await waitForSync(client);
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
localStorage.removeItem("matrix-auth-store");
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async login(homeserverUrl, username, password) {
|
||||||
|
try {
|
||||||
|
const registrationClient = matrixcs.createClient(homeserverUrl);
|
||||||
|
|
||||||
|
const { user_id, device_id, access_token } =
|
||||||
|
await registrationClient.loginWithPassword(username, password);
|
||||||
|
|
||||||
|
const client = matrixcs.createClient({
|
||||||
|
baseUrl: homeserverUrl,
|
||||||
|
accessToken: access_token,
|
||||||
|
userId: user_id,
|
||||||
|
deviceId: device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
localStorage.setItem(
|
||||||
|
"matrix-auth-store",
|
||||||
|
JSON.stringify({ user_id, device_id, access_token })
|
||||||
|
);
|
||||||
|
|
||||||
|
const manager = new ConferenceCallManager(client);
|
||||||
|
|
||||||
|
await client.startClient();
|
||||||
|
|
||||||
|
await waitForSync(client);
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
} catch (err) {
|
||||||
|
localStorage.removeItem("matrix-auth-store");
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async register(homeserverUrl, username, password) {
|
||||||
|
try {
|
||||||
|
const registrationClient = matrixcs.createClient(homeserverUrl);
|
||||||
|
|
||||||
|
const { user_id, device_id, access_token } =
|
||||||
|
await registrationClient.register(username, password, null, {
|
||||||
|
type: "m.login.dummy",
|
||||||
|
});
|
||||||
|
|
||||||
|
const client = matrixcs.createClient({
|
||||||
|
baseUrl: homeserverUrl,
|
||||||
|
accessToken: access_token,
|
||||||
|
userId: user_id,
|
||||||
|
deviceId: device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
localStorage.setItem(
|
||||||
|
"matrix-auth-store",
|
||||||
|
JSON.stringify({ user_id, device_id, access_token })
|
||||||
|
);
|
||||||
|
|
||||||
|
const manager = new ConferenceCallManager(client);
|
||||||
|
|
||||||
|
await client.startClient();
|
||||||
|
|
||||||
|
await waitForSync(client);
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
} catch (err) {
|
||||||
|
localStorage.removeItem("matrix-auth-store");
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
super();
|
super();
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.roomId = roomId;
|
|
||||||
this.joined = false;
|
this.joined = false;
|
||||||
this.room = null;
|
this.room = null;
|
||||||
this.localParticipant = {
|
this.localParticipant = {
|
||||||
|
@ -25,7 +132,7 @@ export class ConferenceCall extends EventEmitter {
|
||||||
this.client.on("Call.incoming", this._onIncomingCall);
|
this.client.on("Call.incoming", this._onIncomingCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
join() {
|
join(roomId) {
|
||||||
console.debug(
|
console.debug(
|
||||||
"join",
|
"join",
|
||||||
`Local user ${this.client.getUserId()} joining room ${this.roomId}`
|
`Local user ${this.client.getUserId()} joining room ${this.roomId}`
|
||||||
|
@ -33,6 +140,7 @@ export class ConferenceCall extends EventEmitter {
|
||||||
|
|
||||||
this.joined = true;
|
this.joined = true;
|
||||||
|
|
||||||
|
this.roomId = roomId;
|
||||||
this.room = this.client.getRoom(this.roomId);
|
this.room = this.client.getRoom(this.roomId);
|
||||||
|
|
||||||
const activeConf = this.room.currentState
|
const activeConf = this.room.currentState
|
189
src/ConferenceCallManagerHooks.js
Normal file
189
src/ConferenceCallManagerHooks.js
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import { ConferenceCallManager } from "./ConferenceCallManager";
|
||||||
|
|
||||||
|
export function useConferenceCallManager(homeserverUrl) {
|
||||||
|
const [{ loading, authenticated, manager, error }, setState] = useState({
|
||||||
|
loading: true,
|
||||||
|
authenticated: false,
|
||||||
|
manager: undefined,
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
ConferenceCallManager.restore(homeserverUrl)
|
||||||
|
.then((manager) => {
|
||||||
|
console.log(manager);
|
||||||
|
setState({
|
||||||
|
manager,
|
||||||
|
loading: false,
|
||||||
|
authenticated: !!manager,
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
setState({
|
||||||
|
manager: undefined,
|
||||||
|
loading: false,
|
||||||
|
authenticated: false,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const login = useCallback(async (username, password) => {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
authenticated: false,
|
||||||
|
error: undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
ConferenceCallManager.login(homeserverUrl, username, password)
|
||||||
|
.then((manager) => {
|
||||||
|
setState({
|
||||||
|
manager,
|
||||||
|
loading: false,
|
||||||
|
authenticated: true,
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
setState({
|
||||||
|
manager: undefined,
|
||||||
|
loading: false,
|
||||||
|
authenticated: false,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const register = useCallback(async (username, password) => {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
authenticated: false,
|
||||||
|
error: undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
ConferenceCallManager.register(homeserverUrl, username, password)
|
||||||
|
.then((manager) => {
|
||||||
|
setState({
|
||||||
|
manager,
|
||||||
|
loading: false,
|
||||||
|
authenticated: true,
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
setState({
|
||||||
|
manager: undefined,
|
||||||
|
loading: false,
|
||||||
|
authenticated: false,
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { loading, authenticated, manager, error, login, register };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useVideoRoom(manager, roomId, timeout = 5000) {
|
||||||
|
const [{ loading, joined, room, participants, error }, setState] = useState({
|
||||||
|
loading: true,
|
||||||
|
joined: false,
|
||||||
|
room: undefined,
|
||||||
|
participants: [],
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
loading: true,
|
||||||
|
room: undefined,
|
||||||
|
error: undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
manager.client.joinRoom(roomId).catch((err) => {
|
||||||
|
setState((prevState) => ({ ...prevState, loading: false, error: err }));
|
||||||
|
});
|
||||||
|
|
||||||
|
let initialRoom = manager.client.getRoom(roomId);
|
||||||
|
|
||||||
|
if (initialRoom) {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
loading: false,
|
||||||
|
room: initialRoom,
|
||||||
|
error: undefined,
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeoutId;
|
||||||
|
|
||||||
|
function roomCallback(room) {
|
||||||
|
if (room && room.roomId === roomId) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
manager.client.removeListener("Room", roomCallback);
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
loading: false,
|
||||||
|
room,
|
||||||
|
error: undefined,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.client.on("Room", roomCallback);
|
||||||
|
|
||||||
|
timeoutId = setTimeout(() => {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
loading: false,
|
||||||
|
room: undefined,
|
||||||
|
error: new Error("Room could not be found."),
|
||||||
|
}));
|
||||||
|
manager.client.removeListener("Room", roomCallback);
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
manager.client.removeListener("Room", roomCallback);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
};
|
||||||
|
}, [roomId]);
|
||||||
|
|
||||||
|
const joinCall = useCallback(() => {
|
||||||
|
const onParticipantsChanged = () => {
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
participants: manager.participants,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
manager.on("participants_changed", onParticipantsChanged);
|
||||||
|
|
||||||
|
manager.join(roomId);
|
||||||
|
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
joined: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
manager.removeListener("participants_changed", onParticipantsChanged);
|
||||||
|
|
||||||
|
setState((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
joined: false,
|
||||||
|
participants: [],
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}, [manager, roomId]);
|
||||||
|
|
||||||
|
return { loading, joined, room, participants, error, joinCall };
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue