🐛(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 type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { styled } from '@/styled-system/jsx' import { styled } from '@/styled-system/jsx'
import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile' import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile'
import { pipLayoutStore } from '../../stores/pipLayoutStore'
import { getTrackKey } from '../../utils/pipTrackSelection' import { getTrackKey } from '../../utils/pipTrackSelection'
type PipFocusLayoutProps = { type PipFocusLayoutProps = {
@@ -25,6 +26,7 @@ export const PipFocusLayout = memo(
<ParticipantTile <ParticipantTile
key={getTrackKey(mainTrack)} key={getTrackKey(mainTrack)}
trackRef={mainTrack} trackRef={mainTrack}
sidePanelStore={pipLayoutStore}
/> />
</MainSlot> </MainSlot>
{thumbnailTrack && ( {thumbnailTrack && (
@@ -32,6 +34,7 @@ export const PipFocusLayout = memo(
<ParticipantTile <ParticipantTile
key={getTrackKey(thumbnailTrack)} key={getTrackKey(thumbnailTrack)}
trackRef={thumbnailTrack} trackRef={thumbnailTrack}
sidePanelStore={pipLayoutStore}
/> />
</Thumbnail> </Thumbnail>
)} )}
@@ -2,6 +2,7 @@ import { memo, useMemo, useRef } from 'react'
import type { TrackReferenceOrPlaceholder } from '@livekit/components-core' import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { styled } from '@/styled-system/jsx' import { styled } from '@/styled-system/jsx'
import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile' import { ParticipantTile } from '@/features/rooms/livekit/components/ParticipantTile'
import { pipLayoutStore } from '../../stores/pipLayoutStore'
import { usePipElementSize } from '../../hooks/usePipElementSize' import { usePipElementSize } from '../../hooks/usePipElementSize'
import { usePipFlipAnimations } from '../../hooks/usePipFlipAnimations' import { usePipFlipAnimations } from '../../hooks/usePipFlipAnimations'
import { computePipGridLayout } from '../../utils/pipGrid' import { computePipGridLayout } from '../../utils/pipGrid'
@@ -46,7 +47,7 @@ export const PipGridLayout = memo(({ tracks }: PipGridLayoutProps) => {
<GridContainer ref={containerRef} style={gridStyle}> <GridContainer ref={containerRef} style={gridStyle}>
{tracks.map((track, index) => ( {tracks.map((track, index) => (
<GridCell key={tileKeys[index]} style={placements[index]}> <GridCell key={tileKeys[index]} style={placements[index]}>
<ParticipantTile trackRef={track} /> <ParticipantTile trackRef={track} sidePanelStore={pipLayoutStore} />
</GridCell> </GridCell>
))} ))}
</GridContainer> </GridContainer>
@@ -27,6 +27,7 @@ import { HStack } from '@/styled-system/jsx'
import { MutedMicIndicator } from './MutedMicIndicator' import { MutedMicIndicator } from './MutedMicIndicator'
import { ParticipantPlaceholder } from './ParticipantPlaceholder' import { ParticipantPlaceholder } from './ParticipantPlaceholder'
import { ParticipantTileFocus } from './ParticipantTileFocus' import { ParticipantTileFocus } from './ParticipantTileFocus'
import type { SidePanelStore } from '../hooks/useSidePanel'
import { FullScreenShareWarning } from './FullScreenShareWarning' import { FullScreenShareWarning } from './FullScreenShareWarning'
import { ParticipantName } from './ParticipantName' import { ParticipantName } from './ParticipantName'
import { getParticipantName } from '@/features/rooms/utils/getParticipantName' import { getParticipantName } from '@/features/rooms/utils/getParticipantName'
@@ -52,6 +53,7 @@ export function TrackRefContextIfNeeded(
interface ParticipantTileExtendedProps extends ParticipantTileProps { interface ParticipantTileExtendedProps extends ParticipantTileProps {
disableMetadata?: boolean disableMetadata?: boolean
sidePanelStore?: SidePanelStore
} }
export const ParticipantTile: ( export const ParticipantTile: (
@@ -66,6 +68,7 @@ export const ParticipantTile: (
onParticipantClick, onParticipantClick,
disableSpeakingIndicator, disableSpeakingIndicator,
disableMetadata, disableMetadata,
sidePanelStore,
...htmlProps ...htmlProps
}: ParticipantTileExtendedProps, }: ParticipantTileExtendedProps,
ref ref
@@ -235,6 +238,7 @@ export const ParticipantTile: (
<ParticipantTileFocus <ParticipantTileFocus
trackRef={trackReference} trackRef={trackReference}
hasKeyboardFocus={hasKeyboardFocus} hasKeyboardFocus={hasKeyboardFocus}
sidePanelStore={sidePanelStore}
/> />
)} )}
</ParticipantContextIfNeeded> </ParticipantContextIfNeeded>
@@ -16,7 +16,7 @@ import {
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { TrackReferenceOrPlaceholder } from '@livekit/components-core' import { TrackReferenceOrPlaceholder } from '@livekit/components-core'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { useSidePanel } from '../hooks/useSidePanel' import { type SidePanelStore, useSidePanel } from '../hooks/useSidePanel'
import { useFullScreen } from '../hooks/useFullScreen' import { useFullScreen } from '../hooks/useFullScreen'
import { Participant, Track } from 'livekit-client' import { Participant, Track } from 'livekit-client'
import { MuteAlertDialog } from './MuteAlertDialog' import { MuteAlertDialog } from './MuteAlertDialog'
@@ -74,9 +74,9 @@ const FocusButton = ({
) )
} }
const EffectsButton = () => { const EffectsButton = ({ store }: { store?: SidePanelStore }) => {
const { t } = useTranslation('rooms', { keyPrefix: 'participantTileFocus' }) const { t } = useTranslation('rooms', { keyPrefix: 'participantTileFocus' })
const { isEffectsOpen, toggleEffects } = useSidePanel() const { isEffectsOpen, toggleEffects } = useSidePanel(store)
return ( return (
<Button <Button
size={'sm'} size={'sm'}
@@ -132,9 +132,11 @@ const MOUSE_IDLE_TIME = 3000
export const ParticipantTileFocus = ({ export const ParticipantTileFocus = ({
trackRef, trackRef,
hasKeyboardFocus, hasKeyboardFocus,
sidePanelStore,
}: { }: {
trackRef: TrackReferenceOrPlaceholder trackRef: TrackReferenceOrPlaceholder
hasKeyboardFocus: boolean hasKeyboardFocus: boolean
sidePanelStore?: SidePanelStore
}) => { }) => {
const [hovered, setHovered] = useState(false) const [hovered, setHovered] = useState(false)
const [opacity, setOpacity] = useState(0) const [opacity, setOpacity] = useState(0)
@@ -216,7 +218,7 @@ export const ParticipantTileFocus = ({
{!isScreenShare ? ( {!isScreenShare ? (
<> <>
{participant.isLocal ? ( {participant.isLocal ? (
<EffectsButton /> <EffectsButton store={sidePanelStore} />
) : ( ) : (
canMute && <MuteButton participant={participant} /> canMute && <MuteButton participant={participant} />
)} )}