diff --git a/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsButton.tsx b/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsButton.tsx index 715dcd30..8b56a951 100644 --- a/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsButton.tsx +++ b/src/frontend/src/features/rooms/livekit/components/controls/Options/OptionsButton.tsx @@ -2,9 +2,49 @@ import { useTranslation } from 'react-i18next' import { RiMoreFill } from '@remixicon/react' import { Button, Menu } from '@/primitives' import { OptionsMenuItems } from './OptionsMenuItems' +import { useOverlayPortalContainer } from '@/primitives/useOverlayPortalContainer' +import { useEffect, useRef, useState } from 'react' +import { PipOptionsMenu } from './PipOptionsMenu' export const OptionsButton = () => { const { t } = useTranslation('rooms') + const portalContainer = useOverlayPortalContainer() + const isInPiP = + portalContainer && portalContainer.ownerDocument !== document + const [isOpen, setIsOpen] = useState(false) + const wrapperRef = useRef(null) + + useEffect(() => { + if (!isOpen || !isInPiP) return + const doc = wrapperRef.current?.ownerDocument ?? document + + const handlePointerDown = (event: PointerEvent) => { + const target = event.target as Node | null + const wrapper = wrapperRef.current + if (!wrapper || !target) return + if (!wrapper.contains(target)) { + setIsOpen(false) + } + } + + doc.addEventListener('pointerdown', handlePointerDown, true) + return () => { + doc.removeEventListener('pointerdown', handlePointerDown, true) + } + }, [isInPiP, isOpen]) + + + + if (isInPiP) { + return ( + + ) + } return ( 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 new file mode 100644 index 00000000..a2e42b22 --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/components/controls/Options/PipOptionsMenu.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import { RiMoreFill } from '@remixicon/react' +import { Box, Button } from '@/primitives' +import { css } from '@/styled-system/css' +import { OptionsMenuItems } from './OptionsMenuItems' + +type PipOptionsMenuProps = { + wrapperRef: React.RefObject + isOpen: boolean + setIsOpen: (isOpen: boolean) => void + label: string +} + +export const PipOptionsMenu = ({ + wrapperRef, + isOpen, + setIsOpen, + label, +}: PipOptionsMenuProps) => { + return ( +
+ + {isOpen && ( +
+ + + +
+ )} +
+ ) +} \ No newline at end of file