Refactor room loading components
This commit is contained in:
parent
550c45b69e
commit
0fe38000f5
5 changed files with 191 additions and 170 deletions
25
src/room/GroupCallLoader.jsx
Normal file
25
src/room/GroupCallLoader.jsx
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from "react";
|
||||||
|
import { useLoadGroupCall } from "../ConferenceCallManagerHooks";
|
||||||
|
import { ErrorView, FullScreenView } from "../FullScreenView";
|
||||||
|
|
||||||
|
export function GroupCallLoader({ client, roomId, viaServers, children }) {
|
||||||
|
const { loading, error, groupCall } = useLoadGroupCall(
|
||||||
|
client,
|
||||||
|
roomId,
|
||||||
|
viaServers
|
||||||
|
);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<FullScreenView>
|
||||||
|
<h1>Loading room...</h1>
|
||||||
|
</FullScreenView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <ErrorView error={error} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return children(groupCall);
|
||||||
|
}
|
||||||
111
src/room/GroupCallView.jsx
Normal file
111
src/room/GroupCallView.jsx
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
import { useHistory } from "react-router-dom";
|
||||||
|
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||||
|
import { useGroupCall } from "matrix-react-sdk/src/hooks/useGroupCall";
|
||||||
|
import { ErrorView, FullScreenView } from "../FullScreenView";
|
||||||
|
import { LobbyView } from "./LobbyView";
|
||||||
|
import { InCallView } from "./InCallView";
|
||||||
|
import { CallEndedView } from "./CallEndedView";
|
||||||
|
import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler";
|
||||||
|
|
||||||
|
export function GroupCallView({
|
||||||
|
client,
|
||||||
|
isPasswordlessUser,
|
||||||
|
roomId,
|
||||||
|
groupCall,
|
||||||
|
simpleGrid,
|
||||||
|
}) {
|
||||||
|
const [showInspector, setShowInspector] = useState(false);
|
||||||
|
const {
|
||||||
|
state,
|
||||||
|
error,
|
||||||
|
activeSpeaker,
|
||||||
|
userMediaFeeds,
|
||||||
|
microphoneMuted,
|
||||||
|
localVideoMuted,
|
||||||
|
localCallFeed,
|
||||||
|
initLocalCallFeed,
|
||||||
|
enter,
|
||||||
|
leave,
|
||||||
|
toggleLocalVideoMuted,
|
||||||
|
toggleMicrophoneMuted,
|
||||||
|
toggleScreensharing,
|
||||||
|
isScreensharing,
|
||||||
|
localScreenshareFeed,
|
||||||
|
screenshareFeeds,
|
||||||
|
hasLocalParticipant,
|
||||||
|
} = useGroupCall(groupCall);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.groupCall = groupCall;
|
||||||
|
}, [groupCall]);
|
||||||
|
|
||||||
|
useSentryGroupCallHandler(groupCall);
|
||||||
|
|
||||||
|
const [left, setLeft] = useState(false);
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const onLeave = useCallback(() => {
|
||||||
|
leave();
|
||||||
|
|
||||||
|
if (!isPasswordlessUser) {
|
||||||
|
history.push("/");
|
||||||
|
} else {
|
||||||
|
setLeft(true);
|
||||||
|
}
|
||||||
|
}, [leave, history]);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return <ErrorView error={error} />;
|
||||||
|
} else if (state === GroupCallState.Entered) {
|
||||||
|
return (
|
||||||
|
<InCallView
|
||||||
|
groupCall={groupCall}
|
||||||
|
client={client}
|
||||||
|
roomName={groupCall.room.name}
|
||||||
|
microphoneMuted={microphoneMuted}
|
||||||
|
localVideoMuted={localVideoMuted}
|
||||||
|
toggleLocalVideoMuted={toggleLocalVideoMuted}
|
||||||
|
toggleMicrophoneMuted={toggleMicrophoneMuted}
|
||||||
|
userMediaFeeds={userMediaFeeds}
|
||||||
|
activeSpeaker={activeSpeaker}
|
||||||
|
onLeave={onLeave}
|
||||||
|
toggleScreensharing={toggleScreensharing}
|
||||||
|
isScreensharing={isScreensharing}
|
||||||
|
localScreenshareFeed={localScreenshareFeed}
|
||||||
|
screenshareFeeds={screenshareFeeds}
|
||||||
|
simpleGrid={simpleGrid}
|
||||||
|
setShowInspector={setShowInspector}
|
||||||
|
showInspector={showInspector}
|
||||||
|
roomId={roomId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (state === GroupCallState.Entering) {
|
||||||
|
return (
|
||||||
|
<FullScreenView>
|
||||||
|
<h1>Entering room...</h1>
|
||||||
|
</FullScreenView>
|
||||||
|
);
|
||||||
|
} else if (left) {
|
||||||
|
return <CallEndedView client={client} />;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<LobbyView
|
||||||
|
client={client}
|
||||||
|
hasLocalParticipant={hasLocalParticipant}
|
||||||
|
roomName={groupCall.room.name}
|
||||||
|
state={state}
|
||||||
|
onInitLocalCallFeed={initLocalCallFeed}
|
||||||
|
localCallFeed={localCallFeed}
|
||||||
|
onEnter={enter}
|
||||||
|
microphoneMuted={microphoneMuted}
|
||||||
|
localVideoMuted={localVideoMuted}
|
||||||
|
toggleLocalVideoMuted={toggleLocalVideoMuted}
|
||||||
|
toggleMicrophoneMuted={toggleMicrophoneMuted}
|
||||||
|
setShowInspector={setShowInspector}
|
||||||
|
showInspector={showInspector}
|
||||||
|
roomId={roomId}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/room/RoomAuthView.jsx
Normal file
5
src/room/RoomAuthView.jsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export function RoomAuthView() {
|
||||||
|
return <div>Register</div>;
|
||||||
|
}
|
||||||
|
|
@ -14,40 +14,18 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useMemo } from "react";
|
||||||
import { useLocation, useParams, useHistory } from "react-router-dom";
|
import { useLocation, useParams } from "react-router-dom";
|
||||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
import { useClient } from "../ConferenceCallManagerHooks";
|
||||||
import { useGroupCall } from "matrix-react-sdk/src/hooks/useGroupCall";
|
import { ErrorView, LoadingView } from "../FullScreenView";
|
||||||
import { useClient, useLoadGroupCall } from "../ConferenceCallManagerHooks";
|
import { RoomAuthView } from "./RoomAuthView";
|
||||||
import { ErrorView, LoadingView, FullScreenView } from "../FullScreenView";
|
import { GroupCallLoader } from "./GroupCallLoader";
|
||||||
import * as Sentry from "@sentry/react";
|
import { GroupCallView } from "./GroupCallView";
|
||||||
import { LobbyView } from "./LobbyView";
|
|
||||||
import { InCallView } from "./InCallView";
|
|
||||||
import { CallEndedView } from "./CallEndedView";
|
|
||||||
|
|
||||||
export function RoomPage() {
|
export function RoomPage() {
|
||||||
const [registrationError, setRegistrationError] = useState();
|
|
||||||
const { loading, isAuthenticated, error, client, isPasswordlessUser } =
|
const { loading, isAuthenticated, error, client, isPasswordlessUser } =
|
||||||
useClient();
|
useClient();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!loading && !isAuthenticated) {
|
|
||||||
setRegistrationError(new Error("Must be registered"));
|
|
||||||
}
|
|
||||||
}, [loading, isAuthenticated]);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return <LoadingView />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (registrationError || error) {
|
|
||||||
return <ErrorView error={registrationError || error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <GroupCall client={client} isPasswordlessUser={isPasswordlessUser} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GroupCall({ client, isPasswordlessUser }) {
|
|
||||||
const { roomId: maybeRoomId } = useParams();
|
const { roomId: maybeRoomId } = useParams();
|
||||||
const { hash, search } = useLocation();
|
const { hash, search } = useLocation();
|
||||||
const [simpleGrid, viaServers] = useMemo(() => {
|
const [simpleGrid, viaServers] = useMemo(() => {
|
||||||
|
|
@ -55,155 +33,30 @@ export function GroupCall({ client, isPasswordlessUser }) {
|
||||||
return [params.has("simple"), params.getAll("via")];
|
return [params.has("simple"), params.getAll("via")];
|
||||||
}, [search]);
|
}, [search]);
|
||||||
const roomId = maybeRoomId || hash;
|
const roomId = maybeRoomId || hash;
|
||||||
const { loading, error, groupCall } = useLoadGroupCall(
|
|
||||||
client,
|
|
||||||
roomId,
|
|
||||||
viaServers
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
window.groupCall = groupCall;
|
|
||||||
}, [groupCall]);
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return <LoadingView />;
|
||||||
<FullScreenView>
|
|
||||||
<h1>Loading room...</h1>
|
|
||||||
</FullScreenView>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return <ErrorView error={error} />;
|
return <ErrorView error={error} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
return <RoomAuthView />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupCallView
|
<GroupCallLoader roomId={roomId} viaServers={viaServers}>
|
||||||
isPasswordlessUser={isPasswordlessUser}
|
{(groupCall) => (
|
||||||
client={client}
|
<GroupCallView
|
||||||
roomId={roomId}
|
client={client}
|
||||||
groupCall={groupCall}
|
roomId={roomId}
|
||||||
simpleGrid={simpleGrid}
|
groupCall={groupCall}
|
||||||
/>
|
isPasswordlessUser={isPasswordlessUser}
|
||||||
|
simpleGrid={simpleGrid}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</GroupCallLoader>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GroupCallView({
|
|
||||||
client,
|
|
||||||
isPasswordlessUser,
|
|
||||||
roomId,
|
|
||||||
groupCall,
|
|
||||||
simpleGrid,
|
|
||||||
}) {
|
|
||||||
const [showInspector, setShowInspector] = useState(false);
|
|
||||||
const {
|
|
||||||
state,
|
|
||||||
error,
|
|
||||||
activeSpeaker,
|
|
||||||
userMediaFeeds,
|
|
||||||
microphoneMuted,
|
|
||||||
localVideoMuted,
|
|
||||||
localCallFeed,
|
|
||||||
initLocalCallFeed,
|
|
||||||
enter,
|
|
||||||
leave,
|
|
||||||
toggleLocalVideoMuted,
|
|
||||||
toggleMicrophoneMuted,
|
|
||||||
toggleScreensharing,
|
|
||||||
isScreensharing,
|
|
||||||
localScreenshareFeed,
|
|
||||||
screenshareFeeds,
|
|
||||||
hasLocalParticipant,
|
|
||||||
} = useGroupCall(groupCall);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function onHangup(call) {
|
|
||||||
if (call.hangupReason === "ice_failed") {
|
|
||||||
Sentry.captureException(new Error("Call hangup due to ICE failure."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onError(error) {
|
|
||||||
Sentry.captureException(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groupCall) {
|
|
||||||
groupCall.on("hangup", onHangup);
|
|
||||||
groupCall.on("error", onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (groupCall) {
|
|
||||||
groupCall.removeListener("hangup", onHangup);
|
|
||||||
groupCall.removeListener("error", onError);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [groupCall]);
|
|
||||||
|
|
||||||
const [left, setLeft] = useState(false);
|
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const onLeave = useCallback(() => {
|
|
||||||
leave();
|
|
||||||
|
|
||||||
if (!isPasswordlessUser) {
|
|
||||||
history.push("/");
|
|
||||||
} else {
|
|
||||||
setLeft(true);
|
|
||||||
}
|
|
||||||
}, [leave, history]);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return <ErrorView error={error} />;
|
|
||||||
} else if (state === GroupCallState.Entered) {
|
|
||||||
return (
|
|
||||||
<InCallView
|
|
||||||
groupCall={groupCall}
|
|
||||||
client={client}
|
|
||||||
roomName={groupCall.room.name}
|
|
||||||
microphoneMuted={microphoneMuted}
|
|
||||||
localVideoMuted={localVideoMuted}
|
|
||||||
toggleLocalVideoMuted={toggleLocalVideoMuted}
|
|
||||||
toggleMicrophoneMuted={toggleMicrophoneMuted}
|
|
||||||
userMediaFeeds={userMediaFeeds}
|
|
||||||
activeSpeaker={activeSpeaker}
|
|
||||||
onLeave={onLeave}
|
|
||||||
toggleScreensharing={toggleScreensharing}
|
|
||||||
isScreensharing={isScreensharing}
|
|
||||||
localScreenshareFeed={localScreenshareFeed}
|
|
||||||
screenshareFeeds={screenshareFeeds}
|
|
||||||
simpleGrid={simpleGrid}
|
|
||||||
setShowInspector={setShowInspector}
|
|
||||||
showInspector={showInspector}
|
|
||||||
roomId={roomId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else if (state === GroupCallState.Entering) {
|
|
||||||
return (
|
|
||||||
<FullScreenView>
|
|
||||||
<h1>Entering room...</h1>
|
|
||||||
</FullScreenView>
|
|
||||||
);
|
|
||||||
} else if (left) {
|
|
||||||
return <CallEndedView client={client} />;
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<LobbyView
|
|
||||||
client={client}
|
|
||||||
hasLocalParticipant={hasLocalParticipant}
|
|
||||||
roomName={groupCall.room.name}
|
|
||||||
state={state}
|
|
||||||
onInitLocalCallFeed={initLocalCallFeed}
|
|
||||||
localCallFeed={localCallFeed}
|
|
||||||
onEnter={enter}
|
|
||||||
microphoneMuted={microphoneMuted}
|
|
||||||
localVideoMuted={localVideoMuted}
|
|
||||||
toggleLocalVideoMuted={toggleLocalVideoMuted}
|
|
||||||
toggleMicrophoneMuted={toggleMicrophoneMuted}
|
|
||||||
setShowInspector={setShowInspector}
|
|
||||||
showInspector={showInspector}
|
|
||||||
roomId={roomId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
27
src/room/useSentryGroupCallHandler.js
Normal file
27
src/room/useSentryGroupCallHandler.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import * as Sentry from "@sentry/react";
|
||||||
|
|
||||||
|
export function useSentryGroupCallHandler(groupCall) {
|
||||||
|
useEffect(() => {
|
||||||
|
function onHangup(call) {
|
||||||
|
if (call.hangupReason === "ice_failed") {
|
||||||
|
Sentry.captureException(new Error("Call hangup due to ICE failure."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError(error) {
|
||||||
|
Sentry.captureException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupCall) {
|
||||||
|
groupCall.on("hangup", onHangup);
|
||||||
|
groupCall.on("error", onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (groupCall) {
|
||||||
|
groupCall.removeListener("hangup", onHangup);
|
||||||
|
groupCall.removeListener("error", onError);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [groupCall]);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue