diff --git a/src/App.jsx b/src/App.jsx index 26508b14..6f7b527c 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -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 ; + return ; } - return
Loading...
; + return ; } diff --git a/src/DevTools.jsx b/src/DevTools.jsx deleted file mode 100644 index c51c0818..00000000 --- a/src/DevTools.jsx +++ /dev/null @@ -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 ( - - {shortUserId} - - ); -} - -function CallId({ callId, ...rest }) { - const shortId = callId.substr(callId.length - 16); - const color = colorHash.hex(shortId); - - return ( - - {shortId} - - ); -} - -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
; - } - - return ( - -
-
setActiveTab("users")} - > - Users -
-
setActiveTab("calls")} - > - Calls -
-
-
- {activeTab === "users" && - Array.from(debugState.users.entries()) - .sort(sortEntries) - .map(([userId, props]) => ( - } - {...props} - onSelect={setSelectedEvent} - /> - ))} - {activeTab === "calls" && - Array.from(debugState.calls.entries()) - .sort(sortEntries) - .map(([callId, props]) => ( - } - {...props} - onSelect={setSelectedEvent} - /> - ))} -
- {selectedEvent && ( - setSelectedEvent(null)} - /> - )} -
- ); -} - -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 ( -
-
- {title} - {`(${state})`} -
-
- {events.map((event, idx) => ( - - ))} -
-
- ); -} - -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 ( -
onSelect(event)}> - {showSender && sender && ( - - )} - - {type.replace("me.robertlong.", "x.")} - - {showCallId && call_id && ( - - )} - {invitee && } - {reason && {reason}} - {eventType && {eventType}} - {eventValue && {eventValue}} -
- ); -} - -function EventViewer({ event, onClose }) { - const type = event.getType(); - const sender = event.getSender(); - const { call_id, invitee } = event.getContent(); - const json = event.toJSON(); - - return createPortal( -
-

Event Type: {type}

-

Sender: {sender}

- {call_id && ( -

- Call Id: -

- )} - {invitee && ( -

- Invitee: -

- )} -

Raw Event:

-
{JSON.stringify(json, undefined, 2)}
- -
, - document.body - ); -} diff --git a/src/DevTools.module.css b/src/DevTools.module.css deleted file mode 100644 index 02dd4f47..00000000 --- a/src/DevTools.module.css +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/src/ErrorModal.jsx b/src/ErrorModal.jsx deleted file mode 100644 index ba544453..00000000 --- a/src/ErrorModal.jsx +++ /dev/null @@ -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 ( - <> -
- - - - -
-
-
-

Error

- {error.message} - - Return to home screen - -
-
- - ); -} diff --git a/src/FullScreenView.jsx b/src/FullScreenView.jsx new file mode 100644 index 00000000..2763da38 --- /dev/null +++ b/src/FullScreenView.jsx @@ -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 ( +
+
+ + + + +
+
+
{children}
+
+
+ ); +} + +export function ErrorView({ error }) { + const location = useLocation(); + + useEffect(() => { + console.error(error); + }, [error]); + + return ( + +

Error

+ {error.message} + {location.pathname !== "/" && ( + + Return to home screen + + )} +
+ ); +} + +export function LoadingView() { + return ( + +

Loading...

+
+ ); +} diff --git a/src/ErrorModal.module.css b/src/FullScreenView.module.css similarity index 84% rename from src/ErrorModal.module.css rename to src/FullScreenView.module.css index d33f5518..977945c0 100644 --- a/src/ErrorModal.module.css +++ b/src/FullScreenView.module.css @@ -1,3 +1,11 @@ +.page { + position: relative; + display: flex; + flex-direction: column; + overflow: hidden; + min-height: 100%; +} + .header { padding: 76px 65px; } diff --git a/src/Home.jsx b/src/Home.jsx index a1af7722..e844d92a 100644 --- a/src/Home.jsx +++ b/src/Home.jsx @@ -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
Loading...
; - } else if (error) { - return ; + return ; + } else if (error || createRoomError) { + return ; } else if (!isAuthenticated || isGuest) { return ( - {children} -
- ); -} - -export function Center({ children, className, ...rest }) { - return ( -
- {children} -
- ); -} - -export function Modal({ children, className, ...rest }) { - return ( -
- {children} -
- ); -} - -export function Info({ children, className, ...rest }) { - return ( -

- {children} -

- ); -} diff --git a/src/Layout.module.css b/src/Layout.module.css deleted file mode 100644 index 61e362b4..00000000 --- a/src/Layout.module.css +++ /dev/null @@ -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; -} diff --git a/src/Logo.svg b/src/Logo.svg deleted file mode 100644 index 56c658bf..00000000 --- a/src/Logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Room.jsx b/src/Room.jsx index 4e44b571..c32862c0 100644 --- a/src/Room.jsx +++ b/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
Loading...
; + return ; } if (registrationError || error) { - return ( -
- -
- ); + return ; } return ; @@ -116,16 +111,7 @@ export function GroupCall({ client }) { } if (error) { - return ( -
-
- - - -
- -
- ); + return ; } return ( @@ -185,16 +171,7 @@ export function GroupCallView({ client, roomId, groupCall, simpleGrid }) { }, [groupCall]); if (error) { - return ( -
-
- - - -
- -
- ); + return ; } else if (state === GroupCallState.Entered) { return ( -
-

Loading room...

-
- + +

Loading room...

+
); } export function EnteringRoomView() { return ( -
-
-

Entering room...

-
-
+ +

Entering room...

+
); } diff --git a/src/main.jsx b/src/main.jsx index 48cc6e2c..a6395415 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -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( - An error has occurred

}> +
,