Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -476,16 +476,25 @@ const MovingPillCaptionsInner = forwardRef<
},
);

const MovingPillCaptionsWithControls: React.FC<
MovingPillCaptionsProps & {readonly controls: SequenceControls | undefined}
> = ({captions, controls, style, ...props}) => {
const MovingPillCaptionsLayer = Interactive.withSchema({
Component: MovingPillCaptionsInner,
componentName: '<MovingPillCaptions>',
componentIdentity: null,
schema: movingPillCaptionsSchema,
supportsEffects: false,
}) as React.FC<MovingPillCaptionsLayerProps>;

export const MovingPillCaptions: React.FC<MovingPillCaptionsProps> = ({
captions,
style,
...props
}) => {
if (captions) {
return (
<MovingPillCaptionsInner
<MovingPillCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={captions}
controls={controls}
style={{translate: '0px 0px'}}
/>
);
Expand All @@ -501,7 +510,7 @@ const MovingPillCaptionsWithControls: React.FC<
width: 900,
}}
>
<MovingPillCaptionsInner
<MovingPillCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={[
Expand Down Expand Up @@ -555,19 +564,10 @@ const MovingPillCaptionsWithControls: React.FC<
confidence: null,
},
]}
controls={controls}
width={props.width ?? 681}
height={props.height ?? 252}
style={{translate: '0px 0px'}}
/>
</div>
);
};

export const MovingPillCaptions = Interactive.withSchema({
Component: MovingPillCaptionsWithControls,
componentName: '<MovingPillCaptions>',
componentIdentity: null,
schema: movingPillCaptionsSchema,
supportsEffects: false,
}) as React.FC<MovingPillCaptionsProps>;
Original file line number Diff line number Diff line change
Expand Up @@ -386,16 +386,25 @@ const PoppingWordCaptionsInner = forwardRef<
},
);

const PoppingWordCaptionsWithControls: React.FC<
PoppingWordCaptionsProps & {readonly controls: SequenceControls | undefined}
> = ({captions, controls, style, ...props}) => {
const PoppingWordCaptionsLayer = Interactive.withSchema({
Component: PoppingWordCaptionsInner,
componentName: '<PoppingWordCaptions>',
componentIdentity: null,
schema: poppingWordCaptionsSchema,
supportsEffects: false,
}) as React.FC<PoppingWordCaptionsLayerProps>;

export const PoppingWordCaptions: React.FC<PoppingWordCaptionsProps> = ({
captions,
style,
...props
}) => {
if (captions) {
return (
<PoppingWordCaptionsInner
<PoppingWordCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={captions}
controls={controls}
style={{translate: '0px 0px'}}
/>
);
Expand All @@ -411,7 +420,7 @@ const PoppingWordCaptionsWithControls: React.FC<
width: 900,
}}
>
<PoppingWordCaptionsInner
<PoppingWordCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={[
Expand Down Expand Up @@ -465,19 +474,10 @@ const PoppingWordCaptionsWithControls: React.FC<
confidence: null,
},
]}
controls={controls}
width={props.width ?? 681}
height={props.height ?? 252}
style={{translate: '0px 0px'}}
/>
</div>
);
};

export const PoppingWordCaptions = Interactive.withSchema({
Component: PoppingWordCaptionsWithControls,
componentName: '<PoppingWordCaptions>',
componentIdentity: null,
schema: poppingWordCaptionsSchema,
supportsEffects: false,
}) as React.FC<PoppingWordCaptionsProps>;
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,25 @@ const WordHighlightCaptionsInner = forwardRef<
},
);

const WordHighlightCaptionsWithControls: React.FC<
WordHighlightCaptionsProps & {readonly controls: SequenceControls | undefined}
> = ({captions, controls, style, ...props}) => {
const WordHighlightCaptionsLayer = Interactive.withSchema({
Component: WordHighlightCaptionsInner,
componentName: '<WordHighlightCaptions>',
componentIdentity: null,
schema: wordHighlightCaptionsSchema,
supportsEffects: false,
}) as React.FC<WordHighlightCaptionsLayerProps>;

export const WordHighlightCaptions: React.FC<WordHighlightCaptionsProps> = ({
captions,
style,
...props
}) => {
if (captions) {
return (
<WordHighlightCaptionsInner
<WordHighlightCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={captions}
controls={controls}
style={{translate: '0px 0px'}}
/>
);
Expand All @@ -369,7 +378,7 @@ const WordHighlightCaptionsWithControls: React.FC<
width: 900,
}}
>
<WordHighlightCaptionsInner
<WordHighlightCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={[
Expand Down Expand Up @@ -423,19 +432,10 @@ const WordHighlightCaptionsWithControls: React.FC<
confidence: null,
},
]}
controls={controls}
width={props.width ?? 681}
height={props.height ?? 252}
style={{translate: '0px 0px'}}
/>
</div>
);
};

export const WordHighlightCaptions = Interactive.withSchema({
Component: WordHighlightCaptionsWithControls,
componentName: '<WordHighlightCaptions>',
componentIdentity: null,
schema: wordHighlightCaptionsSchema,
supportsEffects: false,
}) as React.FC<WordHighlightCaptionsProps>;
56 changes: 52 additions & 4 deletions packages/example/e2e/captions-inspector.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,37 @@ const inlineCaptionsFile = path.join(
'CaptionsTester',
'InlineAnimatedCaptions.tsx',
);
const elementCaptionsFile = path.join(
exampleDir,
'src',
'moving-pill-captions.element.tsx',
);
const elementCallSiteFile = path.join(
exampleDir,
'src',
'MovingPillCaptionsComposition.tsx',
);

