From 09bb4daebcebeeae3d3afdbce0bdc6afbd300c48 Mon Sep 17 00:00:00 2001 From: Cyril Date: Wed, 21 Jan 2026 13:12:18 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D(docs)=20add=20pip=20component=20do?= =?UTF-8?q?cumentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add jsdoc comments to pip components and hooks --- .../rooms/livekit/components/DocumentPiPPortal.tsx | 6 ++++++ .../rooms/livekit/components/PipControlBar.tsx | 5 ++++- .../features/rooms/livekit/components/PipView.tsx | 6 +++++- .../features/rooms/livekit/components/RoomPiP.tsx | 4 ++++ .../components/controls/Options/PipOptionsMenu.tsx | 7 +++++-- .../rooms/livekit/hooks/RoomPiPProvider.tsx | 5 +++++ .../src/primitives/useOverlayPortalContainer.tsx | 13 ++++++++----- 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/frontend/src/features/rooms/livekit/components/DocumentPiPPortal.tsx b/src/frontend/src/features/rooms/livekit/components/DocumentPiPPortal.tsx index 1355606c..5fe98598 100644 --- a/src/frontend/src/features/rooms/livekit/components/DocumentPiPPortal.tsx +++ b/src/frontend/src/features/rooms/livekit/components/DocumentPiPPortal.tsx @@ -29,6 +29,12 @@ const copyStyles = (source: Document, target: Document) => { }) } +/** + * React Portal that renders children into a Document Picture-in-Picture window. + * Handles PiP window lifecycle, style injection, React root management, and uses UNSAFE_PortalProvider + * to ensure React Aria overlays render correctly within the PiP window. + * Creates a fresh React root on reopen to prevent black screen issues. + */ export const DocumentPiPPortal = ({ isOpen, width, diff --git a/src/frontend/src/features/rooms/livekit/components/PipControlBar.tsx b/src/frontend/src/features/rooms/livekit/components/PipControlBar.tsx index 39389a37..3be6caee 100644 --- a/src/frontend/src/features/rooms/livekit/components/PipControlBar.tsx +++ b/src/frontend/src/features/rooms/livekit/components/PipControlBar.tsx @@ -9,7 +9,10 @@ import { HandToggle } from './controls/HandToggle' import { OptionsButton } from './controls/Options/OptionsButton' import { StartMediaButton } from './controls/StartMediaButton' -// Compact PiP toolbar; keep all PiP-specific controls in one place. +/** + * Compact control bar for the Picture-in-Picture window. + * Centralizes all PiP controls (devices, reactions, screen share, options, etc.) in one reusable component. + */ export const PipControlBar = ({ showScreenShare, }: { diff --git a/src/frontend/src/features/rooms/livekit/components/PipView.tsx b/src/frontend/src/features/rooms/livekit/components/PipView.tsx index 9e28a0f9..db67d607 100644 --- a/src/frontend/src/features/rooms/livekit/components/PipView.tsx +++ b/src/frontend/src/features/rooms/livekit/components/PipView.tsx @@ -23,7 +23,11 @@ const pickTrackForPip = ( return tracks[0] } -// Renders the PiP viewport and a compact control bar inside the PiP window. +/** + * Main view component for the Picture-in-Picture window. + * Handles track selection (prioritizes screen share), layout switching (grid for multiple participants), + * and renders the control bar and side panel within the PiP window. + */ export const PipView = () => { const tracks = useTracks( [ diff --git a/src/frontend/src/features/rooms/livekit/components/RoomPiP.tsx b/src/frontend/src/features/rooms/livekit/components/RoomPiP.tsx index da233d0b..ec541725 100644 --- a/src/frontend/src/features/rooms/livekit/components/RoomPiP.tsx +++ b/src/frontend/src/features/rooms/livekit/components/RoomPiP.tsx @@ -2,6 +2,10 @@ import { DocumentPiPPortal } from './DocumentPiPPortal' import { PipView } from './PipView' import { useRoomPiP } from '../hooks/useRoomPiP' +/** + * Wrapper that mounts the PiP UI when room-level PiP state is enabled. + * Bridges RoomPiPProvider state with DocumentPiPPortal and PipView rendering. + */ export const RoomPiP = () => { const { isOpen, close } = useRoomPiP() diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx index c9b0340c..a6258dcb 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx @@ -11,14 +11,17 @@ type PipOptionsMenuProps = { label: string } -// PiP-specific options menu positioned locally above the trigger button. +/** + * PiP-specific options menu with absolute positioning for correct alignment in PiP window. + * Renders locally (unlike standard Menu) and closes automatically on item click or outside click. + */ export const PipOptionsMenu = ({ wrapperRef, isOpen, setIsOpen, label, }: PipOptionsMenuProps) => { - // Close menu when a menu item action completes (e.g., transcription, effects). + // Close menu when a menu item action completes (e.g., transcription, effects, recording). useEffect(() => { if (!isOpen) return const doc = wrapperRef.current?.ownerDocument ?? document diff --git a/src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx b/src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx index 3726daf7..172f31c3 100644 --- a/src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx +++ b/src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx @@ -1,6 +1,11 @@ import { useCallback, useMemo, useState } from 'react' import { RoomPiPContext } from './roomPiPContext' +/** + * Context Provider that manages Picture-in-Picture state at the room level. + * Handles open/closed state, browser support detection, and exposes open/close/toggle functions. + * Components access PiP state via the useRoomPiP hook. + */ export const RoomPiPProvider = ({ children, }: { diff --git a/src/frontend/src/primitives/useOverlayPortalContainer.tsx b/src/frontend/src/primitives/useOverlayPortalContainer.tsx index 2300d85b..2822f0d2 100644 --- a/src/frontend/src/primitives/useOverlayPortalContainer.tsx +++ b/src/frontend/src/primitives/useOverlayPortalContainer.tsx @@ -1,20 +1,23 @@ import { useMemo } from 'react' import { useUNSAFE_PortalContext } from '@react-aria/overlays' +/** + * Hook to retrieve the portal container for overlays (menus, tooltips, popovers). + * Returns the container from UNSAFE_PortalProvider context (pip-root in PiP, undefined in main window). + */ export const useOverlayPortalContainer = () => { const { getContainer } = useUNSAFE_PortalContext() - // Read the portal container provided by UNSAFE_PortalProvider. - // This is how overlays know which document/window they should render into. - // "UNSAFE" means we're overriding the library default container on purpose. return useMemo(() => getContainer?.() ?? undefined, [getContainer]) } +/** + * Hook to retrieve the boundary element for overlay positioning. + * Returns the portal container in PiP (for PiP-relative positioning), undefined in main window. + */ export const useOverlayBoundaryElement = () => { const portalContainer = useOverlayPortalContainer() return useMemo(() => { - // Use the portal container as the positioning boundary. - // In PiP this keeps overlays positioned relative to the PiP window. if (portalContainer) return portalContainer return undefined }, [portalContainer])