diff --git a/CHANGELOG.md b/CHANGELOG.md index 49661460..a0f1e9e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to - 🐛(migrations) use settings in migrations #1058 - 💄(frontend) truncate pinned participant name with ellipsis on overflow #1056 - ♿(frontend) prevent focus ring clipping on invite dialog #1078 +- ♿(frontend) dynamic tab title when connected to meeting #1060 ## [1.9.0] - 2026-03-02 diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 0a1d3c7e..789f7d09 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -4,7 +4,7 @@ import { Suspense } from 'react' import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { QueryClientProvider } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' -import { useLang } from 'hoofd' +import { useLang, useTitle } from 'hoofd' import { Switch, Route } from 'wouter' import { I18nProvider } from 'react-aria-components' import { Layout } from './layout/Layout' @@ -18,6 +18,7 @@ import { useIsSdkContext } from '@/features/sdk/hooks/useIsSdkContext' function App() { const { i18n } = useTranslation() useLang(i18n.language) + useTitle(import.meta.env.VITE_APP_TITLE ?? '') const isSDKContext = useIsSdkContext() diff --git a/src/frontend/src/features/rooms/livekit/hooks/useRoomPageTitle.ts b/src/frontend/src/features/rooms/livekit/hooks/useRoomPageTitle.ts new file mode 100644 index 00000000..c8c5d60e --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/hooks/useRoomPageTitle.ts @@ -0,0 +1,28 @@ +import { useTitle } from 'hoofd' +import { useRoomData } from './useRoomData' +import { useMemo } from 'react' + +const APP_TITLE = import.meta.env.VITE_APP_TITLE ?? '' + +/** + * Updates the browser tab title with the room name to help users easily find + * the meeting tab among many open tabs. Works on both the join screen and + * once connected. + */ +export const useRoomPageTitle = () => { + const roomData = useRoomData() + + const pageTitle = useMemo(() => { + if (!roomData) { + return APP_TITLE + } + + const roomLabel = roomData.name || roomData.slug || '' + + if (!roomLabel) return APP_TITLE + + return `${APP_TITLE} - ${roomLabel} ` + }, [roomData]) + + useTitle(pageTitle) +} diff --git a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx index d03fe15f..f69727dc 100644 --- a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx +++ b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx @@ -30,6 +30,7 @@ import { useSidePanel } from '../hooks/useSidePanel' import { RecordingProvider } from '@/features/recording' import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal' import { useConnectionObserver } from '../hooks/useConnectionObserver' +import { useRoomPageTitle } from '../hooks/useRoomPageTitle' import { useNoiseReduction } from '../hooks/useNoiseReduction' import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut' import { useSettingsDialog } from '@/features/settings' @@ -113,6 +114,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) { ) useConnectionObserver() + useRoomPageTitle() useVideoResolutionSubscription() useRegisterKeyboardShortcut({