Skip to content

✨(feat) Introduce Picture-in-Picture (PiP)#890

Open
Ovgodd wants to merge 41 commits intomainfrom
feat/pip-support
Open

✨(feat) Introduce Picture-in-Picture (PiP)#890
Ovgodd wants to merge 41 commits intomainfrom
feat/pip-support

Conversation

@Ovgodd
Copy link
Copy Markdown
Collaborator

@Ovgodd Ovgodd commented Jan 22, 2026

Purpose

Introduce a Document Picture-in-Picture (PiP) experience that reuses the existing room controls and side panels,

Proposal

Implement a dedicated PiP window using a React portal that mounts the desired React tree into the PiP document. The PiP view supports single or grid layouts, provides the control ba and notifications

  • PiP open/close and reopen correctly
  • Overlays (menus/tooltips) render in the PiP document
  • Side panel (transcript/record/effects) opens in Pix
  • Notifications

@Ovgodd Ovgodd requested a review from lebaudantoine January 22, 2026 10:17
@Ovgodd Ovgodd self-assigned this Jan 22, 2026
@Ovgodd Ovgodd added the enhancement New feature or request label Jan 22, 2026
@Ovgodd Ovgodd force-pushed the feat/pip-support branch 4 times, most recently from d071c97 to 851ca16 Compare January 22, 2026 10:46
@Ovgodd Ovgodd marked this pull request as ready for review January 23, 2026 09:21
@Ovgodd
Copy link
Copy Markdown
Collaborator Author

Ovgodd commented Jan 23, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 23, 2026

✅ Actions performed

Full review triggered.

1 similar comment
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 23, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 23, 2026

Caution

Review failed

The head commit changed during the review from 74dc656 to d7fb31e.

Walkthrough

This pull request introduces a Picture-in-Picture (PiP) feature for video conferencing. It adds a new React-based PiP infrastructure including a document PiP portal component, PiP-specific UI components (control bar, view, lateral menu, options menu), hooks (useDocumentPiP, useRoomPiP), and context management (RoomPiPProvider, RoomPiPContext). Supporting changes include TypeScript type definitions for react-aria overlays, portal-aware hook utilities, modifications to existing components (Menu, Popover, TooltipWrapper, OptionsButton, VideoConference) to adapt to PiP contexts, and localization strings in four languages. The feature integrates with the browser's documentPictureInPicture API.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: introducing Picture-in-Picture functionality to the application.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly explains the purpose of introducing Document Picture-in-Picture (PiP) functionality and details the implementation approach using React portals.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/frontend/src/primitives/TooltipWrapper.tsx (1)

9-49: PiP tooltips ignore tooltipType delay.

In the external-document branch, VisualOnlyTooltip (see src/frontend/src/primitives/VisualOnlyTooltip.tsx, around lines 22-40) shows immediately on hover/focus, so tooltipType="delayed" no longer delays in PiP. If the delay is meant to stay consistent, pass it through and implement the delay in VisualOnlyTooltip.