test.describe('captions inspector', () => {
let sourceBefore: string;
let inlineSourceBefore: string;
let elementSourceBefore: string;
let elementCallSiteSourceBefore: string;

test.beforeEach(async () => {
sourceBefore = fs.readFileSync(inlineCaptionsFile, 'utf-8');
inlineSourceBefore = fs.readFileSync(inlineCaptionsFile, 'utf-8');
elementSourceBefore = fs.readFileSync(elementCaptionsFile, 'utf-8');
elementCallSiteSourceBefore = fs.readFileSync(elementCallSiteFile, 'utf-8');
await startStudio();
});

test.afterEach(async () => {
await stopStudio();
fs.writeFileSync(inlineCaptionsFile, sourceBefore);
fs.writeFileSync(inlineCaptionsFile, inlineSourceBefore);
fs.writeFileSync(elementCaptionsFile, elementSourceBefore);
fs.writeFileSync(elementCallSiteFile, elementCallSiteSourceBefore);
});

test('persists a forced page break to an inline caption', async ({page}) => {
test('persists caption edits at their inline definitions', async ({page}) => {
await page.goto(`${STUDIO_URL}/captions-inspector-e2e`);
await expect(page).toHaveURL(/captions-inspector-e2e/, {timeout: 15_000});
await page.waitForFunction(
Expand Down Expand Up @@ -64,5 +80,37 @@ test.describe('captions inspector', () => {
.includes('pageBreakAfter: true');
})
.toBe(true);

await page.goto(`${STUDIO_URL}/default-captions-inspector-e2e`);
await expect(page).toHaveURL(/default-captions-inspector-e2e/, {
timeout: 15_000,
});
await page.waitForFunction(
() => !document.body.innerText.includes('Loading...'),
{timeout: 30_000},
);

const defaultCaptionsSequence = page
.getByTitle('Moving Pill Captions', {exact: true})
.first();
const defaultCaption = page.getByRole('textbox', {name: 'Caption 1'});
await expect(async () => {
await defaultCaptionsSequence.click();
await expect(defaultCaption).toBeVisible({timeout: 1_000});
}).toPass({timeout: 30_000});
await expect(defaultCaption).toBeEnabled();

await defaultCaption.fill('Editable captions');
await defaultCaption.blur();
await expect
.poll(() => {
return /text:\s*['"]Editable captions['"]/.test(
fs.readFileSync(elementCaptionsFile, 'utf-8'),
);
})
.toBe(true);
expect(fs.readFileSync(elementCallSiteFile, 'utf-8')).toBe(
elementCallSiteSourceBefore,
);
});
});
9 changes: 9 additions & 0 deletions packages/example/src/E2eTestRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {Issue8216} from './Issue8216/Issue8216';
import {LightLeakExample} from './LightLeak';
import {LostNodePathRepro} from './LostNodePathE2e/LostNodePathRepro';
import {MacCursorsExample} from './MacCursors';
import {MovingPillCaptionsComposition} from './MovingPillCaptionsComposition';
import {NewVideoComp} from './NewVideo';
import {RotationKeyframeE2e} from './RotationKeyframeE2e';
import {SchemaTest, schemaTestSchema} from './SchemaTest';
Expand Down Expand Up @@ -110,6 +111,14 @@ export const E2eTestRoot: React.FC = () => {
width={1080}
height={CAPTIONS_HEIGHT}
/>
<Composition
id="default-captions-inspector-e2e"
component={MovingPillCaptionsComposition}
durationInFrames={210}
fps={30}
width={1920}
height={1080}
/>
<Folder name="visual-controls">
<Composition
id="visual-controls"
Expand Down
30 changes: 15 additions & 15 deletions packages/example/src/moving-pill-captions.element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -476,16 +476,25 @@ const MovingPillCaptionsInner = forwardRef<
},
);

const MovingPillCaptionsWithControls: React.FC<
MovingPillCaptionsProps & {readonly controls: SequenceControls | undefined}
> = ({captions, controls, style, ...props}) => {
const MovingPillCaptionsLayer = Interactive.withSchema({
Component: MovingPillCaptionsInner,
componentName: '<MovingPillCaptions>',
componentIdentity: null,
schema: movingPillCaptionsSchema,
supportsEffects: false,
}) as React.FC<MovingPillCaptionsLayerProps>;

export const MovingPillCaptions: React.FC<MovingPillCaptionsProps> = ({
captions,
style,
...props
}) => {
if (captions) {
return (
<MovingPillCaptionsInner
<MovingPillCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={captions}
controls={controls}
style={{translate: '0px 0px'}}
/>
);
Expand All @@ -501,7 +510,7 @@ const MovingPillCaptionsWithControls: React.FC<
width: 900,
}}
>
<MovingPillCaptionsInner
<MovingPillCaptionsLayer
{...props}
callerStyle={style ?? null}
captions={[
Expand Down Expand Up @@ -555,19 +564,10 @@ const MovingPillCaptionsWithControls: React.FC<
confidence: null,
},
]}
controls={controls}
width={props.width ?? 681}
height={props.height ?? 252}
style={{translate: '0px 0px'}}
/>
</div>
);
};

export const MovingPillCaptions = Interactive.withSchema({
Component: MovingPillCaptionsWithControls,
componentName: '<MovingPillCaptions>',
componentIdentity: null,
schema: movingPillCaptionsSchema,
supportsEffects: false,
}) as React.FC<MovingPillCaptionsProps>;
1 change: 1 addition & 0 deletions packages/studio/src/components/CaptionTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export const CaptionTextEditor: React.FC<{
{formatMilliseconds(caption.endMs)} ms
</div>
<RemotionInput
aria-label={`Caption ${index + 1}`}
data-caption-index={index}
disabled={readOnly}
onBlur={(event) => {
Expand Down
Loading