refactor(studio): remove dead crossfade scaffolding from NLEPreview

Follow-up to the playhead-preservation fix: clean up the now-unreachable
crossfade infrastructure that was only triggered by refreshKey changes.

- Remove retiringKey state, retiringTimerRef, handleNewPlayerLoad
- Remove the retiring Player render block and conditional onLoad/style
- Drop refreshKey from getPreviewPlayerKey signature and NLEPreviewProps
- Stop passing refreshKey from NLELayout to NLEPreview
- Update NLELayout comment to reflect current iframe.src reload model
- Simplify getPreviewPlayerKey test
This commit is contained in:
Miguel Ángel
2026-05-21 13:21:10 -04:00
parent 1e9a175778
commit afa6530a10
3 changed files with 10 additions and 52 deletions
@@ -133,8 +133,8 @@ export const NLELayout = memo(function NLELayout({
// Lightweight reload: change iframe src instead of destroying the Player.
// refreshPlayer() saves the seek position and appends a cache-busting _t
// param, avoiding the full web-component teardown + crossfade that the
// key-based path uses.
// param — the Player instance stays alive so the adapter is available for
// saveSeekPosition() to read the current time before the reload.
const prevRefreshKeyRef = useRef(refreshKey);
useEffect(() => {
if (refreshKey === prevRefreshKeyRef.current) return;
@@ -352,7 +352,6 @@ export const NLELayout = memo(function NLELayout({
onCompositionLoadingChange={setCompositionLoading}
portrait={portrait}
directUrl={directUrl}
refreshKey={refreshKey}
suppressLoadingOverlay={hasLoadedOnceRef.current}
/>
{!isFullscreen && previewOverlay}
@@ -112,17 +112,9 @@ function renderPreview() {
}
describe("getPreviewPlayerKey", () => {
it("keeps the same player identity when only refreshKey changes", () => {
expect(
getPreviewPlayerKey({
projectId: "timeline-edit-playground",
refreshKey: 1,
}),
).toBe(
getPreviewPlayerKey({
projectId: "timeline-edit-playground",
refreshKey: 2,
}),
it("uses projectId as key when no directUrl", () => {
expect(getPreviewPlayerKey({ projectId: "timeline-edit-playground" })).toBe(
"timeline-edit-playground",
);
});
@@ -20,7 +20,6 @@ interface NLEPreviewProps {
onCompositionLoadingChange?: (loading: boolean) => void;
portrait?: boolean;
directUrl?: string;
refreshKey?: number;
suppressLoadingOverlay?: boolean;
}
@@ -30,7 +29,6 @@ export function getPreviewPlayerKey({
}: {
projectId: string;
directUrl?: string;
refreshKey?: number;
}): string {
return directUrl ?? projectId;
}
@@ -91,15 +89,12 @@ export const NLEPreview = memo(function NLEPreview({
onCompositionLoadingChange,
portrait,
directUrl,
refreshKey,
suppressLoadingOverlay,
}: NLEPreviewProps) {
const baseKey = getPreviewPlayerKey({ projectId, directUrl, refreshKey });
const activeKey = getPreviewPlayerKey({ projectId, directUrl });
const viewportRef = useRef<HTMLDivElement>(null);
const stageRef = useRef<HTMLDivElement>(null);
const [retiringKey, setRetiringKey] = useState<string | null>(null);
const [stageSize, setStageSize] = useState(() => resolvePreviewStageSize(0, 0, portrait));
const retiringTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const zoomRef = useRef<PreviewZoomState>(loadInitialZoom());
const [settledZoom, setSettledZoom] = useState<PreviewZoomState>(() => zoomRef.current);
@@ -119,7 +114,6 @@ export const NLEPreview = memo(function NLEPreview({
return () => {
if (settleTimerRef.current) clearTimeout(settleTimerRef.current);
if (hudTimerRef.current) clearTimeout(hudTimerRef.current);
if (retiringTimerRef.current) clearTimeout(retiringTimerRef.current);
};
}, []);
@@ -204,8 +198,6 @@ export const NLEPreview = memo(function NLEPreview({
[applyTransform],
);
const activeKey = baseKey;
const applyInitialZoom = useCallback(() => {
const z = zoomRef.current;
if (Math.abs(z.zoomPercent - 100) > 0.5 || Math.abs(z.panX) > 0.1 || Math.abs(z.panY) > 0.1) {
@@ -213,16 +205,6 @@ export const NLEPreview = memo(function NLEPreview({
}
}, [writeTransform]);
const handleNewPlayerLoad = () => {
onIframeLoad();
applyInitialZoom();
if (retiringTimerRef.current) clearTimeout(retiringTimerRef.current);
retiringTimerRef.current = setTimeout(() => {
setRetiringKey(null);
retiringTimerRef.current = null;
}, 160);
};
useEffect(() => {
const viewport = viewportRef.current;
if (!viewport) return;
@@ -405,32 +387,17 @@ export const NLEPreview = memo(function NLEPreview({
}}
data-testid="preview-zoom-stage"
>
{retiringKey && (
<Player
key={retiringKey}
projectId={directUrl ? undefined : projectId}
directUrl={directUrl}
onLoad={() => {}}
portrait={portrait}
style={{ position: "absolute", inset: 0, zIndex: 0, opacity: 1 }}
/>
)}
<Player
key={activeKey}
ref={iframeRef}
projectId={directUrl ? undefined : projectId}
directUrl={directUrl}
onLoad={
retiringKey
? handleNewPlayerLoad
: () => {
onIframeLoad();
applyInitialZoom();
}
}
onLoad={() => {
onIframeLoad();
applyInitialZoom();
}}
onCompositionLoadingChange={onCompositionLoadingChange}
portrait={portrait}
style={retiringKey ? { position: "absolute", inset: 0, zIndex: 1 } : undefined}
suppressLoadingOverlay={suppressLoadingOverlay}
/>
</div>