(frontend) handle notifications by reusing the existing notif region

Render the notification region from the main window into the PiP
document via a portal, rather than duplicating it. This keeps a
single listener, a single store, and a single component instance —
so notifications stay consistent across both windows without extra
synchronization.

Simplest approach I could find. Good enough as a first pass;
worth revisiting if the requirements grow.

Co-authored-by: Cyril <c.gromoff@gmail.com>
This commit is contained in:
lebaudantoine
2026-05-20 21:06:19 +02:00
committed by aleb_the_flash
parent 38c131e02c
commit e21da647a0
3 changed files with 21 additions and 9 deletions
@@ -3,18 +3,17 @@ import { useRoomContext } from '@livekit/components-react'
import { Participant, RemoteParticipant, RoomEvent } from 'livekit-client'
import { ChatMessage, isMobileBrowser } from '@livekit/components-core'
import { useTranslation } from 'react-i18next'
import { Div } from '@/primitives'
import { NotificationType } from './NotificationType'
import { NotificationDuration } from './NotificationDuration'
import { decodeNotificationDataReceived } from './utils'
import { useNotificationSound } from '@/features/notifications/hooks/useSoundNotification'
import { ToastProvider, toastQueue } from './components/ToastProvider'
import { WaitingParticipantNotification } from './components/WaitingParticipantNotification'
import { toastQueue } from './components/ToastProvider'
import { layoutStore } from '@/stores/layout'
import { PanelId } from '@/features/rooms/livekit/hooks/useSidePanel'
import { useScreenReaderAnnounce } from '@/hooks/useScreenReaderAnnounce'
import { Emoji } from '@/features/reactions/types'
import { useReactions } from '@/features/reactions/hooks/useReactions'
import { NotificationProvider } from './NotificationProvider'
export const MainNotificationToast = () => {
const room = useRoomContext()
@@ -233,10 +232,5 @@ export const MainNotificationToast = () => {
// the 'notifications' namespace might not be loaded yet
useTranslation(['notifications'])
return (
<Div position="absolute" bottom={0} right={5} zIndex={1000}>
<ToastProvider />
<WaitingParticipantNotification />
</Div>
)
return <NotificationProvider />
}
@@ -0,0 +1,16 @@
import { Div } from '@/primitives'
import { ToastProvider } from './components/ToastProvider'
import { WaitingParticipantNotification } from './components/WaitingParticipantNotification'
export const NotificationProvider = ({
bottom = 0,
right = 5,
}: {
bottom?: number
right?: number
}) => (
<Div position="absolute" bottom={bottom} right={right} zIndex={1000}>
<ToastProvider />
<WaitingParticipantNotification />
</Div>
)
@@ -4,6 +4,7 @@ import { PipFloatingReactions } from './PipFloatingReactions'
import { PipStage } from './layout/PipStage'
import { ReactionsToolbar } from '@/features/reactions/components/toolbar/ReactionsToolbar'
import { useReactionsToolbar } from '@/features/reactions/hooks/useReactionsToolbar'
import { NotificationProvider } from '@/features/notifications/NotificationProvider'
const Container = styled('div', {
base: {
@@ -53,6 +54,7 @@ export const PipView = () => {
<ReactionsToolbar adjustedCentering={false} />
<PipControlBar showScreenShare={false} />
<PipFloatingReactions />
<NotificationProvider bottom={30} />
</Container>
)
}