From 9ebfc8ea29693868b20134601db9dc0d04e78103 Mon Sep 17 00:00:00 2001 From: Nathan Vasse Date: Mon, 20 Jan 2025 17:59:53 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(front)=20refactor=20Effects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to have an agnostic component to apply effects on any video track, enters EffectsConfiguration. It takes in input the video track and outputs the processor applied. This is gonna be used in order to use the same component on the pre join screen and the in room customization side panel. --- .../rooms/livekit/components/SidePanel.tsx | 2 +- .../livekit/components/effects/Effects.tsx | 18 ++ .../EffectsConfiguration.tsx} | 215 ++++++++++-------- 3 files changed, 137 insertions(+), 98 deletions(-) create mode 100644 src/frontend/src/features/rooms/livekit/components/effects/Effects.tsx rename src/frontend/src/features/rooms/livekit/components/{Effects.tsx => effects/EffectsConfiguration.tsx} (52%) diff --git a/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx b/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx index 44e5cb1d..49b573e1 100644 --- a/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx +++ b/src/frontend/src/features/rooms/livekit/components/SidePanel.tsx @@ -8,9 +8,9 @@ import { useTranslation } from 'react-i18next' import { ParticipantsList } from './controls/Participants/ParticipantsList' import { useSidePanel } from '../hooks/useSidePanel' import { ReactNode } from 'react' -import { Effects } from './Effects' import { Chat } from '../prefabs/Chat' import { Transcript } from './Transcript' +import { Effects } from './effects/Effects' type StyledSidePanelProps = { title: string diff --git a/src/frontend/src/features/rooms/livekit/components/effects/Effects.tsx b/src/frontend/src/features/rooms/livekit/components/effects/Effects.tsx new file mode 100644 index 00000000..3c2aee55 --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/components/effects/Effects.tsx @@ -0,0 +1,18 @@ +import { useLocalParticipant } from '@livekit/components-react' +import { LocalVideoTrack } from 'livekit-client' +import { css } from '@/styled-system/css' +import { EffectsConfiguration } from './EffectsConfiguration' + +export const Effects = () => { + const { cameraTrack } = useLocalParticipant() + const localCameraTrack = cameraTrack?.track as LocalVideoTrack + return ( +
+ +
+ ) +} diff --git a/src/frontend/src/features/rooms/livekit/components/Effects.tsx b/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx similarity index 52% rename from src/frontend/src/features/rooms/livekit/components/Effects.tsx rename to src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx index bbdc9a0b..235a31b8 100644 --- a/src/frontend/src/features/rooms/livekit/components/Effects.tsx +++ b/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx @@ -1,13 +1,21 @@ +import { LocalVideoTrack, Track, TrackProcessor } from 'livekit-client' import { useEffect, useRef, useState } from 'react' -import { useLocalParticipant } from '@livekit/components-react' -import { LocalVideoTrack } from 'livekit-client' -import { Text, P, ToggleButton, Div, H } from '@/primitives' import { useTranslation } from 'react-i18next' -import { HStack, styled, VStack } from '@/styled-system/jsx' import { BackgroundBlurFactory, BackgroundBlurProcessorInterface, -} from './blur/index' +} from '../blur' +import { css } from '@/styled-system/css' +import { Text, P, ToggleButton, H } from '@/primitives' +import { HStack, styled } from '@/styled-system/jsx' + +enum BlurRadius { + NONE = 0, + LIGHT = 5, + NORMAL = 10, +} + +const isSupported = BackgroundBlurFactory.isSupported() const Information = styled('div', { base: { @@ -19,48 +27,45 @@ const Information = styled('div', { }, }) -enum BlurRadius { - NONE = 0, - LIGHT = 5, - NORMAL = 10, -} - -const isSupported = BackgroundBlurFactory.isSupported() - -export const Effects = () => { - const { t } = useTranslation('rooms', { keyPrefix: 'effects' }) - const { isCameraEnabled, cameraTrack, localParticipant } = - useLocalParticipant() +export const EffectsConfiguration = ({ + videoTrack, + onSubmit, + layout = 'horizontal', +}: { + videoTrack: LocalVideoTrack + onSubmit?: (processor?: TrackProcessor) => void + layout?: 'vertical' | 'horizontal' +}) => { const videoRef = useRef(null) + const { t } = useTranslation('rooms', { keyPrefix: 'effects' }) const [processorPending, setProcessorPending] = useState(false) - const localCameraTrack = cameraTrack?.track as LocalVideoTrack + useEffect(() => { + const videoElement = videoRef.current + if (!videoElement) return - const getProcessor = () => { - return localCameraTrack?.getProcessor() as BackgroundBlurProcessorInterface - } + const attachVideoTrack = async () => videoTrack?.attach(videoElement) + attachVideoTrack() - const getBlurRadius = (): BlurRadius => { - const processor = getProcessor() - return processor?.options.blurRadius || BlurRadius.NONE - } + return () => { + if (!videoElement) return + videoTrack.detach(videoElement) + } + }, [videoTrack, videoTrack?.isMuted]) const toggleBlur = async (blurRadius: number) => { - if (!isCameraEnabled) await localParticipant.setCameraEnabled(true) - if (!localCameraTrack) return - + if (!videoTrack) return setProcessorPending(true) - const processor = getProcessor() const currentBlurRadius = getBlurRadius() - try { if (blurRadius == currentBlurRadius && processor) { - await localCameraTrack.stopProcessor() + await videoTrack.stopProcessor() + onSubmit?.(undefined) } else if (!processor) { - await localCameraTrack.setProcessor( - BackgroundBlurFactory.getProcessor({ blurRadius })! - ) + const newProcessor = BackgroundBlurFactory.getProcessor({ blurRadius })! + await videoTrack.setProcessor(newProcessor) + onSubmit?.(newProcessor) } else { processor?.update({ blurRadius }) } @@ -71,21 +76,17 @@ export const Effects = () => { } } - useEffect(() => { - const videoElement = videoRef.current - if (!videoElement) return + const getProcessor = () => { + return videoTrack?.getProcessor() as BackgroundBlurProcessorInterface + } - const attachVideoTrack = async () => localCameraTrack?.attach(videoElement) - attachVideoTrack() - - return () => { - if (!videoElement) return - localCameraTrack.detach(videoElement) - } - }, [localCameraTrack, isCameraEnabled]) + const getBlurRadius = (): BlurRadius => { + const processor = getProcessor() + return processor?.options.blurRadius || BlurRadius.NONE + } const isSelected = (blurRadius: BlurRadius) => { - return isCameraEnabled && getBlurRadius() == blurRadius + return getBlurRadius() == blurRadius } const tooltipLabel = (blurRadius: BlurRadius) => { @@ -93,55 +94,82 @@ export const Effects = () => { } return ( - - {localCameraTrack && isCameraEnabled ? ( -