Suggested wiring change (requires adding a delay prop to VisualOnlyTooltip)
-    isExternalDocument ? (
-      <VisualOnlyTooltip tooltip={tooltip}>{children}</VisualOnlyTooltip>
-    ) : (
+    isExternalDocument ? (
+      <VisualOnlyTooltip
+        tooltip={tooltip}
+        delayMs={
+          tooltipType === 'instant'
+            ? INSTANT_TOOLTIP_DELAY_MS
+            : DELAYED_TOOLTIP_DELAY_MS
+        }
+      >
+        {children}
+      </VisualOnlyTooltip>
+    ) : (
🤖 Fix all issues with AI agents
In `@src/frontend/`@types/react-aria-overlays.d.ts:
- Around line 1-4: Add declarations for the missing types in the module
augmentation: declare PortalProviderContextValue as an object with getContainer:
() => HTMLElement | null and PortalProviderProps as an object with getContainer:
() => HTMLElement | null and children: React.ReactNode; keep the existing
exported symbols useUNSAFE_PortalContext(): PortalProviderContextValue and
UNSAFE_PortalProvider: (props: PortalProviderProps) => JSX.Element so imports
like useOverlayPortalContainer compile.

In
`@src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsButton.tsx`:
- Around line 16-33: The outside-click pointerdown handler inside the useEffect
(referencing wrapperRef, isInPiP, isOpen) duplicates PipOptionsMenu's click
handling and can close the menu before PipOptionsMenu's item actions run; remove
this useEffect block (or disable its registration when PipOptionsMenu is
present) so outside-click logic is consolidated in PipOptionsMenu, ensuring only
PipOptionsMenu handles closing on clicks and avoiding conflicting pointerdown vs
click ordering.

In
`@src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx`:
- Around line 59-68: The menu needs Escape-key dismissal: inside the
PipOptionsMenu component's existing effect (where isOpen and setIsOpen are
used), add a keydown listener that, when isOpen is true and event.key ===
'Escape', calls setIsOpen(false); ensure the listener is registered only while
the menu is open and always cleaned up in the effect's cleanup to remove the
handler; reference the Button trigger (id "room-options-trigger") and the
isOpen/setIsOpen state so the handler closes the same menu instance.
- Around line 25-50: The effect currently only closes the menu when a menu item
is clicked; update the click handler in the useEffect (handleMenuItemClick) to
also close the menu when the click is outside the menu wrapper: if
wrapperRef.current exists and neither wrapper.contains(target) nor
wrapper.querySelector('button')?.contains(target) are true then call
setIsOpen(false) (use requestAnimationFrame if you want the same timing
behavior), keeping the existing doc.addEventListener(..., true) and the cleanup
removeEventListener so outside clicks on the PiP background will close the menu.

In `@src/frontend/src/features/rooms/livekit/components/DocumentPiPPortal.tsx`:
- Around line 39-58: syncCssVariables is scanning every computed style property
each time (in applyVarsFrom) which is expensive; update it to cache CSS variable
names per source Document (keyed by source.documentElement or source.baseURI)
and reuse that cache on subsequent PiP opens, and only read values via
source.defaultView.getComputedStyle for those cached variable names and set them
on target.documentElement; reference the syncCssVariables function and its inner
applyVarsFrom to implement the cache lookup/population and the reduced per-open
loop so you avoid iterating all computed style properties on each call.
- Around line 126-140: DocumentPiPPortal and useDocumentPiP both register
pagehide/beforeunload on pipWindow causing duplicate handlers; change
useDocumentPiP to accept an optional onClose callback and move the
pagehide/beforeunload registration there (using pipWindow from the hook), then
remove the useEffect that registers those events from DocumentPiPPortal (and let
the hook call onClose which should reset containerRef.current,
setContainer(null) and propagate the original onClose). Ensure you update the
hook signature (useDocumentPiP) and all call sites in DocumentPiPPortal to pass
the existing onClose prop and remove the duplicate event listener effect that
references pipWindow, containerRef, setContainer.

In `@src/frontend/src/features/rooms/livekit/components/PipControlBar.tsx`:
- Around line 65-73: PipControlsRight's absolute positioning with a fixed right
offset (right: '1.35rem') can overlap centered controls in PipControlsCenter on
narrow PiP windows; update the layout so controls don't collide by adding a
minimum width or switching to a responsive flex layout: modify the styled
component PipControlsRight (and/or the parent PipControls container) to either
enforce a minWidth (e.g., minWidth on PipControlsRight or min-width on
PipControls container) or remove absolute positioning and use flexbox with
justify-content: space-between / gap or media query breakpoints to change
positioning when the container becomes too narrow, ensuring PipControlsCenter
remains centered and elements don't overlap.

In `@src/frontend/src/features/rooms/livekit/components/PipView.tsx`:
- Around line 31-44: The early-return logic in PipView can look asymmetric
because when pickTrackForPip(tracks) returns undefined but hasMultipleTiles is
true the component will render the grid (handled by GridLayout) even if tracks
are placeholders; add a short inline comment in PipView next to the if
(!trackRef && !hasMultipleTiles) return null explaining this intentional
behavior — that placeholder-only scenarios are expected to fall through to the
GridLayout path and that pickTrackForPip may return a placeholder or undefined
while GridLayout will render placeholders correctly.

In `@src/frontend/src/features/rooms/livekit/hooks/useDocumentPiP.ts`:
- Around line 28-39: The openPiP function currently awaits pip.requestWindow
without handling rejections; wrap the call in a try-catch so any errors from
pip.requestWindow are caught, avoid setting pipWindow on failure, and return
null on error. Specifically, in useDocumentPiP's openPiP, surround the await
pip.requestWindow({ width, height }) with try-catch, call setPipWindow only on
success, and handle/log the caught error (e.g., with console.error or existing
logger) before returning null so no unhandled promise rejection occurs.
- Around line 28-39: openPiP can race when called multiple times before
requestWindow resolves; introduce a ref (e.g., pendingPiPRef) to store the
in-flight Promise and use it to short-circuit subsequent calls, update
setPipWindow only once the Promise resolves, clear the ref on resolve/reject,
and also re-check pipWindow (and pipWindow.closed) after await to avoid creating
duplicate windows; update references in the openPiP callback (and any cleanup)
to use pendingPiPRef alongside the existing pipWindow and setPipWindow logic.
- Around line 23-26: The useMemo-based detection of documentPictureInPicture in
useDocumentPiP recalculates on remount; replace the useMemo call that defines
isSupported with a more idiomatic SSR-safe pattern (either a module-level
constant or a useState with a lazy initializer) so the window check (typeof
window === 'undefined') runs only once and the result is stable for the hook
lifecycle; locate the isSupported declaration inside the useDocumentPiP hook and
change it to useState(() => typeof window !== 'undefined' &&
'documentPictureInPicture' in window) or move that evaluation to a top-level
constant and have the hook read that constant.

In `@src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx`:
- Around line 200-208: The inline style block in VideoConference.tsx uses
hardcoded "magic" values (358px, 80px, 16px, 3rem) tied to isSidePanelOpen;
extract these into named constants or CSS variables and use them instead to
avoid layout coupling: add descriptive CSS variables (e.g.,
--lk-side-panel-width, --lk-top-offset, --lk-right-offset, --lk-side-panel-gap)
in the module or global stylesheet and replace the numeric literals in the style
inset expressions and transition comment reference the style object in
VideoConference.tsx so the component reads those variables (or imports
constants) rather than hardcoding pixels.

In `@src/frontend/src/locales/nl/rooms.json`:
- Around line 235-238: The Dutch locale still has English PiP labels; update the
pictureInPicture translations by replacing the values for the keys
"pictureInPicture.enter" and "pictureInPicture.exit" with Dutch text (e.g.,
"Beeld-in-beeld" and "Beeld-in-beeld sluiten" or preferred Dutch phrasing),
ensuring the JSON structure and quoting remain valid.

In `@src/frontend/src/primitives/useOverlayPortalContainer.tsx`:
- Around line 18-24: The function useOverlayBoundaryElement contains a redundant
conditional returning portalContainer or undefined; simplify it by returning
portalContainer directly (or portalContainer ?? undefined) instead of the if
block — update the return inside useMemo in useOverlayBoundaryElement which
calls useOverlayPortalContainer to just return portalContainer and keep the
dependency array [portalContainer].

Comment thread src/frontend/@types/react-aria-overlays.d.ts
Comment thread src/frontend/src/features/pip/components/controls/PipOptionsMenu.tsx Outdated
Comment thread src/frontend/src/features/pip/components/DocumentPiPPortal.tsx
Comment thread src/frontend/src/features/rooms/livekit/hooks/useDocumentPiP.ts Outdated
Comment thread src/frontend/src/features/rooms/livekit/hooks/useDocumentPiP.ts Outdated
Comment thread src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx Outdated
Comment thread src/frontend/src/locales/nl/rooms.json
Comment thread src/frontend/src/primitives/useOverlayPortalContainer.tsx
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 23, 2026

Walkthrough

This pull request introduces Picture-in-Picture (PiP) functionality to a LiveKit-based video conferencing frontend. The implementation includes a new document PiP portal system (DocumentPiPPortal) that manages rendering content into a separate PiP window with synchronized styling, cross-document theme and CSS variable propagation, and lifecycle management. New React hooks (useDocumentPiP, useRoomPiP, RoomPiPProvider) provide PiP window and state management at the room level. Multiple UI components render PiP-specific controls (PipControlBar, PipLateralMenu, PictureInPictureMenuItem, PipOptionsMenu) and content (PipView). Core primitive components (Menu, Popover, TooltipWrapper, VisualOnlyTooltip) are updated to detect and adapt behavior for PiP contexts using portal container awareness. Localization entries for en, de, fr, and nl add PiP feature labels. TypeScript declarations for @react-aria/overlays enable portal provider access. The VideoConference component is wrapped with RoomPiPProvider for room-level PiP state.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Introduce Picture-in-Picture (PiP)' clearly summarizes the main feature addition, matching the comprehensive PiP implementation changes across components, hooks, and UI elements in the changeset.
Description check ✅ Passed The description is directly related to the changeset, explaining the PiP feature purpose, implementation approach (React portal, layouts, controls), and completion of key objectives (open/close, overlays, side panel integration).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Fix all issues with AI agents
In `@src/frontend/`@types/react-aria-overlays.d.ts:
- Around line 1-4: The ambient module declaration for '@react-aria/overlays'
declares unresolved types (PortalProviderContextValue, PortalProviderProps) and
unused exports (useUNSAFE_PortalContext, UNSAFE_PortalProvider); remove this
dead declaration file entirely to prevent TypeScript compilation errors and
because the package and symbols are not used or present in dependencies.

In
`@src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx`:
- Around line 24-43: The effect in PipOptionsMenu.tsx currently only closes the
menu when a menu item is clicked; extend the handleMenuItemClick (or rename to
handleDocumentClick) to also detect outside clicks by checking if the click
target is not contained within wrapperRef.current (and not the trigger button)
and call setIsOpen(false) via requestAnimationFrame for consistency; ensure the
listener is still attached to doc (ownerDocument) and cleaned up in the effect
return so outside clicks close the PiP options menu as documented.

In
`@src/frontend/src/features/rooms/livekit/components/controls/PipLateralMenu.tsx`:
- Around line 33-34: The toggle handler uses the current isOpen value directly
which can lead to stale state; update handlePress to use a functional state
updater: call setIsOpen(prev => !prev) instead of setIsOpen(!isOpen), leaving
handleClose as is; update the function referenced as handlePress in
PipLateralMenu.tsx to use the functional form to ensure correctness under
concurrent/batched updates.
- Around line 49-60: The Dialog in PipLateralMenu lacks an accessible name;
update the Dialog usage in the PipLateralMenu component to include an aria-label
(for example "PIP lateral menu" or "Picture-in-picture controls") so screen
readers can identify the dialog context; add the aria-label prop directly on the
Dialog element in PipLateralMenu to provide a clear, concise label (e.g.,
aria-label="PIP lateral menu").

In `@src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx`:
- Around line 1-13: Import the ReactNode type explicitly and use it in the
RoomPiPProvider props instead of referencing React.ReactNode; specifically add
an import like "import type { ReactNode } from 'react'" at the top and change
the props annotation from "children: React.ReactNode" to "children: ReactNode"
in the RoomPiPProvider declaration to avoid relying on the global React
namespace.

In `@src/frontend/src/features/rooms/livekit/hooks/useDocumentPiP.ts`:
- Around line 28-38: The openPiP function may throw if pip.requestWindow
rejects; update useDocumentPiP.openPiP to wrap the await pip.requestWindow(...)
call in a try/catch, catch any error from requestWindow, optionally log it
(e.g., via console.warn or existing logger), ensure setPipWindow is only called
on success and return null on failure so callers (like DocumentPiPPortal) don't
receive an unhandled rejection; reference the openPiP async function, the
pip.requestWindow call, and the setPipWindow state updater when making the
change.

In `@src/frontend/src/locales/nl/rooms.json`:
- Around line 235-238: Replace the English strings under the JSON object
"pictureInPicture" (keys "enter" and "exit") with native Dutch phrasing: set
"enter" to "Beeld-in-beeld" and "exit" to "Beeld-in-beeld sluiten" (or consult a
native speaker for preferred variant), keeping the same keys unchanged.

In `@src/frontend/src/primitives/TooltipWrapper.tsx`:
- Around line 32-49: TooltipWrapper currently bypasses tooltipType delays for
external-document tooltips because VisualOnlyTooltip is rendered without a
delay; compute the effective delay (use tooltipType to choose between
INSTANT_TOOLTIP_DELAY_MS and DELAYED_TOOLTIP_DELAY_MS) in TooltipWrapper and
pass it as a prop (e.g., delayMs) into VisualOnlyTooltip so it can honor the
same timing as the TooltipTrigger path; update VisualOnlyTooltip to accept and
apply delayMs. Reference: TooltipWrapper (useOverlayPortalContainer,
tooltipType, INSTANT_TOOLTIP_DELAY_MS, DELAYED_TOOLTIP_DELAY_MS) and
VisualOnlyTooltip.

Comment thread src/frontend/@types/react-aria-overlays.d.ts
Comment thread src/frontend/src/features/pip/components/controls/PipOptionsMenu.tsx Outdated
Comment on lines +33 to +34
const handlePress = () => setIsOpen(!isOpen)
const handleClose = () => setIsOpen(false)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Use a functional state update when toggling the menu.

This avoids stale state under concurrent/batched updates.

Suggested change
-  const handlePress = () => setIsOpen(!isOpen)
+  const handlePress = () => setIsOpen((open) => !open)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handlePress = () => setIsOpen(!isOpen)
const handleClose = () => setIsOpen(false)
const handlePress = () => setIsOpen((open) => !open)
const handleClose = () => setIsOpen(false)
🤖 Prompt for AI Agents
In
`@src/frontend/src/features/rooms/livekit/components/controls/PipLateralMenu.tsx`
around lines 33 - 34, The toggle handler uses the current isOpen value directly
which can lead to stale state; update handlePress to use a functional state
updater: call setIsOpen(prev => !prev) instead of setIsOpen(!isOpen), leaving
handleClose as is; update the function referenced as handlePress in
PipLateralMenu.tsx to use the functional form to ensure correctness under
concurrent/batched updates.

Comment thread src/frontend/src/features/pip/components/controls/PipLateralMenu.tsx Outdated
Comment on lines +1 to +13
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,
}: {
children: React.ReactNode
}) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Prefer explicit ReactNode import for types.
Avoid relying on a global React namespace, which is TS-config dependent.

