Cleanup error/loading screens
This commit is contained in:
parent
aa988e9f4a
commit
940706bed0
12 changed files with 77 additions and 530 deletions
|
@ -31,7 +31,7 @@ import { Room } from "./Room";
|
|||
import { ClientProvider } from "./ConferenceCallManagerHooks";
|
||||
import { useFocusVisible } from "@react-aria/interactions";
|
||||
import styles from "./App.module.css";
|
||||
import { ErrorModal } from "./ErrorModal";
|
||||
import { ErrorView, LoadingView } from "./FullScreenView";
|
||||
|
||||
const SentryRoute = Sentry.withSentryRouting(Route);
|
||||
|
||||
|
@ -129,8 +129,8 @@ function RoomRedirect() {
|
|||
}, [history, pathname]);
|
||||
|
||||
if (error) {
|
||||
return <ErrorModal error={error} />;
|
||||
return <ErrorView error={error} />;
|
||||
}
|
||||
|
||||
return <div>Loading...</div>;
|
||||
return <LoadingView />;
|
||||
}
|
||||
|
|
245
src/DevTools.jsx
245
src/DevTools.jsx
|
@ -1,245 +0,0 @@
|
|||
/*
|
||||
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, useEffect, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import ColorHash from "color-hash";
|
||||
import classNames from "classnames";
|
||||
import styles from "./DevTools.module.css";
|
||||
import { Resizable } from "re-resizable";
|
||||
|
||||
const colorHash = new ColorHash({ lightness: 0.8 });
|
||||
|
||||
function UserId({ userId, ...rest }) {
|
||||
const shortUserId = userId.split(":")[0];
|
||||
const color = colorHash.hex(shortUserId);
|
||||
return (
|
||||
<span style={{ color }} {...rest}>
|
||||
{shortUserId}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function CallId({ callId, ...rest }) {
|
||||
const shortId = callId.substr(callId.length - 16);
|
||||
const color = colorHash.hex(shortId);
|
||||
|
||||
return (
|
||||
<span style={{ color }} {...rest}>
|
||||
{shortId}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function sortEntries(a, b) {
|
||||
const aInactive = a[1].state === "inactive";
|
||||
const bInactive = b[1].state === "inactive";
|
||||
|
||||
if (aInactive && !bInactive) {
|
||||
return 1;
|
||||
} else if (bInactive && !aInactive) {
|
||||
return -1;
|
||||
} else {
|
||||
return a[0] < b[0] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
export function DevTools({ callDebugger }) {
|
||||
const [debugState, setDebugState] = useState(callDebugger.debugState);
|
||||
const [selectedEvent, setSelectedEvent] = useState();
|
||||
const [activeTab, setActiveTab] = useState("users");
|
||||
|
||||
useEffect(() => {
|
||||
function onRoomDebug() {
|
||||
setDebugState({ ...callDebugger.debugState });
|
||||
}
|
||||
|
||||
callDebugger.on("debug", onRoomDebug);
|
||||
|
||||
return () => {
|
||||
callDebugger.removeListener("debug", onRoomDebug);
|
||||
};
|
||||
}, [callDebugger]);
|
||||
|
||||
if (!callDebugger.groupCall.entered) {
|
||||
return <div className={styles.devTools} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Resizable
|
||||
enable={{
|
||||
top: true,
|
||||
right: false,
|
||||
bottom: false,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight: false,
|
||||
bottomLeft: false,
|
||||
topLeft: false,
|
||||
}}
|
||||
className={styles.devTools}
|
||||
>
|
||||
<div className={styles.toolbar}>
|
||||
<div
|
||||
className={classNames(styles.tab, {
|
||||
[styles.activeTab]: activeTab === "users",
|
||||
})}
|
||||
onClick={() => setActiveTab("users")}
|
||||
>
|
||||
Users
|
||||
</div>
|
||||
<div
|
||||
className={classNames(styles.tab, {
|
||||
[styles.activeTab]: activeTab === "calls",
|
||||
})}
|
||||
onClick={() => setActiveTab("calls")}
|
||||
>
|
||||
Calls
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.devToolsContainer}>
|
||||
{activeTab === "users" &&
|
||||
Array.from(debugState.users.entries())
|
||||
.sort(sortEntries)
|
||||
.map(([userId, props]) => (
|
||||
<EventContainer
|
||||
key={userId}
|
||||
showCallId
|
||||
title={<UserId userId={userId} />}
|
||||
{...props}
|
||||
onSelect={setSelectedEvent}
|
||||
/>
|
||||
))}
|
||||
{activeTab === "calls" &&
|
||||
Array.from(debugState.calls.entries())
|
||||
.sort(sortEntries)
|
||||
.map(([callId, props]) => (
|
||||
<EventContainer
|
||||
key={callId}
|
||||
showSender
|
||||
title={<CallId callId={callId} />}
|
||||
{...props}
|
||||
onSelect={setSelectedEvent}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{selectedEvent && (
|
||||
<EventViewer
|
||||
event={selectedEvent}
|
||||
onClose={() => setSelectedEvent(null)}
|
||||
/>
|
||||
)}
|
||||
</Resizable>
|
||||
);
|
||||
}
|
||||
|
||||
function EventContainer({ title, state, events, ...rest }) {
|
||||
const eventsRef = useRef();
|
||||
const [autoScroll, setAutoScroll] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoScroll) {
|
||||
const el = eventsRef.current;
|
||||
el.scrollTop = el.scrollHeight - el.clientHeight;
|
||||
}
|
||||
});
|
||||
|
||||
const onScroll = useCallback(() => {
|
||||
const el = eventsRef.current;
|
||||
|
||||
if (el.scrollHeight - el.scrollTop === el.clientHeight) {
|
||||
setAutoScroll(true);
|
||||
} else {
|
||||
setAutoScroll(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.user}>
|
||||
<div className={styles.userId}>
|
||||
<span>{title}</span>
|
||||
<span>{`(${state})`}</span>
|
||||
</div>
|
||||
<div ref={eventsRef} className={styles.events} onScroll={onScroll}>
|
||||
{events.map((event, idx) => (
|
||||
<EventItem key={idx} event={event} {...rest} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function EventItem({ event, showCallId, showSender, onSelect }) {
|
||||
const type = event.getType();
|
||||
const sender = event.getSender();
|
||||
const { call_id, invitee, reason, eventType, ...rest } = event.getContent();
|
||||
|
||||
let eventValue;
|
||||
|
||||
if (eventType === "icegatheringstatechange") {
|
||||
eventValue = rest.iceGatheringState;
|
||||
} else if (eventType === "iceconnectionstatechange") {
|
||||
eventValue = rest.iceConnectionState;
|
||||
} else if (eventType === "signalingstatechange") {
|
||||
eventValue = rest.signalingState;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.event} onClick={() => onSelect(event)}>
|
||||
{showSender && sender && (
|
||||
<UserId className={styles.eventDetails} userId={sender} />
|
||||
)}
|
||||
<span className={styles.eventType}>
|
||||
{type.replace("me.robertlong.", "x.")}
|
||||
</span>
|
||||
{showCallId && call_id && (
|
||||
<CallId className={styles.eventDetails} callId={call_id} />
|
||||
)}
|
||||
{invitee && <UserId className={styles.eventDetails} userId={invitee} />}
|
||||
{reason && <span className={styles.eventDetails}>{reason}</span>}
|
||||
{eventType && <span className={styles.eventDetails}>{eventType}</span>}
|
||||
{eventValue && <span className={styles.eventDetails}>{eventValue}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function EventViewer({ event, onClose }) {
|
||||
const type = event.getType();
|
||||
const sender = event.getSender();
|
||||
const { call_id, invitee } = event.getContent();
|
||||
const json = event.toJSON();
|
||||
|
||||
return createPortal(
|
||||
<div className={styles.eventViewer}>
|
||||
<p>Event Type: {type}</p>
|
||||
<p>Sender: {sender}</p>
|
||||
{call_id && (
|
||||
<p>
|
||||
Call Id: <CallId callId={call_id} />
|
||||
</p>
|
||||
)}
|
||||
{invitee && (
|
||||
<p>
|
||||
Invitee: <UserId userId={invitee} />
|
||||
</p>
|
||||
)}
|
||||
<p>Raw Event:</p>
|
||||
<pre className={styles.content}>{JSON.stringify(json, undefined, 2)}</pre>
|
||||
<button onClick={onClose}>Close</button>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
.devTools {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 2px solid #111;
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.tab {
|
||||
vertical-align: middle;
|
||||
padding: 4px 8px;
|
||||
background-color: #444;
|
||||
margin: 0 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.activeTab {
|
||||
background-color: #666;
|
||||
}
|
||||
|
||||
.devToolsContainer {
|
||||
display: flex;
|
||||
height: 250px;
|
||||
gap: 2px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
background-color: #555;
|
||||
min-width: 512px;
|
||||
}
|
||||
|
||||
.userId {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.userId > * {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.userId > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.events {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.event {
|
||||
display: flex;
|
||||
font-family: monospace;
|
||||
padding: 4px 12px;
|
||||
background-color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.event:nth-child(even) {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.event:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.event > * {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.event > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.eventType, .eventDetails {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.eventType {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.eventDetails {
|
||||
font-weight: 200;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.eventViewer {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 320px;
|
||||
max-width: 80%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid black;
|
||||
background-color: #222;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.eventViewer .content {
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { ErrorMessage } from "./Input";
|
||||
import styles from "./ErrorModal.module.css";
|
||||
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
|
||||
|
||||
export function ErrorModal({ error }) {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
console.error(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header>
|
||||
<LeftNav>
|
||||
<HeaderLogo />
|
||||
</LeftNav>
|
||||
<RightNav />
|
||||
</Header>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<h1>Error</h1>
|
||||
<ErrorMessage>{error.message}</ErrorMessage>
|
||||
<Link className={styles.homeLink} to="/">
|
||||
Return to home screen
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
49
src/FullScreenView.jsx
Normal file
49
src/FullScreenView.jsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { ErrorMessage } from "./Input";
|
||||
import styles from "./FullScreenView.module.css";
|
||||
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
|
||||
|
||||
export function FullScreenView({ children }) {
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<Header>
|
||||
<LeftNav>
|
||||
<HeaderLogo />
|
||||
</LeftNav>
|
||||
<RightNav />
|
||||
</Header>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ErrorView({ error }) {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
console.error(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<FullScreenView>
|
||||
<h1>Error</h1>
|
||||
<ErrorMessage>{error.message}</ErrorMessage>
|
||||
{location.pathname !== "/" && (
|
||||
<Link className={styles.homeLink} to="/">
|
||||
Return to home screen
|
||||
</Link>
|
||||
)}
|
||||
</FullScreenView>
|
||||
);
|
||||
}
|
||||
|
||||
export function LoadingView() {
|
||||
return (
|
||||
<FullScreenView>
|
||||
<h1>Loading...</h1>
|
||||
</FullScreenView>
|
||||
);
|
||||
}
|
|
@ -1,3 +1,11 @@
|
|||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 76px 65px;
|
||||
}
|
|
@ -29,7 +29,7 @@ import { UserMenu } from "./UserMenu";
|
|||
import { Button } from "./button";
|
||||
import { CallList } from "./CallList";
|
||||
import classNames from "classnames";
|
||||
import { ErrorModal } from "./ErrorModal";
|
||||
import { ErrorView, LoadingView } from "./FullScreenView";
|
||||
|
||||
export function Home() {
|
||||
const { isAuthenticated, isGuest, loading, error, client } = useClient();
|
||||
|
@ -64,9 +64,9 @@ export function Home() {
|
|||
);
|
||||
|
||||
if (loading) {
|
||||
return <div>Loading...</div>;
|
||||
} else if (error) {
|
||||
return <ErrorModal error={error} />;
|
||||
return <LoadingView />;
|
||||
} else if (error || createRoomError) {
|
||||
return <ErrorView error={error || createRoomError} />;
|
||||
} else if (!isAuthenticated || isGuest) {
|
||||
return (
|
||||
<UnregisteredView
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
import styles from "./Layout.module.css";
|
||||
|
||||
export function Content({ children, className, ...rest }) {
|
||||
return (
|
||||
<div className={classNames(styles.content, className)} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Center({ children, className, ...rest }) {
|
||||
return (
|
||||
<div className={classNames(styles.center, className)} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Modal({ children, className, ...rest }) {
|
||||
return (
|
||||
<div className={classNames(styles.modal, className)} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Info({ children, className, ...rest }) {
|
||||
return (
|
||||
<p className={classNames(styles.info, className)} {...rest}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 20px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal {
|
||||
color: var(--textColor1);
|
||||
border-radius: 8px;
|
||||
padding: 25px 60px;
|
||||
max-width: 400px;
|
||||
background-color: var(--bgColor2);
|
||||
flex: 1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.modal h2 {
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 60C46.5686 60 60 46.5686 60 30C60 13.4315 46.5686 0 30 0C13.4315 0 0 13.4315 0 30C0 46.5686 13.4315 60 30 60Z" fill="#0DBD8B"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5148 13.9784C24.5148 12.7674 25.4985 11.7858 26.712 11.7858C34.9366 11.7858 41.6039 18.4393 41.6039 26.6468C41.6039 27.8577 40.6202 28.8394 39.4067 28.8394C38.1932 28.8394 37.2095 27.8577 37.2095 26.6468C37.2095 20.8612 32.5096 16.171 26.712 16.171C25.4985 16.171 24.5148 15.1893 24.5148 13.9784Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.017 24.4541C47.2304 24.4541 48.2142 25.4358 48.2142 26.6467C48.2142 34.8542 41.5468 41.5077 33.3223 41.5077C32.1088 41.5077 31.1251 40.5261 31.1251 39.3151C31.1251 38.1042 32.1088 37.1225 33.3223 37.1225C39.1199 37.1225 43.8198 32.4323 43.8198 26.6467C43.8198 25.4358 44.8035 24.4541 46.017 24.4541Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.5193 46.0216C35.5193 47.2326 34.5355 48.2142 33.3221 48.2142C25.0975 48.2142 18.4302 41.5607 18.4302 33.3532C18.4302 32.1423 19.4139 31.1606 20.6274 31.1606C21.8408 31.1606 22.8245 32.1423 22.8245 33.3532C22.8245 39.1388 27.5244 43.829 33.3221 43.829C34.5355 43.829 35.5193 44.8107 35.5193 46.0216Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.9825 35.5459C12.7691 35.5459 11.7854 34.5642 11.7854 33.3533C11.7854 25.1458 18.4527 18.4923 26.6773 18.4923C27.8907 18.4923 28.8744 19.4739 28.8744 20.6849C28.8744 21.8958 27.8907 22.8775 26.6773 22.8775C20.8796 22.8775 16.1797 27.5677 16.1797 33.3533C16.1797 34.5642 15.196 35.5459 13.9825 35.5459Z" fill="white"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
49
src/Room.jsx
49
src/Room.jsx
|
@ -31,7 +31,6 @@ import {
|
|||
RightNav,
|
||||
RoomHeaderInfo,
|
||||
RoomSetupHeaderInfo,
|
||||
HeaderLogo,
|
||||
} from "./Header";
|
||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import VideoGrid, {
|
||||
|
@ -43,7 +42,7 @@ import { useGroupCall } from "matrix-react-sdk/src/hooks/useGroupCall";
|
|||
import { useCallFeed } from "matrix-react-sdk/src/hooks/useCallFeed";
|
||||
import { useMediaStream } from "matrix-react-sdk/src/hooks/useMediaStream";
|
||||
import { useClient, useLoadGroupCall } from "./ConferenceCallManagerHooks";
|
||||
import { ErrorModal } from "./ErrorModal";
|
||||
import { ErrorView, LoadingView, FullScreenView } from "./FullScreenView";
|
||||
import { GroupCallInspector } from "./GroupCallInspector";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { OverflowMenu } from "./OverflowMenu";
|
||||
|
@ -79,15 +78,11 @@ export function Room() {
|
|||
}, [loading, isAuthenticated]);
|
||||
|
||||
if (loading || registeringGuest) {
|
||||
return <div>Loading...</div>;
|
||||
return <LoadingView />;
|
||||
}
|
||||
|
||||
if (registrationError || error) {
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
<ErrorModal error={registrationError || error} />
|
||||
</div>
|
||||
);
|
||||
return <ErrorView error={registrationError || error} />;
|
||||
}
|
||||
|
||||
return <GroupCall client={client} />;
|
||||
|
@ -116,16 +111,7 @@ export function GroupCall({ client }) {
|
|||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
<Header>
|
||||
<LeftNav>
|
||||
<HeaderLogo />
|
||||
</LeftNav>
|
||||
</Header>
|
||||
<ErrorModal error={error} />
|
||||
</div>
|
||||
);
|
||||
return <ErrorView error={error} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -185,16 +171,7 @@ export function GroupCallView({ client, roomId, groupCall, simpleGrid }) {
|
|||
}, [groupCall]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
<Header>
|
||||
<LeftNav>
|
||||
<HeaderLogo />
|
||||
</LeftNav>
|
||||
</Header>
|
||||
<ErrorModal error={error} />
|
||||
</div>
|
||||
);
|
||||
return <ErrorView error={error} />;
|
||||
} else if (state === GroupCallState.Entered) {
|
||||
return (
|
||||
<InRoomView
|
||||
|
@ -244,21 +221,17 @@ export function GroupCallView({ client, roomId, groupCall, simpleGrid }) {
|
|||
|
||||
export function LoadingRoomView() {
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Loading room...</p>
|
||||
</div>
|
||||
</div>
|
||||
<FullScreenView>
|
||||
<h1>Loading room...</h1>
|
||||
</FullScreenView>
|
||||
);
|
||||
}
|
||||
|
||||
export function EnteringRoomView() {
|
||||
return (
|
||||
<div className={styles.room}>
|
||||
<div className={styles.centerMessage}>
|
||||
<p>Entering room...</p>
|
||||
</div>
|
||||
</div>
|
||||
<FullScreenView>
|
||||
<h1>Entering room...</h1>
|
||||
</FullScreenView>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import "./index.css";
|
|||
import App from "./App";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { Integrations } from "@sentry/tracing";
|
||||
import { ErrorView } from "./FullScreenView";
|
||||
|
||||
if (import.meta.env.VITE_CUSTOM_THEME) {
|
||||
const style = document.documentElement.style;
|
||||
|
@ -56,7 +57,7 @@ Sentry.init({
|
|||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<Sentry.ErrorBoundary fallback={<p>An error has occurred</p>}>
|
||||
<Sentry.ErrorBoundary fallback={ErrorView}>
|
||||
<App history={history} />
|
||||
</Sentry.ErrorBoundary>
|
||||
</React.StrictMode>,
|
||||
|
|
Loading…
Reference in a new issue