🐛(frontend) route PiP tile effects to the PiP side panel

Inject side-panel store into PiP tiles so Effects opens in PiP window.
This commit is contained in:
Cyril
2026-05-06 13:08:26 +02:00
parent 45b939da5c
commit 87f8d4ca7e
4 changed files with 15 additions and 5 deletions
@@ -2,6 +2,7 @@ import { memo } from 'react'
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { styled } from '@/styled-system/jsx'
import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile'
import { pipLayoutStore } from '../../stores/pipLayoutStore'
import { getTrackKey } from '../../utils/pipTrackSelection'
type PipFocusLayoutProps = {
@@ -25,6 +26,7 @@ export const PipFocusLayout = memo(
<ParticipantTile
key={getTrackKey(mainTrack)}
trackRef={mainTrack}
sidePanelStore={pipLayoutStore}
/>
</MainSlot>
{thumbnailTrack && (
@@ -32,6 +34,7 @@ export const PipFocusLayout = memo(
<ParticipantTile
key={getTrackKey(thumbnailTrack)}
trackRef={thumbnailTrack}
sidePanelStore={pipLayoutStore}
/>
</Thumbnail>
)}
@@ -2,6 +2,7 @@ import { memo, useMemo, useRef } from 'react'
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { styled } from '@/styled-system/jsx'
import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile'
import { pipLayoutStore } from '../../stores/pipLayoutStore'
import { usePipElementSize } from '../../hooks/usePipElementSize'
import { usePipFlipAnimations } from '../../hooks/usePipFlipAnimations'
import { computePipGridLayout } from '../../utils/pipGrid'
@@ -46,7 +47,7 @@ export const PipGridLayout = memo(({ tracks }: PipGridLayoutProps) => {
<GridContainer ref={containerRef} style={gridStyle}>
{tracks.map((track, index) => (
<GridCell key={tileKeys[index]} style={placements[index]}>
<ParticipantTile trackRef={track} />
<ParticipantTile trackRef={track} sidePanelStore={pipLayoutStore} />
</GridCell>
))}
</GridContainer>
@@ -27,6 +27,7 @@ import { HStack } from '@/styled-system/jsx'
import { MutedMicIndicator } from './MutedMicIndicator'
import { ParticipantPlaceholder } from './ParticipantPlaceholder'
import { ParticipantTileFocus } from './ParticipantTileFocus'
import type { SidePanelStore } from '../hooks/useSidePanel'
import { FullScreenShareWarning } from './FullScreenShareWarning'
import { ParticipantName } from './ParticipantName'
import { getParticipantName } from '@/features/rooms/utils/getParticipantName'
@@ -52,6 +53,7 @@ export function TrackRefContextIfNeeded(
interface ParticipantTileExtendedProps extends ParticipantTileProps {
disableMetadata?: boolean
sidePanelStore?: SidePanelStore
}
export const ParticipantTile: (
@@ -66,6 +68,7 @@ export const ParticipantTile: (
onParticipantClick,
disableSpeakingIndicator,
disableMetadata,
sidePanelStore,
...htmlProps
}: ParticipantTileExtendedProps,
ref
@@ -235,6 +238,7 @@ export const ParticipantTile: (
<ParticipantTileFocus
trackRef={trackReference}
hasKeyboardFocus={hasKeyboardFocus}
sidePanelStore={sidePanelStore}
/>
)}
</ParticipantContextIfNeeded>
@@ -16,7 +16,7 @@ import {
import { useTranslation } from 'react-i18next'
import { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { useEffect, useRef, useState } from 'react'
import { useSidePanel } from '../hooks/useSidePanel'
import { type SidePanelStore, useSidePanel } from '../hooks/useSidePanel'
import { useFullScreen } from '../hooks/useFullScreen'
import { Participant, Track } from 'livekit-client'
import { MuteAlertDialog } from './MuteAlertDialog'
@@ -74,9 +74,9 @@ const FocusButton = ({
)
}
const EffectsButton = () => {
const EffectsButton = ({ store }: { store?: SidePanelStore }) => {
const { t } = useTranslation('rooms', { keyPrefix: 'participantTileFocus' })
const { isEffectsOpen, toggleEffects } = useSidePanel()
const { isEffectsOpen, toggleEffects } = useSidePanel(store)
return (
<Button
size={'sm'}
@@ -132,9 +132,11 @@ const MOUSE_IDLE_TIME = 3000
export const ParticipantTileFocus = ({
trackRef,
hasKeyboardFocus,
sidePanelStore,
}: {
trackRef: TrackReferenceOrPlaceholder
hasKeyboardFocus: boolean
sidePanelStore?: SidePanelStore
}) => {
const [hovered, setHovered] = useState(false)
const [opacity, setOpacity] = useState(0)
@@ -216,7 +218,7 @@ export const ParticipantTileFocus = ({
{!isScreenShare ? (
<>
{participant.isLocal ? (
<EffectsButton />
<EffectsButton store={sidePanelStore} />
) : (
canMute && <MuteButton participant={participant} />
)}