diff --git a/src/App.jsx b/src/App.jsx index 026d24c..02d3f88 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -15,86 +15,42 @@ limitations under the License. */ import React from "react"; -import { - BrowserRouter as Router, - Switch, - Route, - Redirect, - useLocation, -} from "react-router-dom"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import * as Sentry from "@sentry/react"; -import { useClient } from "./ConferenceCallManagerHooks"; -import { Home } from "./Home"; -import { Room } from "./Room"; -import { RegisterPage } from "./RegisterPage"; -import { LoginPage } from "./LoginPage"; -import { Center } from "./Layout"; -import { GuestAuthPage } from "./GuestAuthPage"; import { OverlayProvider } from "@react-aria/overlays"; +import { Home } from "./Home"; +import { LoginPage } from "./LoginPage"; +import { RegisterPage } from "./RegisterPage"; +import { Room } from "./Room"; +import { ClientProvider } from "./ConferenceCallManagerHooks"; const SentryRoute = Sentry.withSentryRouting(Route); -export default function App() { - const { protocol, host } = window.location; - // Assume homeserver is hosted on same domain (proxied in development by vite) - const homeserverUrl = `${protocol}//${host}`; - const { - loading, - authenticated, - client, - login, - logout, - registerGuest, - register, - } = useClient(homeserverUrl); +const { protocol, host } = window.location; +// Assume homeserver is hosted on same domain (proxied in development by vite) +const homeserverUrl = `${protocol}//${host}`; +export default function App() { return ( - - {loading ? ( -
-

Loading...

-
- ) : ( + + - - - + + + - + - + - {authenticated ? ( - - ) : ( - - )} + - )} - +
+
); } - -function AuthenticatedRoute({ authenticated, children, ...rest }) { - const location = useLocation(); - - return ( - - {authenticated ? ( - children - ) : ( - - )} - - ); -} diff --git a/src/CallTile.jsx b/src/CallList.jsx similarity index 59% rename from src/CallTile.jsx rename to src/CallList.jsx index 94b7e42..5339198 100644 --- a/src/CallTile.jsx +++ b/src/CallList.jsx @@ -4,9 +4,28 @@ import { CopyButton } from "./button"; import { Facepile } from "./Facepile"; import { Avatar } from "./Avatar"; import { ReactComponent as VideoIcon } from "./icons/Video.svg"; -import styles from "./CallTile.module.css"; +import styles from "./CallList.module.css"; -export function CallTile({ name, avatarUrl, roomUrl, participants }) { +export function CallList({ title, rooms }) { + return ( + <> +

{title}

+
+ {rooms.map(({ roomId, roomName, roomUrl, avatarUrl, participants }) => ( + + ))} +
+ + ); +} + +function CallTile({ name, avatarUrl, roomUrl, participants }) { return ( { @@ -86,12 +101,16 @@ export async function fetchGroupCall( }); } -export function useClient(homeserverUrl) { - const [{ loading, authenticated, client }, setState] = useState({ - loading: true, - authenticated: false, - client: undefined, - }); +export function ClientProvider({ homeserverUrl, children }) { + const history = useHistory(); + const [{ loading, isAuthenticated, isGuest, client, userName }, setState] = + useState({ + loading: true, + isAuthenticated: false, + isGuest: false, + client: undefined, + userName: null, + }); useEffect(() => { async function restore() { @@ -117,8 +136,10 @@ export function useClient(homeserverUrl) { JSON.stringify({ user_id, device_id, access_token, guest }) ); - return client; + return { client, guest }; } + + return { client: undefined, guest: false }; } catch (err) { localStorage.removeItem("matrix-auth-store"); throw err; @@ -126,15 +147,23 @@ export function useClient(homeserverUrl) { } restore() - .then((client) => { - if (client) { - setState({ client, loading: false, authenticated: true }); - } else { - setState({ client: undefined, loading: false, authenticated: false }); - } + .then(({ client, guest }) => { + setState({ + client, + loading: false, + isAuthenticated: !!client, + isGuest: guest, + userName: client?.getUserIdLocalpart(), + }); }) .catch(() => { - setState({ client: undefined, loading: false, authenticated: false }); + setState({ + client: undefined, + loading: false, + isAuthenticated: false, + isGuest: false, + userName: null, + }); }); }, []); @@ -176,10 +205,22 @@ export function useClient(homeserverUrl) { JSON.stringify({ user_id, device_id, access_token }) ); - setState({ client, loading: false, authenticated: true }); + setState({ + client, + loading: false, + isAuthenticated: true, + isGuest: false, + userName: client.getUserIdLocalpart(), + }); } catch (err) { localStorage.removeItem("matrix-auth-store"); - setState({ client: undefined, loading: false, authenticated: false }); + setState({ + client: undefined, + loading: false, + isAuthenticated: false, + isGuest: false, + userName: null, + }); throw err; } }, []); @@ -210,10 +251,22 @@ export function useClient(homeserverUrl) { JSON.stringify({ user_id, device_id, access_token, guest: true }) ); - setState({ client, loading: false, authenticated: true }); + setState({ + client, + loading: false, + isAuthenticated: true, + isGuest: true, + userName: client.getUserIdLocalpart(), + }); } catch (err) { localStorage.removeItem("matrix-auth-store"); - setState({ client: undefined, loading: false, authenticated: false }); + setState({ + client: undefined, + loading: false, + isAuthenticated: false, + isGuest: false, + userName: null, + }); throw err; } }, []); @@ -239,10 +292,25 @@ export function useClient(homeserverUrl) { JSON.stringify({ user_id, device_id, access_token }) ); - setState({ client, loading: false, authenticated: true }); + setState({ + client, + loading: false, + isGuest: false, + isAuthenticated: true, + isGuest: false, + userName: client.getUserIdLocalpart(), + }); + + return client; } catch (err) { localStorage.removeItem("matrix-auth-store"); - setState({ client: undefined, loading: false, authenticated: false }); + setState({ + client: undefined, + loading: false, + isGuest: false, + isAuthenticated: false, + userName: null, + }); throw err; } }, []); @@ -252,17 +320,164 @@ export function useClient(homeserverUrl) { window.location = "/"; }, [history]); + const context = useMemo( + () => ({ + loading, + isAuthenticated, + isGuest, + client, + login, + registerGuest, + register, + logout, + userName, + }), + [ + loading, + isAuthenticated, + isGuest, + client, + login, + registerGuest, + register, + logout, + userName, + ] + ); + + return ( + {children} + ); +} + +export function useClient() { + return useContext(ClientContext); +} + +function roomAliasFromRoomName(roomName) { + return roomName + .trim() + .replace(/\s/g, "-") + .replace(/[^\w-]/g, "") + .toLowerCase(); +} + +export async function createRoom(client, name) { + const { room_id, room_alias } = await client.createRoom({ + visibility: "private", + preset: "public_chat", + name, + room_alias_name: roomAliasFromRoomName(name), + power_level_content_override: { + invite: 100, + kick: 100, + ban: 100, + redact: 50, + state_default: 0, + events_default: 0, + users_default: 0, + events: { + "m.room.power_levels": 100, + "m.room.history_visibility": 100, + "m.room.tombstone": 100, + "m.room.encryption": 100, + "m.room.name": 50, + "m.room.message": 0, + "m.room.encrypted": 50, + "m.sticker": 50, + "org.matrix.msc3401.call.member": 0, + }, + users: { + [client.getUserId()]: 100, + }, + }, + }); + + await client.setGuestAccess(room_id, { + allowJoin: true, + allowRead: true, + }); + + await client.createGroupCall( + room_id, + GroupCallType.Video, + GroupCallIntent.Prompt + ); + + return room_alias || room_id; +} + +export function useCreateRoom(client) { + const [creatingRoom, setCreatingRoom] = useState(false); + const [createRoomError, setCreateRoomError] = useState(); + + const onCreateRoom = useCallback( + (roomName) => { + setCreateRoomError(undefined); + setCreatingRoom(true); + + return createRoom(client, roomName).catch((error) => { + setCreateRoomError(error); + setCreatingRoom(false); + }); + }, + [client] + ); + return { - loading, - authenticated, - client, - login, - registerGuest, - register, - logout, + creatingRoom, + createRoomError, + createRoom: onCreateRoom, }; } +export function useCreateRoomAsPasswordlessUser() { + const { register } = useClient(); + const [creatingRoom, setCreatingRoom] = useState(false); + const [createRoomError, setCreateRoomError] = useState(); + + const onCreateRoom = useCallback( + (roomName, userName) => { + async function onCreateRoom(roomName, userName) { + const client = await register(userName, randomString(16)); + return await createRoom(client, roomName); + } + + setCreateRoomError(undefined); + setCreatingRoom(true); + + return onCreateRoom(roomName, userName).catch((error) => { + setCreateRoomError(error); + setCreatingRoom(false); + }); + }, + [register] + ); + + return { + creatingRoom, + createRoomError, + createRoom: onCreateRoom, + }; +} + +export function useLoadGroupCall(client, roomId, viaServers) { + const [state, setState] = useState({ + loading: true, + error: undefined, + groupCall: undefined, + }); + + useEffect(() => { + setState({ loading: true }); + fetchGroupCall(client, roomId, viaServers, 30000) + .then((groupCall) => setState({ loading: false, groupCall })) + .catch((error) => setState({ loading: false, error })); + }, [client, roomId]); + + return state; +} + const tsCache = {}; function getLastTs(client, r) { @@ -324,6 +539,10 @@ export function useGroupCallRooms(client) { const groupCall = client.getGroupCallForRoom(room.roomId); return { + roomId: room.roomId, + roomName: room.name, + avatarUrl: null, + roomUrl: `/room/${room.getCanonicalAlias() || room.roomId}`, room, groupCall, participants: [...groupCall.participants], @@ -352,9 +571,16 @@ export function usePublicRooms(client, publicSpaceRoomId, maxRooms = 50) { useEffect(() => { if (publicSpaceRoomId) { client.getRoomHierarchy(publicSpaceRoomId, maxRooms).then(({ rooms }) => { - const filteredRooms = rooms.filter( - (room) => room.room_type !== "m.space" - ); + const filteredRooms = rooms + .filter((room) => room.room_type !== "m.space") + .map((room) => ({ + roomId: room.room_id, + roomName: room.name, + avatarUrl: null, + room, + roomUrl: `/room/${room.room_id}`, + participants: [], + })); setRooms(filteredRooms); }); diff --git a/src/GuestAuthPage.jsx b/src/GuestAuthPage.jsx deleted file mode 100644 index 4011ba2..0000000 --- a/src/GuestAuthPage.jsx +++ /dev/null @@ -1,49 +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, { useState, useEffect } from "react"; -import styles from "./GuestAuthPage.module.css"; -import { useLocation, useHistory } from "react-router-dom"; -import { Header, LeftNav, HeaderLogo } from "./Header"; -import { Center, Content, Modal } from "./Layout"; -import { ErrorModal } from "./ErrorModal"; - -export function GuestAuthPage({ onLoginAsGuest }) { - const history = useHistory(); - const location = useLocation(); - const [error, setError] = useState(); - - useEffect(() => { - onLoginAsGuest("Guest " + Math.round(Math.random() * 999)).catch(setError); - }, [onLoginAsGuest, location, history]); - - return ( -
-
- - - -
- -
- - {error ? :
Loading...
} -
-
-
-
- ); -} diff --git a/src/GuestAuthPage.module.css b/src/GuestAuthPage.module.css deleted file mode 100644 index 9da730f..0000000 --- a/src/GuestAuthPage.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.guestAuthPage { - position: relative; - display: flex; - flex-direction: column; - width: 100vw; - height: 100vh; - overflow: hidden; -} \ No newline at end of file diff --git a/src/Home.jsx b/src/Home.jsx index 282d634..8d57a59 100644 --- a/src/Home.jsx +++ b/src/Home.jsx @@ -14,110 +14,57 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useCallback, useState } from "react"; +import React, { useCallback } from "react"; import { useHistory } from "react-router-dom"; import { + useClient, useGroupCallRooms, usePublicRooms, + useCreateRoom, + useCreateRoomAsPasswordlessUser, } from "./ConferenceCallManagerHooks"; import { Header, HeaderLogo, LeftNav, RightNav } from "./Header"; import styles from "./Home.module.css"; import { FieldRow, InputField, ErrorMessage } from "./Input"; -import { - GroupCallIntent, - GroupCallType, -} from "matrix-js-sdk/src/browser-index"; import { UserMenu } from "./UserMenu"; import { Button } from "./button"; -import { CallTile } from "./CallTile"; +import { CallList } from "./CallList"; +import classNames from "classnames"; +import { ErrorModal } from "./ErrorModal"; -function roomAliasFromRoomName(roomName) { - return roomName - .trim() - .replace(/\s/g, "-") - .replace(/[^\w-]/g, "") - .toLowerCase(); +export function Home() { + const { isAuthenticated, isGuest, loading, error, client } = useClient(); + + if (loading) { + return
Loading...
; + } else if (error) { + return ; + } else if (!isAuthenticated || isGuest) { + return ; + } else { + return ; + } } -export function Home({ client, onLogout }) { +function UnregisteredView() { const history = useHistory(); - const [roomName, setRoomName] = useState(""); - const [guestAccess, setGuestAccess] = useState(false); - const [createRoomError, setCreateRoomError] = useState(); - const rooms = useGroupCallRooms(client); - const publicRooms = usePublicRooms( - client, - import.meta.env.VITE_PUBLIC_SPACE_ROOM_ID - ); + const { createRoomError, creatingRoom, createRoom } = + useCreateRoomAsPasswordlessUser(); const onCreateRoom = useCallback( (e) => { e.preventDefault(); - setCreateRoomError(undefined); - - async function createRoom(name, roomAlias, guestAccess) { - const { room_id, room_alias } = await client.createRoom({ - visibility: "private", - preset: "public_chat", - name, - room_alias_name: roomAlias, - power_level_content_override: { - invite: 100, - kick: 100, - ban: 100, - redact: 50, - state_default: 0, - events_default: 0, - users_default: 0, - events: { - "m.room.power_levels": 100, - "m.room.history_visibility": 100, - "m.room.tombstone": 100, - "m.room.encryption": 100, - "m.room.name": 50, - "m.room.message": 0, - "m.room.encrypted": 50, - "m.sticker": 50, - "org.matrix.msc3401.call.member": 0, - }, - users: { - [client.getUserId()]: 100, - }, - }, - }); - - if (guestAccess) { - await client.setGuestAccess(room_id, { - allowJoin: true, - allowRead: true, - }); - } - - await client.createGroupCall( - room_id, - GroupCallType.Video, - GroupCallIntent.Prompt - ); - - history.push(`/room/${room_alias || room_id}`); - } - const data = new FormData(e.target); const roomName = data.get("roomName"); - const guestAccess = data.get("guestAccess"); + const userName = data.get("userName"); - createRoom(roomName, roomAliasFromRoomName(roomName), guestAccess).catch( - (error) => { - setCreateRoomError(error); - setShowAdvanced(true); - } - ); + createRoom(roomName, userName).then((roomIdOrAlias) => { + history.push(`/room/${roomIdOrAlias}`); + }); }, - [client] + [history] ); - const [roomId, setRoomId] = useState(""); - const onJoinRoom = useCallback( (e) => { e.preventDefault(); @@ -129,12 +76,134 @@ export function Home({ client, onLogout }) { ); return ( -
-
+
+
+ + + +
+
+
+
+

Join a call

+ + + + + + +
+
+
+

Create a call

+ + + + + + + {createRoomError && ( + + {createRoomError.message} + + )} + + + +
+
+
+
+
+ ); +} + +function RegisteredView({ client }) { + const history = useHistory(); + const { createRoomError, creatingRoom, createRoom } = useCreateRoom(client); + + const onCreateRoom = useCallback( + (e) => { + e.preventDefault(); + const data = new FormData(e.target); + const roomName = data.get("roomName"); + + createRoom(roomName).then((roomIdOrAlias) => { + history.push(`/room/${roomIdOrAlias}`); + }); + }, + [history] + ); + + const onJoinRoom = useCallback( + (e) => { + e.preventDefault(); + const data = new FormData(e.target); + const roomId = data.get("roomId"); + history.push(`/room/${roomId}`); + }, + [history] + ); + const publicRooms = usePublicRooms( + client, + import.meta.env.VITE_PUBLIC_SPACE_ROOM_ID + ); + const recentRooms = useGroupCallRooms(client); + + const hideCallList = publicRooms.length === 0 && recentRooms.length === 0; + + return ( +
+
+
+ + + + {hideCallList && ( + + + + )}
@@ -149,8 +218,6 @@ export function Home({ client, onLogout }) { required autoComplete="off" placeholder="Call ID" - value={roomId} - onChange={(e) => setRoomId(e.target.value)} /> @@ -171,18 +238,6 @@ export function Home({ client, onLogout }) { required autoComplete="off" placeholder="Room Name" - value={roomName} - onChange={(e) => setRoomName(e.target.value)} - /> - - - setGuestAccess(e.target.checked)} /> {createRoomError && ( @@ -191,55 +246,36 @@ export function Home({ client, onLogout }) { )} -
-
-
- - - - -
-
- {publicRooms.length > 0 && ( - <> -

Public Calls

-
- {publicRooms.map((room) => ( - - ))} -
- - )} -

Recent Calls

-
- {rooms.map(({ room, participants }) => ( - - ))} + {!hideCallList && ( +
+
+ + + + +
+
+ {publicRooms.length > 0 && ( + + )} + {recentRooms.length > 0 && ( + + )}
-
+ )}
); } diff --git a/src/Home.module.css b/src/Home.module.css index 182cf73..b9f79f4 100644 --- a/src/Home.module.css +++ b/src/Home.module.css @@ -15,6 +15,11 @@ background-color: var(--bgColor2); } +.fullWidth { + background-color: var(--bgColor1); + overflow-y: auto; +} + .centered { display: flex; flex-direction: column; @@ -65,6 +70,10 @@ top: -12px; } +.fullWidth .content hr:after { + background-color: var(--bgColor1); +} + .left .content form { display: flex; flex-direction: column; @@ -99,11 +108,3 @@ .right .content h3:first-child { margin-top: 0; } - -.roomList { - display: flex; - flex-wrap: wrap; - justify-content: flex-start; - gap: 24px; - flex: 1; -} diff --git a/src/LoginPage.jsx b/src/LoginPage.jsx index cf3bc7b..6c92c18 100644 --- a/src/LoginPage.jsx +++ b/src/LoginPage.jsx @@ -20,8 +20,10 @@ import { Header, HeaderLogo, LeftNav } from "./Header"; import { FieldRow, InputField, ErrorMessage } from "./Input"; import { Center, Content, Info, Modal } from "./Layout"; import { Button } from "./button"; +import { useClient } from "./ConferenceCallManagerHooks"; -export function LoginPage({ onLogin }) { +export function LoginPage() { + const { login } = useClient(); const [homeserver, setHomeServer] = useState( `${window.location.protocol}//${window.location.host}` ); @@ -32,17 +34,19 @@ export function LoginPage({ onLogin }) { const [loading, setLoading] = useState(false); const [error, setError] = useState(); + // TODO: Handle hitting login page with authenticated client + const onSubmitLoginForm = useCallback( (e) => { e.preventDefault(); setLoading(true); - onLogin(homeserver, usernameRef.current.value, passwordRef.current.value) + login(homeserver, usernameRef.current.value, passwordRef.current.value) .then(() => { if (location.state && location.state.from) { - history.replace(location.state.from); + history.push(location.state.from); } else { - history.replace("/"); + history.push("/"); } }) .catch((error) => { @@ -50,7 +54,7 @@ export function LoginPage({ onLogin }) { setLoading(false); }); }, - [onLogin, location, history, homeserver] + [login, location, history, homeserver] ); return ( diff --git a/src/RegisterPage.jsx b/src/RegisterPage.jsx index 2b21afe..434df33 100644 --- a/src/RegisterPage.jsx +++ b/src/RegisterPage.jsx @@ -20,8 +20,11 @@ import { Header, LeftNav, HeaderLogo } from "./Header"; import { FieldRow, InputField, ErrorMessage } from "./Input"; import { Center, Content, Info, Modal } from "./Layout"; import { Button } from "./button"; +import { useClient } from "./ConferenceCallManagerHooks"; -export function RegisterPage({ onRegister }) { +export function RegisterPage() { + // TODO: Handle hitting login page with authenticated client + const { register } = useClient(); const registerUsernameRef = useRef(); const registerPasswordRef = useRef(); const history = useHistory(); @@ -33,15 +36,15 @@ export function RegisterPage({ onRegister }) { (e) => { e.preventDefault(); setLoading(true); - onRegister( + register( registerUsernameRef.current.value, registerPasswordRef.current.value ) .then(() => { if (location.state && location.state.from) { - history.replace(location.state.from); + history.push(location.state.from); } else { - history.replace("/"); + history.push("/"); } }) .catch((error) => { @@ -49,7 +52,7 @@ export function RegisterPage({ onRegister }) { setLoading(false); }); }, - [onRegister, location, history] + [register, location, history] ); return ( diff --git a/src/Room.jsx b/src/Room.jsx index ea89941..29f710f 100644 --- a/src/Room.jsx +++ b/src/Room.jsx @@ -42,7 +42,7 @@ import "matrix-react-sdk/res/css/views/voip/GroupCallView/_VideoGrid.scss"; 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 { fetchGroupCall } from "./ConferenceCallManagerHooks"; +import { useClient, useLoadGroupCall } from "./ConferenceCallManagerHooks"; import { ErrorModal } from "./ErrorModal"; import { GroupCallInspector } from "./GroupCallInspector"; import * as Sentry from "@sentry/react"; @@ -56,24 +56,39 @@ const canScreenshare = "getDisplayMedia" in navigator.mediaDevices; // For now we can disable screensharing in Safari. const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); -function useLoadGroupCall(client, roomId, viaServers) { - const [state, setState] = useState({ - loading: true, - error: undefined, - groupCall: undefined, - }); +export function Room() { + const [registeringGuest, setRegisteringGuest] = useState(false); + const [registrationError, setRegistrationError] = useState(); + const { loading, isAuthenticated, error, client, registerGuest } = + useClient(); useEffect(() => { - setState({ loading: true }); - fetchGroupCall(client, roomId, viaServers, 30000) - .then((groupCall) => setState({ loading: false, groupCall })) - .catch((error) => setState({ loading: false, error })); - }, [roomId]); + if (!loading && !isAuthenticated) { + setRegisteringGuest(true); - return state; + registerGuest() + .then(() => { + setRegisteringGuest(false); + }) + .catch((error) => { + setRegistrationError(error); + setRegisteringGuest(false); + }); + } + }, [loading, isAuthenticated]); + + if (loading || registeringGuest) { + return
Loading...
; + } + + if (registrationError || error) { + return ; + } + + return ; } -export function Room({ client, onLogout }) { +export function GroupCall({ client }) { const { roomId: maybeRoomId } = useParams(); const { hash, search } = useLocation(); const [simpleGrid, viaServers] = useMemo(() => { @@ -115,7 +130,6 @@ export function Room({ client, onLogout }) { return (
- +
@@ -347,7 +354,6 @@ function RoomSetupView({ } function InRoomView({ - onLogout, client, groupCall, roomName, @@ -424,11 +430,7 @@ function InRoomView({ - + {items.length === 0 ? ( diff --git a/src/UserMenu.jsx b/src/UserMenu.jsx index ddf7885..8fd6f03 100644 --- a/src/UserMenu.jsx +++ b/src/UserMenu.jsx @@ -7,45 +7,67 @@ import { ReactComponent as LogoutIcon } from "./icons/Logout.svg"; import styles from "./UserMenu.module.css"; import { Item } from "@react-stately/collections"; import { Menu } from "./Menu"; +import { useHistory, useLocation } from "react-router-dom"; +import { useClient } from "./ConferenceCallManagerHooks"; -export function UserMenu({ userName, signedIn, onLogin, onLogout }) { - const onAction = useCallback((value) => { - switch (value) { - case "user": - break; - case "logout": - onLogout(); - break; - case "login": - onLogin(); - break; - } - }); +export function UserMenu() { + const location = useLocation(); + const history = useHistory(); + const { isAuthenticated, isGuest, logout, userName } = useClient(); + + const onAction = useCallback( + (value) => { + switch (value) { + case "user": + break; + case "logout": + logout(); + break; + case "login": + history.push("/login", { state: { from: location } }); + break; + case "register": + history.push("/register", { state: { from: location } }); + break; + } + }, + [history, location, logout] + ); const items = useMemo(() => { - if (signedIn) { - return [ - { - key: "user", - icon: UserIcon, - label: userName, - }, - { - key: "logout", - label: "Sign Out", - icon: LogoutIcon, - }, - ]; - } else { - return [ + const arr = []; + + if (isAuthenticated) { + arr.push({ + key: "user", + icon: UserIcon, + label: userName, + }); + } + + if (!isAuthenticated || isGuest) { + arr.push( { key: "login", label: "Sign In", icon: LoginIcon, }, - ]; + { + key: "register", + label: "Register", + icon: LoginIcon, + } + ); + } else { + arr.push({ + key: "logout", + label: "Sign Out", + icon: LogoutIcon, + }); } - }, [signedIn, userName]); + + return arr; + }, [isAuthenticated, isGuest, userName]); return (