From bbc73d073bb52670e225f408124ab3fb45a3ed68 Mon Sep 17 00:00:00 2001 From: fkwp Date: Thu, 8 Oct 2026 11:43:01 +0200 Subject: [PATCH] Name the background effect pieces after background effects - One name, as review asked: TrackProcessorContext becomes BackgroundEffectsContext, with BackgroundEffectsProvider, BackgroundEffectsState, useBackgroundEffects, useBackgroundEffectsState$ and useSyncBackgroundEffects. - The state's Behavior is backgroundEffectsState$ wherever it is passed, in place of trackProcessorState$, trackerProcessorState$ and processorState$. - Renames only: nothing changes in behaviour. Rebased onto main: the context lives in src/tracks, main's fromLivekitProcessor keeps its name, and the Publisher, ConnectionFactory and their tests this renamed in are gone, as main moved them into the SDK. Co-Authored-By: Claude Opus 5.5 (1M context) --- component/index.tsx | 6 +-- src/App.tsx | 6 +-- src/room/CallView.test.tsx | 6 +-- src/room/InCallView.test.tsx | 10 ++--- src/room/InCallView.tsx | 12 +++--- src/room/KnockLobbyView.test.tsx | 8 ++-- src/room/LobbyView.test.tsx | 8 ++-- src/room/LobbyView.tsx | 10 ++--- src/settings/SettingsModal.tsx | 4 +- src/state/BackgroundEffects.test.ts | 4 +- src/state/BackgroundEffects.ts | 8 ++-- ...st.ts => BackgroundEffectsContext.test.ts} | 28 +++++++------- ...ntext.tsx => BackgroundEffectsContext.tsx} | 38 ++++++++++--------- 13 files changed, 76 insertions(+), 72 deletions(-) rename src/tracks/{TrackProcessorContext.test.ts => BackgroundEffectsContext.test.ts} (94%) rename src/tracks/{TrackProcessorContext.tsx => BackgroundEffectsContext.tsx} (81%) diff --git a/component/index.tsx b/component/index.tsx index 4a4b4d8cf..bf5b7b797 100644 --- a/component/index.tsx +++ b/component/index.tsx @@ -74,7 +74,7 @@ import { import { MediaDevicesContext } from "../src/MediaDevicesContext"; import { MediaDevices } from "../src/state/MediaDevices"; import { ObservableScope } from "../src/state/ObservableScope"; -import { ProcessorProvider } from "../src/tracks/TrackProcessorContext"; +import { BackgroundEffectsProvider } from "../src/tracks/BackgroundEffectsContext"; import { Config } from "../src/config/Config"; import { type ConfigOptions } from "../src/config/ConfigOptions"; import { i18n } from "../src/utils/i18n"; @@ -255,7 +255,7 @@ export const ElementCall: FC = ({ - + = ({ preload={params.preload} skipLobby={params.skipLobby} /> - + diff --git a/src/App.tsx b/src/App.tsx index a92d56b59..8b3980d8b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -35,7 +35,7 @@ import { ErrorPage, LoadingPage } from "./FullScreenView"; import { Initializer } from "./initializer"; import { type WidgetHelpers } from "./widget"; import { useTheme } from "./useTheme"; -import { ProcessorProvider } from "./tracks/TrackProcessorContext"; +import { BackgroundEffectsProvider } from "./tracks/BackgroundEffectsContext"; import { type AppViewModel } from "./state/AppViewModel"; import { MediaDevicesContext } from "./MediaDevicesContext"; import { @@ -148,7 +148,7 @@ export const App: FC = ({ vm, widget }) => { loaded && clientReady ? ( - + } > @@ -159,7 +159,7 @@ export const App: FC = ({ vm, widget }) => { } /> - + ) : ( diff --git a/src/room/CallView.test.tsx b/src/room/CallView.test.tsx index 2c2208c56..1e242d5df 100644 --- a/src/room/CallView.test.tsx +++ b/src/room/CallView.test.tsx @@ -61,7 +61,7 @@ import { } from "../HostBridge"; import { type JoinCallData } from "../widget"; import { MatrixRTCTransportMissingError } from "../utils/errors"; -import { ProcessorProvider } from "../tracks/TrackProcessorContext"; +import { BackgroundEffectsProvider } from "../tracks/BackgroundEffectsContext"; import { MediaDevicesContext } from "../MediaDevicesContext"; import { constant } from "../state/Behavior"; @@ -193,7 +193,7 @@ function createCallView( - + {options.withErrorBoundary ? ( {callView} @@ -201,7 +201,7 @@ function createCallView( ) : ( callView )} - + diff --git a/src/room/InCallView.test.tsx b/src/room/InCallView.test.tsx index 209fcc113..edf09f6f7 100644 --- a/src/room/InCallView.test.tsx +++ b/src/room/InCallView.test.tsx @@ -48,7 +48,7 @@ import { MediaDevicesContext } from "../MediaDevicesContext"; import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices"; import { AppBar } from "../AppBar"; import { type MatrixInfo } from "./VideoPreview"; -import { ProcessorProvider } from "../tracks/TrackProcessorContext"; +import { BackgroundEffectsProvider } from "../tracks/BackgroundEffectsContext"; import { initializeWidget } from "../widget"; import { RootElementProvider } from "../RootElementContext"; @@ -234,7 +234,7 @@ describe("ActiveCall", () => { const { findByTestId } = render( - + { onLeft={(): void => {}} /> - + , ); @@ -282,7 +282,7 @@ describe("ActiveCall", () => { - + { onLeft={(): void => {}} /> - + , diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 9caba2841..96d1eb6aa 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -109,7 +109,7 @@ import { useBehavior } from "../useBehavior.ts"; import { useValueBehavior } from "../useValueBehavior.ts"; import { Toast } from "../Toast.tsx"; import overlayStyles from "../Overlay.module.css"; -import { useTrackProcessorState$ } from "../tracks/TrackProcessorContext.tsx"; +import { useBackgroundEffectsState$ } from "../tracks/BackgroundEffectsContext.tsx"; import { type Layout } from "../state/layout-types.ts"; import { ObservableScope } from "../state/ObservableScope.ts"; import { CallFooter, type FooterSnapshot } from "../components/CallFooter.tsx"; @@ -150,7 +150,7 @@ export const ActiveCall: FC = (props) => { const urlParams = useUrlParams(); const hostBridge = useHostBridge(); const mediaDevices = useMediaDevices(); - const trackProcessorState$ = useTrackProcessorState$(); + const backgroundEffectsState$ = useBackgroundEffectsState$(); // The element we have to draw the call in: the page, or the container a host // gave us. Its size, not the window's, decides how the call is laid out. const rootElement = useRootElement(); @@ -174,7 +174,7 @@ export const ActiveCall: FC = (props) => { props.muteStates, mediaDevices, capture, - trackProcessorState$.value.processor, + backgroundEffectsState$.value.processor, ), }); @@ -189,7 +189,7 @@ export const ActiveCall: FC = (props) => { encryptionSystem: props.e2eeSystem, capture, videoProcessor$: scope.behavior( - trackProcessorState$.pipe(map((state) => state.processor)), + backgroundEffectsState$.pipe(map((state) => state.processor)), ), hostBridge, autoLeaveWhenOthersLeft, @@ -219,7 +219,7 @@ export const ActiveCall: FC = (props) => { urlParams, hostBridge, mediaDevices, - trackProcessorState$, + backgroundEffectsState$, props.client, rootElement, ]); @@ -250,7 +250,7 @@ export const ActiveCall: FC = (props) => { props.onLeft, urlParams, mediaDevices, - trackProcessorState$, + backgroundEffectsState$, props.client, vm, ]); diff --git a/src/room/KnockLobbyView.test.tsx b/src/room/KnockLobbyView.test.tsx index fda9cee06..0bfb76c2c 100644 --- a/src/room/KnockLobbyView.test.tsx +++ b/src/room/KnockLobbyView.test.tsx @@ -14,19 +14,19 @@ import { type MatrixClient, type RoomSummary } from "matrix-js-sdk"; import { KnockLobbyView } from "./KnockLobbyView"; import { LeaveToHomeProvider } from "../LeaveToHomeContext"; import { MediaDevicesContext } from "../MediaDevicesContext"; -import { type ProcessorState } from "../tracks/TrackProcessorContext"; +import { type BackgroundEffectsState } from "../tracks/BackgroundEffectsContext"; import { mockMediaDevices } from "../utils/test"; vi.mock("@livekit/components-react", () => ({ usePreviewTracks: (): unknown[] => [], })); -vi.mock("../tracks/TrackProcessorContext", () => ({ - useTrackProcessor: (): ProcessorState => ({ +vi.mock("../tracks/BackgroundEffectsContext", () => ({ + useBackgroundEffects: (): BackgroundEffectsState => ({ supported: false, processor: undefined, }), - useTrackProcessorSync: (): void => {}, + useSyncBackgroundEffects: (): void => {}, })); vi.mock("react-use-measure", () => ({ diff --git a/src/room/LobbyView.test.tsx b/src/room/LobbyView.test.tsx index fbe4248e7..ab6bc581e 100644 --- a/src/room/LobbyView.test.tsx +++ b/src/room/LobbyView.test.tsx @@ -28,7 +28,7 @@ import { } from "../utils/test"; import { type MediaDevices } from "../state/MediaDevices"; import { MediaDevicesContext } from "../MediaDevicesContext"; -import { type ProcessorState } from "../tracks/TrackProcessorContext"; +import { type BackgroundEffectsState } from "../tracks/BackgroundEffectsContext"; import { type EncryptionSystem } from "../e2ee/sharedKeyManagement"; import lobbyStyles from "./LobbyView.module.css"; import headerStyles from "../Header.module.css"; @@ -41,12 +41,12 @@ vi.mock("@livekit/components-react", () => ({ usePreviewTracks: (): unknown[] => [], })); -vi.mock("../tracks/TrackProcessorContext", () => ({ - useTrackProcessor: (): ProcessorState => ({ +vi.mock("../tracks/BackgroundEffectsContext", () => ({ + useBackgroundEffects: (): BackgroundEffectsState => ({ supported: false, processor: undefined, }), - useTrackProcessorSync: (): void => {}, + useSyncBackgroundEffects: (): void => {}, })); vi.mock("react-use-measure", () => ({ diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index 660e06953..b7c283b7f 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -41,9 +41,9 @@ import { useMediaDevices } from "../MediaDevicesContext"; import { ObservableScope } from "../state/ObservableScope"; import { useInitial } from "../useInitial"; import { - useTrackProcessor, - useTrackProcessorSync, -} from "../tracks/TrackProcessorContext"; + useBackgroundEffects, + useSyncBackgroundEffects, +} from "../tracks/BackgroundEffectsContext"; import { getValue } from "../utils/observable"; import { useBehavior } from "../useBehavior"; import { CallFooter, type FooterSnapshot } from "../components/CallFooter"; @@ -137,7 +137,7 @@ export const LobbyView: FC = ({ }, ); - const { processor } = useTrackProcessor(); + const { processor } = useBackgroundEffects(); const initialProcessor = useInitial(() => processor); const localTrackOptions = useMemo( @@ -185,7 +185,7 @@ export const LobbyView: FC = ({ } }, [devices, videoInputId, videoTrack]); - useTrackProcessorSync(videoTrack); + useSyncBackgroundEffects(videoTrack); const [footerVm, setFooterVm] = useState | null>( null, diff --git a/src/settings/SettingsModal.tsx b/src/settings/SettingsModal.tsx index 7c1e79271..f962281fd 100644 --- a/src/settings/SettingsModal.tsx +++ b/src/settings/SettingsModal.tsx @@ -27,7 +27,7 @@ import { import { PreferencesSettingsTab } from "./PreferencesSettingsTab"; import { Slider } from "../Slider"; import { DeviceSelection } from "./DeviceSelection"; -import { useTrackProcessor } from "../tracks/TrackProcessorContext"; +import { useBackgroundEffects } from "../tracks/BackgroundEffectsContext"; import { DeveloperSettingsTab, type DeveloperSettingsSnapshot, @@ -78,7 +78,7 @@ export const SettingsModal: FC = ({ // Generate a `Checkbox` input to turn blur on or off. const BlurCheckbox: React.FC = (): ReactNode => { - const { supported } = useTrackProcessor(); + const { supported } = useBackgroundEffects(); const [blurActive, setBlurActive] = useSetting(backgroundBlurSetting); diff --git a/src/state/BackgroundEffects.test.ts b/src/state/BackgroundEffects.test.ts index 7319f11b5..a4d037258 100644 --- a/src/state/BackgroundEffects.test.ts +++ b/src/state/BackgroundEffects.test.ts @@ -13,7 +13,7 @@ import { BackgroundEffects, type BackgroundEffectsOptions, } from "./BackgroundEffects"; -import { type ProcessorState } from "../tracks/TrackProcessorContext"; +import { type BackgroundEffectsState } from "../tracks/BackgroundEffectsContext"; import { flushPromises, testScope, withTestScheduler } from "../utils/test"; /** A pipeline that records what it is switched to. */ @@ -45,7 +45,7 @@ function fakePipeline(): { } /** One letter per state: idle, attached. */ -function letter(state: ProcessorState): string { +function letter(state: BackgroundEffectsState): string { return state.processor === undefined ? "i" : "a"; } diff --git a/src/state/BackgroundEffects.ts b/src/state/BackgroundEffects.ts index 353c4aac3..ddc9f7a8c 100644 --- a/src/state/BackgroundEffects.ts +++ b/src/state/BackgroundEffects.ts @@ -17,8 +17,8 @@ import { type Behavior } from "./Behavior"; import { type ObservableScope } from "./ObservableScope"; import { fromLivekitProcessor, - type ProcessorState, -} from "../tracks/TrackProcessorContext"; + type BackgroundEffectsState, +} from "../tracks/BackgroundEffectsContext"; const blurRadius = 15; @@ -33,7 +33,7 @@ export interface BackgroundEffectsOptions { /** The background effect pipeline, as the camera tracks and the menus see it. */ export class BackgroundEffects { - public readonly state$: Behavior; + public readonly state$: Behavior; public constructor( scope: ObservableScope, @@ -43,7 +43,7 @@ export class BackgroundEffects { const processor = fromLivekitProcessor(pipeline); this.state$ = scope.behavior( blur$.pipe( - scan( + scan( (previous, wanted) => { // Attached the first time an effect is wanted and never detached // after, so someone who never turns one on pays for none of it. diff --git a/src/tracks/TrackProcessorContext.test.ts b/src/tracks/BackgroundEffectsContext.test.ts similarity index 94% rename from src/tracks/TrackProcessorContext.test.ts rename to src/tracks/BackgroundEffectsContext.test.ts index cf6ede33a..1d0fb53c1 100644 --- a/src/tracks/TrackProcessorContext.test.ts +++ b/src/tracks/BackgroundEffectsContext.test.ts @@ -21,12 +21,12 @@ import { import { applyProcessor, fromLivekitProcessor, - ProcessorProvider, - type ProcessorState, - trackProcessorSync, - useTrackProcessor, - useTrackProcessorSync, -} from "./TrackProcessorContext"; + BackgroundEffectsProvider, + type BackgroundEffectsState, + syncBackgroundEffects, + useBackgroundEffects, + useSyncBackgroundEffects, +} from "./BackgroundEffectsContext"; import { backgroundBlur } from "../settings/settings"; import { constant } from "../state/Behavior"; import { flushPromises, testScope } from "../utils/test"; @@ -119,10 +119,10 @@ describe("applyProcessor", () => { }); }); -describe("trackProcessorSync", () => { +describe("syncBackgroundEffects", () => { it("applies the processor to the current track", () => { const track = mockTrack("live"); - trackProcessorSync( + syncBackgroundEffects( testScope(), constant(track), constant({ supported: true, processor }), @@ -170,7 +170,7 @@ describe("fromLivekitProcessor", () => { }); }); -describe("ProcessorProvider", () => { +describe("BackgroundEffectsProvider", () => { /** A camera track that holds whatever processor it is given. */ function cameraTrack(): LocalVideoTrack { let current: unknown; @@ -188,17 +188,17 @@ describe("ProcessorProvider", () => { } as unknown as LocalVideoTrack; } - let seen: ProcessorState[]; + let seen: BackgroundEffectsState[]; const Surface: FC<{ track: LocalVideoTrack | null }> = ({ track }) => { - seen.push(useTrackProcessor()); - useTrackProcessorSync(track); + seen.push(useBackgroundEffects()); + useSyncBackgroundEffects(track); return null; }; // One component for every render, so a rerender updates the tree rather than // mounting a second provider with a pipeline of its own. const Surfaces: FC<{ tracks: (LocalVideoTrack | null)[] }> = ({ tracks }) => createElement( - ProcessorProvider, + BackgroundEffectsProvider, null, createElement( "div", @@ -215,7 +215,7 @@ describe("ProcessorProvider", () => { await flushPromises(); }); }; - const latest = (): ProcessorState => seen[seen.length - 1]; + const latest = (): BackgroundEffectsState => seen[seen.length - 1]; beforeEach(() => { seen = []; diff --git a/src/tracks/TrackProcessorContext.tsx b/src/tracks/BackgroundEffectsContext.tsx similarity index 81% rename from src/tracks/TrackProcessorContext.tsx rename to src/tracks/BackgroundEffectsContext.tsx index e0059b41c..ddd497651 100644 --- a/src/tracks/TrackProcessorContext.tsx +++ b/src/tracks/BackgroundEffectsContext.tsx @@ -39,7 +39,7 @@ import { useBehavior } from "../useBehavior"; // it is a combination of exposing observable and react hooks. // preferably we should not make this a context anymore and instead just a vm? -export type ProcessorState = { +export type BackgroundEffectsState = { supported: boolean | undefined; processor: undefined | VideoProcessor; }; @@ -71,19 +71,19 @@ export function fromLivekitProcessor( }; } -const ProcessorContext = createContext( +const BackgroundEffectsContext = createContext( undefined, ); -export function useTrackProcessor(): ProcessorState { - return useBehavior(useTrackProcessorState$()); +export function useBackgroundEffects(): BackgroundEffectsState { + return useBehavior(useBackgroundEffectsState$()); } -export function useTrackProcessorState$(): Behavior { - const effects = use(ProcessorContext); +export function useBackgroundEffectsState$(): Behavior { + const effects = use(BackgroundEffectsContext); if (effects === undefined) throw new Error( - "useTrackProcessor must be used within a ProcessorProvider", + "useBackgroundEffects must be used within a BackgroundEffectsProvider", ); return effects.state$; } @@ -122,24 +122,24 @@ export function applyProcessor( /** * Updates your video tracks to always use the given processor. */ -export const trackProcessorSync = ( +export const syncBackgroundEffects = ( scope: ObservableScope, videoTrack$: Behavior, - processor$: Behavior, + backgroundEffectsState$: Behavior, ): void => { - combineLatest([videoTrack$, processor$]) + combineLatest([videoTrack$, backgroundEffectsState$]) .pipe(scope.bind()) - .subscribe(([videoTrack, processorState]) => { - if (!processorState) return; + .subscribe(([videoTrack, backgroundEffectsState]) => { + if (!backgroundEffectsState) return; if (!videoTrack) return; - applyProcessor(videoTrack, processorState.processor); + applyProcessor(videoTrack, backgroundEffectsState.processor); }); }; -export const useTrackProcessorSync = ( +export const useSyncBackgroundEffects = ( videoTrack: LocalVideoTrack | null, ): void => { - const { processor } = useTrackProcessor(); + const { processor } = useBackgroundEffects(); useEffect(() => { if (!videoTrack) return; applyProcessor(videoTrack, processor); @@ -150,7 +150,7 @@ interface Props { children: JSX.Element; } -export const ProcessorProvider: FC = ({ children }) => { +export const BackgroundEffectsProvider: FC = ({ children }) => { const [effects, setEffects] = useState(null); useEffect(() => { const scope = new ObservableScope(); @@ -168,5 +168,9 @@ export const ProcessorProvider: FC = ({ children }) => { }, []); if (effects === null) return null; - return {children}; + return ( + + {children} + + ); };