fix(studio): address timeline PR review — drop dead code, add fadeIn keyframes, compSrc test

This commit is contained in:
Miguel Ángel
2026-05-20 23:54:19 -04:00
parent ef2ff298b6
commit 36898f7681
5 changed files with 80 additions and 30 deletions
@@ -0,0 +1,50 @@
import { describe, expect, it } from "vitest";
import { normalizeCompositionSrc } from "./useRenderClipContent";
describe("normalizeCompositionSrc", () => {
const origin = "http://localhost:5190";
const pid = "my-project";
it("strips absolute preview URL to relative path", () => {
const result = normalizeCompositionSrc(
"http://localhost:5190/api/projects/my-project/preview/compositions/intro.html",
pid,
origin,
);
expect(result).toBe("compositions/intro.html");
});
it("preserves already-relative paths", () => {
const result = normalizeCompositionSrc("compositions/intro.html", pid, origin);
expect(result).toBe("compositions/intro.html");
});
it("preserves absolute URLs from different origins", () => {
const result = normalizeCompositionSrc(
"https://cdn.example.com/compositions/intro.html",
pid,
origin,
);
expect(result).toBe("https://cdn.example.com/compositions/intro.html");
});
it("preserves absolute URLs for different projects", () => {
const result = normalizeCompositionSrc(
"http://localhost:5190/api/projects/other-project/preview/compositions/intro.html",
pid,
origin,
);
expect(result).toBe(
"http://localhost:5190/api/projects/other-project/preview/compositions/intro.html",
);
});
it("handles nested composition paths", () => {
const result = normalizeCompositionSrc(
"http://localhost:5190/api/projects/my-project/preview/compositions/scenes/hero.html",
pid,
origin,
);
expect(result).toBe("compositions/scenes/hero.html");
});
});
@@ -5,6 +5,23 @@ import type { TimelineElement } from "../player";
import { AudioWaveform } from "../player/components/AudioWaveform";
import { getTimelineElementLabel } from "../utils/studioHelpers";
export function normalizeCompositionSrc(
compSrc: string,
projectId: string,
origin: string,
): string {
try {
const parsed = new URL(compSrc, origin);
const previewPrefix = `/api/projects/${projectId}/preview/`;
if (parsed.pathname.startsWith(previewPrefix)) {
return parsed.pathname.slice(previewPrefix.length);
}
} catch {
// already relative
}
return compSrc;
}
interface UseRenderClipContentOptions {
projectIdRef: { current: string | null };
compIdToSrc: Map<string, string>;
@@ -25,15 +42,7 @@ export function useRenderClipContent({
let compSrc = el.compositionSrc;
if (compSrc) {
try {
const parsed = new URL(compSrc, window.location.origin);
const previewPrefix = `/api/projects/${pid}/preview/`;
if (parsed.pathname.startsWith(previewPrefix)) {
compSrc = parsed.pathname.slice(previewPrefix.length);
}
} catch {
// already relative
}
compSrc = normalizeCompositionSrc(compSrc, pid, window.location.origin);
}
if (compSrc && compIdToSrc.size > 0) {
const resolved =
@@ -50,7 +59,7 @@ export function useRenderClipContent({
previewUrl: `/api/projects/${pid}/preview/comp/${compSrc}`,
label: getTimelineElementLabel(el),
labelColor: style.label,
accentColor: style.clip,
seekTime: 0,
duration: el.duration,
});
@@ -63,7 +72,7 @@ export function useRenderClipContent({
previewUrl: activePreviewUrl,
label: getTimelineElementLabel(el),
labelColor: style.label,
accentColor: style.clip,
selector: el.selector,
selectorIndex: el.selectorIndex,
seekTime: el.start,
@@ -119,7 +128,7 @@ export function useRenderClipContent({
previewUrl: `/api/projects/${pid}/preview`,
label: getTimelineElementLabel(el),
labelColor: style.label,
accentColor: style.clip,
selector: el.selector,
selectorIndex: el.selectorIndex,
seekTime: el.start,