From aaf1163910c403d92ff55df747ec60e8629f0798 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Tue, 4 Mar 2025 18:39:45 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8(frontend)=20add=20login=20hint=20f?= =?UTF-8?q?or=20unauthenticated=20users=20in=20lobby?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add informational message suggesting authentication for users waiting in lobby without being logged in. Highlight that logging in could grant immediate access without admin approval when rooms have trusted access level enabled. --- .../src/features/rooms/components/Join.tsx | 10 ++- src/frontend/src/hooks/useLoginHint.ts | 22 +++++++ src/frontend/src/layout/Header.tsx | 66 ++++++++++++++++++- src/frontend/src/locales/de/global.json | 8 +++ src/frontend/src/locales/en/global.json | 8 +++ src/frontend/src/locales/fr/global.json | 8 +++ src/frontend/src/stores/hints.ts | 9 +++ 7 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 src/frontend/src/hooks/useLoginHint.ts create mode 100644 src/frontend/src/stores/hints.ts diff --git a/src/frontend/src/features/rooms/components/Join.tsx b/src/frontend/src/features/rooms/components/Join.tsx index 67e5e19c..318fbd72 100644 --- a/src/frontend/src/features/rooms/components/Join.tsx +++ b/src/frontend/src/features/rooms/components/Join.tsx @@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next' import { usePreviewTracks } from '@livekit/components-react' import { css } from '@/styled-system/css' import { Screen } from '@/layout/Screen' -import { useMemo, useEffect, useRef, useState, useCallback } from 'react' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { LocalVideoTrack, Track } from 'livekit-client' import { H } from '@/primitives/H' import { SelectToggleDevice } from '../livekit/components/controls/SelectToggleDevice' @@ -26,6 +26,8 @@ import { useQuery } from '@tanstack/react-query' import { queryClient } from '@/api/queryClient' import { ApiLobbyStatus, ApiRequestEntry } from '../api/requestEntry' import { Spinner } from '@/primitives/Spinner' +import { ApiAccessLevel } from '../api/ApiRoom' +import { useLoginHint } from '@/hooks/useLoginHint' const onError = (e: Error) => console.error('ERROR', e) @@ -264,10 +266,16 @@ export const Join = ({ onAccepted: handleAccepted, }) + const { openLoginHint } = useLoginHint() + const handleSubmit = async () => { const { data } = await refetchRoom() if (!data?.livekit) { + // Display a message to inform the user that by logging in, they won't have to wait for room entry approval. + if (data?.access_level == ApiAccessLevel.TRUSTED) { + openLoginHint() + } startWaiting() return } diff --git a/src/frontend/src/hooks/useLoginHint.ts b/src/frontend/src/hooks/useLoginHint.ts new file mode 100644 index 00000000..314b8006 --- /dev/null +++ b/src/frontend/src/hooks/useLoginHint.ts @@ -0,0 +1,22 @@ +import { useSnapshot } from 'valtio' +import { hintsStore } from '@/stores/hints' +import { useUser } from '@/features/auth' +import { useEffect } from 'react' + +export const useLoginHint = () => { + const hintsSnap = useSnapshot(hintsStore) + const { isLoggedIn } = useUser() + + const openLoginHint = () => (hintsStore.showLoginHint = true) + const closeLoginHint = () => (hintsStore.showLoginHint = false) + + useEffect(() => { + if (isLoggedIn && hintsSnap.showLoginHint) closeLoginHint() + }, [isLoggedIn, hintsSnap]) + + return { + isVisible: hintsSnap.showLoginHint, + openLoginHint, + closeLoginHint, + } +} diff --git a/src/frontend/src/layout/Header.tsx b/src/frontend/src/layout/Header.tsx index 05903238..50d37d10 100644 --- a/src/frontend/src/layout/Header.tsx +++ b/src/frontend/src/layout/Header.tsx @@ -2,7 +2,7 @@ import { Link } from 'wouter' import { css } from '@/styled-system/css' import { HStack, Stack } from '@/styled-system/jsx' import { useTranslation } from 'react-i18next' -import { Button } from '@/primitives' +import { Button, Text } from '@/primitives' import { SettingsButton } from '@/features/settings' import { useUser } from '@/features/auth' import { useMatchesRoute } from '@/navigation/useMatchesRoute' @@ -12,6 +12,7 @@ import { MenuList } from '@/primitives/MenuList' import { ProConnectButton } from '@/components/ProConnectButton' import LogoAsset from '@/assets/logo.svg' +import { useLoginHint } from '@/hooks/useLoginHint' const Marianne = () => { return ( @@ -91,6 +92,64 @@ const Logo = () => { ) } +const LoginHint = () => { + const { t } = useTranslation() + const { isVisible, closeLoginHint } = useLoginHint() + if (!isVisible) return null + return ( +
+ + {t('loginHint.title')} + + + {t('loginHint.body')} + + +
+ ) +} + export const Header = () => { const { t } = useTranslation() const isHome = useMatchesRoute('home') @@ -144,7 +203,10 @@ export const Header = () => {