From 394b4b24c4c6277b1d4ef1cf3ab5321b6c800bc0 Mon Sep 17 00:00:00 2001 From: Wojciech Kozyra Date: Thu, 29 Aug 2024 13:42:03 +0200 Subject: [PATCH] [ts-sdk] Assign `ComponentId` automatically with `useId` hook (#704) --- ts/examples/src/dynamic-inputs.tsx | 4 +--- ts/live-compositor/src/component.ts | 23 +++++++++---------- ts/live-compositor/src/components/Image.ts | 6 ++--- .../src/components/InputStream.ts | 6 ++--- ts/live-compositor/src/components/Rescaler.ts | 10 ++------ ts/live-compositor/src/components/Shader.ts | 10 ++------ ts/live-compositor/src/components/Text.ts | 6 ++--- ts/live-compositor/src/components/Tiles.ts | 10 ++------ ts/live-compositor/src/components/View.ts | 10 ++------ ts/live-compositor/src/components/WebView.ts | 10 ++------ ts/package.json | 1 + 11 files changed, 29 insertions(+), 67 deletions(-) diff --git a/ts/examples/src/dynamic-inputs.tsx b/ts/examples/src/dynamic-inputs.tsx index f4b9f26ed..7cd692ac9 100644 --- a/ts/examples/src/dynamic-inputs.tsx +++ b/ts/examples/src/dynamic-inputs.tsx @@ -1,14 +1,12 @@ import LiveCompositor from '@live-compositor/node'; import { useInputStreams, Text, InputStream, Tiles, Rescaler, View } from 'live-compositor'; import { downloadAllAssets, ffplayStartPlayerAsync, sleep } from './utils'; -import { useId } from 'react'; import path from 'path'; function ExampleApp() { const inputs = useInputStreams(); - const id = useId(); return ( - + {inputs .filter(input => input.videoState === 'playing') .map(input => ( diff --git a/ts/live-compositor/src/component.ts b/ts/live-compositor/src/component.ts index 19cb58f8a..82f7c9167 100644 --- a/ts/live-compositor/src/component.ts +++ b/ts/live-compositor/src/component.ts @@ -1,26 +1,27 @@ -import React from 'react'; +import React, { useId } from 'react'; import * as Api from './api'; -type ComponentProps

= { children?: React.ReactNode } & P; +type ComponentProps

= { children?: React.ReactNode; id?: Api.ComponentId } & P; export type SceneComponent = Api.Component | string; export type SceneBuilder

= (props: P, children: SceneComponent[]) => Api.Component; -abstract class LiveCompositorComponent

extends React.Component> { - abstract builder: SceneBuilder

; - - render(): React.ReactNode { - const { children, ...props } = this.props; +export function createCompositorComponent

( + sceneBuilder: SceneBuilder

+): (props: ComponentProps

) => React.ReactNode { + return (props: ComponentProps

): React.ReactNode => { + const { children, ...otherProps } = props; + const autoId = useId(); return React.createElement( 'compositor', { - sceneBuilder: this.builder, - props, + sceneBuilder, + props: { ...otherProps, id: otherProps.id ?? autoId }, }, ...(Array.isArray(children) ? children : [children]) ); - } + }; } export function sceneComponentIntoApi(component: SceneComponent): Api.Component { @@ -33,5 +34,3 @@ export function sceneComponentIntoApi(component: SceneComponent): Api.Component } return component; } - -export default LiveCompositorComponent; diff --git a/ts/live-compositor/src/components/Image.ts b/ts/live-compositor/src/components/Image.ts index b6caa0463..74b359a4a 100644 --- a/ts/live-compositor/src/components/Image.ts +++ b/ts/live-compositor/src/components/Image.ts @@ -1,5 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { SceneBuilder, SceneComponent } from '../component'; +import { createCompositorComponent, SceneComponent } from '../component'; export type ImageProps = { children?: undefined; @@ -14,9 +14,7 @@ export type ImageProps = { imageId: Api.RendererId; }; -class Image extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const Image = createCompositorComponent(sceneBuilder); function sceneBuilder(props: ImageProps, _children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/InputStream.ts b/ts/live-compositor/src/components/InputStream.ts index c708fe022..2f46f0c69 100644 --- a/ts/live-compositor/src/components/InputStream.ts +++ b/ts/live-compositor/src/components/InputStream.ts @@ -1,5 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { SceneBuilder, SceneComponent } from '../component'; +import { createCompositorComponent, SceneComponent } from '../component'; export type InputStreamProps = { children?: undefined; @@ -14,9 +14,7 @@ export type InputStreamProps = { inputId: Api.InputId; }; -class InputStream extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const InputStream = createCompositorComponent(sceneBuilder); function sceneBuilder(props: InputStreamProps, _children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/Rescaler.ts b/ts/live-compositor/src/components/Rescaler.ts index 6b18abd06..73865c50b 100644 --- a/ts/live-compositor/src/components/Rescaler.ts +++ b/ts/live-compositor/src/components/Rescaler.ts @@ -1,11 +1,7 @@ import React from 'react'; import * as Api from '../api'; import { intoApiTransition, Transition } from './common'; -import LiveCompositorComponent, { - SceneBuilder, - SceneComponent, - sceneComponentIntoApi, -} from '../component'; +import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component'; export type RescalerProps = { children: React.ReactElement | string | number; @@ -77,9 +73,7 @@ export type RescalerProps = { transition?: Transition; }; -class Rescaler extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const Rescaler = createCompositorComponent(sceneBuilder); function sceneBuilder(props: RescalerProps, children: SceneComponent[]): Api.Component { if (children?.length !== 1) { diff --git a/ts/live-compositor/src/components/Shader.ts b/ts/live-compositor/src/components/Shader.ts index 97f94848f..f97c882bd 100644 --- a/ts/live-compositor/src/components/Shader.ts +++ b/ts/live-compositor/src/components/Shader.ts @@ -1,9 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { - SceneBuilder, - SceneComponent, - sceneComponentIntoApi, -} from '../component'; +import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component'; export type ShaderProps = { /** @@ -57,9 +53,7 @@ export type ShaderParamStructField = fieldName: string; }; -class Shader extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const Shader = createCompositorComponent(sceneBuilder); function sceneBuilder(props: ShaderProps, children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/Text.ts b/ts/live-compositor/src/components/Text.ts index da2d98bec..be93dcc9c 100644 --- a/ts/live-compositor/src/components/Text.ts +++ b/ts/live-compositor/src/components/Text.ts @@ -1,5 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { SceneBuilder, SceneComponent } from '../component'; +import { createCompositorComponent, SceneComponent } from '../component'; export type TextProps = { children?: (string | number)[] | string | number; @@ -68,9 +68,7 @@ export type TextProps = { weight?: Api.TextWeight; }; -class Text extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const Text = createCompositorComponent(sceneBuilder); function sceneBuilder(props: TextProps, children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/Tiles.ts b/ts/live-compositor/src/components/Tiles.ts index 48db1f8ff..fb9e98b0b 100644 --- a/ts/live-compositor/src/components/Tiles.ts +++ b/ts/live-compositor/src/components/Tiles.ts @@ -1,10 +1,6 @@ import * as Api from '../api'; import { intoApiTransition, Transition } from './common'; -import LiveCompositorComponent, { - SceneBuilder, - SceneComponent, - sceneComponentIntoApi, -} from '../component'; +import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component'; export type TilesProps = { /** @@ -58,9 +54,7 @@ export type TilesProps = { transition?: Transition; }; -class Tiles extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const Tiles = createCompositorComponent(sceneBuilder); function sceneBuilder(props: TilesProps, children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/View.ts b/ts/live-compositor/src/components/View.ts index 8dc237788..0668b643a 100644 --- a/ts/live-compositor/src/components/View.ts +++ b/ts/live-compositor/src/components/View.ts @@ -1,9 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { - SceneBuilder, - SceneComponent, - sceneComponentIntoApi, -} from '../component'; +import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component'; import { intoApiTransition, Transition } from './common'; export type ViewProps = { @@ -74,9 +70,7 @@ export type ViewProps = { backgroundColorRgba?: Api.RGBAColor; }; -class View extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const View = createCompositorComponent(sceneBuilder); function sceneBuilder(props: ViewProps, children: SceneComponent[]): Api.Component { return { diff --git a/ts/live-compositor/src/components/WebView.ts b/ts/live-compositor/src/components/WebView.ts index 21d2c9ba8..0d4bc6ea3 100644 --- a/ts/live-compositor/src/components/WebView.ts +++ b/ts/live-compositor/src/components/WebView.ts @@ -1,9 +1,5 @@ import * as Api from '../api'; -import LiveCompositorComponent, { - SceneBuilder, - SceneComponent, - sceneComponentIntoApi, -} from '../component'; +import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component'; export type WebViewProps = { /** @@ -18,9 +14,7 @@ export type WebViewProps = { instanceId: Api.RendererId; }; -class WebView extends LiveCompositorComponent { - builder: SceneBuilder = sceneBuilder; -} +const WebView = createCompositorComponent(sceneBuilder); function sceneBuilder(props: WebViewProps, children: SceneComponent[]): Api.Component { return { diff --git a/ts/package.json b/ts/package.json index 03db3ee4b..1a4893361 100644 --- a/ts/package.json +++ b/ts/package.json @@ -4,6 +4,7 @@ "version": "0.1.0", "scripts": { "lint": "lerna run lint", + "lint:fix": "lerna run lint -- --fix", "build": "lerna run build", "typecheck": "lerna run typecheck", "clean": "lerna run clean",