♻️ Suggested refactor
-import { useCallback, useMemo, useState } from 'react'
+import { useCallback, useMemo, useState } from 'react'
+import type { ReactNode } from 'react'
@@
 }: {
-  children: React.ReactNode
+  children: ReactNode
 }) => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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,
}: {
children: React.ReactNode
}) => {
import { useCallback, useMemo, useState } from 'react'
import type { ReactNode } 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,
}: {
children: ReactNode
}) => {
🤖 Prompt for AI Agents
In `@src/frontend/src/features/rooms/livekit/hooks/RoomPiPProvider.tsx` around
lines 1 - 13, Import the ReactNode type explicitly and use it in the
RoomPiPProvider props instead of referencing React.ReactNode; specifically add
an import like "import type { ReactNode } from 'react'" at the top and change
the props annotation from "children: React.ReactNode" to "children: ReactNode"
in the RoomPiPProvider declaration to avoid relying on the global React
namespace.

Comment thread src/frontend/src/features/rooms/livekit/hooks/useDocumentPiP.ts Outdated
Comment thread src/frontend/src/locales/nl/rooms.json
Comment thread src/frontend/src/primitives/TooltipWrapper.tsx
@Ovgodd Ovgodd linked an issue Jan 23, 2026 that may be closed by this pull request
@Ovgodd Ovgodd force-pushed the feat/pip-support branch 2 times, most recently from 2f81be0 to 67dd60c Compare February 10, 2026 12:50
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Ovgodd added 11 commits April 8, 2026 09:27
utility hook to cleanly open/close the pip window
mount react content into pip window with styles
add labels for PiP in each supported language
prevent black screen after closing and reopening pip
avoid layout jumps and prepare for more buttons
route menus/tooltips to the pip document
keep pip options layout reusable and isolated
centralize pip controls in reusable component
close options menu when selecting transcription or
add jsdoc comments to pip components and hooks
Prevent PiP actions from affecting main panel state and reduce PiP-only noise.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 7d92dd8 to 07ed4d7 Compare April 8, 2026 07:52
Ovgodd added 3 commits April 8, 2026 10:19
Show a main tile with a bottom-right thumbnail in PiP, like Google Meet.
Use PiP document ResizeObserver so controls hide into "..." while resizing.
PiP-only reactions strip, store flag, and overflow menu wired to PiP state.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 1cd8f0b to 40da9c0 Compare April 10, 2026 07:25
Ovgodd added 3 commits April 22, 2026 18:00
Reuse a single ResizeObserver hook in the PiP control bar.
Render all participants with a focus mode and animated adaptive grid.
Start PiP in a taller shape closer to a typical video call layout.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch 3 times, most recently from 77f7726 to 28dd02c Compare April 24, 2026 07:29
Ovgodd added 2 commits April 24, 2026 09:29
Labels for PiP window, stage, toolbar, reactions, and SR open/close.
Cross-doc focus helpers, Escape stack, lang/title sync, landmarks, SR announce.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 28dd02c to 12f607d Compare April 24, 2026 07:30
PiP-native options popover; split reactions, keyboard nav, and pagination.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 12f607d to 946da58 Compare April 24, 2026 11:07
Ovgodd added 3 commits April 24, 2026 13:36
Set a single clipping owner per PiP layout and use a consistent 4px radius.
Force-close PiP on unmount and reset PiP state so next room starts clean.
Forward PiP keydown events and register PiP-specific handlers.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 5ca3976 to 74dc656 Compare April 27, 2026 09:11
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 74dc656 to d7fb31e Compare April 27, 2026 09:13
@suitenumerique suitenumerique deleted a comment from coderabbitai Bot Apr 27, 2026
Group banner and toasts in one stack, cap visibility, fix chat dedup.
@Ovgodd Ovgodd force-pushed the feat/pip-support branch from 8296fc5 to 1080407 Compare April 29, 2026 05:21
Ovgodd added 3 commits April 29, 2026 14:13
Extract OverflowItems, replace `any`, convert function declarations to const arrows.
Replace nested ternary logic, use globalThis instead of window, and switch side-panel enum re-exports to export-from for clearer and safer patterns.

Made-with: Cursor
Flip when top overflows; clamp left/right so PiP tooltips stay visible.
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Picture-in-Picture Support

2 participants