From 3fc4cc908e8d7e1c605d5996ab1a6c0724f0ae8b Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 22 Apr 2025 19:19:40 +0200 Subject: [PATCH] Cleanup + use a better check for blurring support --- src/livekit/TrackProcessorContext.tsx | 89 +++++++++------------------ src/livekit/useLiveKit.ts | 2 +- src/room/LobbyView.tsx | 2 +- src/settings/SettingsModal.tsx | 7 +-- 4 files changed, 33 insertions(+), 67 deletions(-) diff --git a/src/livekit/TrackProcessorContext.tsx b/src/livekit/TrackProcessorContext.tsx index ba94e257..b310e7b3 100644 --- a/src/livekit/TrackProcessorContext.tsx +++ b/src/livekit/TrackProcessorContext.tsx @@ -7,18 +7,10 @@ Please see LICENSE in the repository root for full details. import { ProcessorWrapper, + supportsBackgroundProcessors, type BackgroundOptions, } from "@livekit/track-processors"; -import { - createContext, - type FC, - useCallback, - useContext, - useEffect, - useRef, - useState, -} from "react"; -import { logger } from "matrix-js-sdk/src/logger"; +import { createContext, type FC, useContext, useEffect, useMemo } from "react"; import { type LocalVideoTrack } from "livekit-client"; import { @@ -30,23 +22,23 @@ import { BlurBackgroundTransformer } from "./BlurBackgroundTransformer"; type ProcessorState = { supported: boolean | undefined; processor: undefined | ProcessorWrapper; - /** - * Call this method to try to initialize a processor. - * This only needs to happen if supported is undefined. - * If the backgroundBlur setting is set to true this does not need to be called - * and the processorState.supported will update automatically to the correct value. - */ - checkSupported: () => void; }; + const ProcessorContext = createContext(undefined); -export const useTrackProcessor = (): ProcessorState | undefined => - useContext(ProcessorContext); +export function useTrackProcessor(): ProcessorState { + const state = useContext(ProcessorContext); + if (state === undefined) + throw new Error( + "useTrackProcessor must be used within a ProcessorProvider", + ); + return state; +} export const useTrackProcessorSync = ( videoTrack: LocalVideoTrack | null, ): void => { - const { processor } = useTrackProcessor() || {}; + const { processor } = useTrackProcessor(); useEffect(() => { if (!videoTrack) return; if (processor && !videoTrack.getProcessor()) { @@ -61,53 +53,28 @@ export const useTrackProcessorSync = ( interface Props { children: JSX.Element; } + export const ProcessorProvider: FC = ({ children }) => { // The setting the user wants to have const [blurActivated] = useSetting(backgroundBlurSettings); - - // If `ProcessorState.supported` is undefined the user can activate that we want - // to have it at least checked (this is useful to show the settings menu properly) - // We dont want to try initializing the blur if the user is not even looking at the setting - const [shouldCheckSupport, setShouldCheckSupport] = useState(blurActivated); - - // Cache the processor so we only need to initialize it once. - const blur = useRef | undefined>( - undefined, + const supported = useMemo(() => supportsBackgroundProcessors(), []); + const blur = useMemo( + () => + new ProcessorWrapper( + new BlurBackgroundTransformer({ blurRadius: 15 }), + "background-blur", + ), + [], ); - const checkSupported = useCallback(() => { - setShouldCheckSupport(true); - }, []); // This is the actual state exposed through the context - const [processorState, setProcessorState] = useState(() => ({ - supported: false, - processor: undefined, - checkSupported, - })); - - useEffect(() => { - if (!shouldCheckSupport) return; - try { - if (!blur.current) { - blur.current = new ProcessorWrapper( - new BlurBackgroundTransformer({ blurRadius: 15 }), - "background-blur", - ); - } - setProcessorState({ - checkSupported, - supported: true, - processor: blurActivated ? blur.current : undefined, - }); - } catch (e) { - setProcessorState({ - checkSupported, - supported: false, - processor: undefined, - }); - logger.error("disable background blur", e); - } - }, [blurActivated, checkSupported, shouldCheckSupport]); + const processorState = useMemo( + () => ({ + supported, + processor: supported && blurActivated ? blur : undefined, + }), + [supported, blurActivated, blur], + ); return ( diff --git a/src/livekit/useLiveKit.ts b/src/livekit/useLiveKit.ts index c9bfd78e..f214a203 100644 --- a/src/livekit/useLiveKit.ts +++ b/src/livekit/useLiveKit.ts @@ -88,7 +88,7 @@ export function useLiveKit( const devices = useMediaDevices(); const initialDevices = useRef(devices); - const { processor } = useTrackProcessor() || {}; + const { processor } = useTrackProcessor(); const initialProcessor = useInitial(() => processor); const roomOptions = useMemo( (): RoomOptions => ({ diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index f3739175..e6bf5362 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -120,7 +120,7 @@ export const LobbyView: FC = ({ muteStates.audio.enabled && { deviceId: devices.audioInput.selectedId }, ); - const { processor } = useTrackProcessor() || {}; + const { processor } = useTrackProcessor(); const initialProcessor = useInitial(() => processor); const localTrackOptions = useMemo( diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index 44d06116..b24674dc 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -5,10 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import { type FC, type ReactNode, useEffect, useState } from "react"; +import { type FC, type ReactNode, useState } from "react"; import { useTranslation } from "react-i18next"; import { type MatrixClient } from "matrix-js-sdk"; -import { Root as Form ,Separator} from "@vector-im/compound-web"; +import { Root as Form, Separator } from "@vector-im/compound-web"; import { type Room as LivekitRoom } from "livekit-client"; import { Modal } from "../Modal"; @@ -69,8 +69,7 @@ export const SettingsModal: FC = ({ // Generate a `Checkbox` input to turn blur on or off. const BlurCheckbox: React.FC = (): ReactNode => { - const { supported, checkSupported } = useTrackProcessor() || {}; - useEffect(() => checkSupported?.(), [checkSupported]); + const { supported } = useTrackProcessor(); const [blurActive, setBlurActive] = useSetting(backgroundBlurSetting);