diff --git a/src/frontend/public/assets/pip.svg b/src/frontend/public/assets/pip.svg new file mode 100644 index 00000000..fb2b64c4 --- /dev/null +++ b/src/frontend/public/assets/pip.svg @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/src/features/pip/components/PipRoomPlaceholder.tsx b/src/frontend/src/features/pip/components/PipRoomPlaceholder.tsx new file mode 100644 index 00000000..8cc381a9 --- /dev/null +++ b/src/frontend/src/features/pip/components/PipRoomPlaceholder.tsx @@ -0,0 +1,48 @@ +import { useTranslation } from 'react-i18next' +import { styled } from '@/styled-system/jsx' +import { usePictureInPicture } from '../hooks/usePictureInPicture' +import { Button, Text } from '@/primitives' + +export const PipRoomPlaceholder = () => { + const { t } = useTranslation('rooms', { + keyPrefix: 'pictureInPicture.placeholder', + }) + const { close } = usePictureInPicture() + + return ( + + + {t('title')} + + {t('description')} + + + + ) +} + +const Container = styled('div', { + base: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + width: '100%', + height: '100%', + gap: '0.5rem', + padding: '1.5rem', + textAlign: 'center', + color: 'white', + }, +}) diff --git a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx index fb5b763a..8545ef83 100644 --- a/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx +++ b/src/frontend/src/features/rooms/livekit/prefabs/VideoConference.tsx @@ -41,6 +41,8 @@ import { ReactionPortals } from '@/features/reactions/components/ReactionPortals import { CarouselLayout } from '@/features/layout/components/CarouselLayout' import { GridLayout } from '@/features/layout/components/GridLayout' import { RoomContentArea } from '@/features/layout/components/RoomContentArea' +import { usePictureInPicture } from '@/features/pip/hooks/usePictureInPicture' +import { PipRoomPlaceholder } from '@/features/pip/components/PipRoomPlaceholder' /** * @public @@ -121,6 +123,8 @@ export function VideoConference({ ...props }: VideoConferenceProps) { (track) => !isEqualTrackRef(track, focusTrack) ) + const { isOpen: isPictureInPictureOpen } = usePictureInPicture() + // handle pin announcements useEffect(() => { @@ -250,32 +254,38 @@ export function VideoConference({ ...props }: VideoConferenceProps) { /> - {!focusTrack ? ( -
- - - -
+ {isPictureInPictureOpen ? ( + ) : ( -
- - + {!focusTrack ? ( +
- - - {focusTrack && } - -
+ + + +
+ ) : ( +
+ + + + + {focusTrack && } + +
+ )} + )}