fix(studio): mute composition hover previews (#2478)

* fix(studio): mute composition hover previews

* fix(studio): route hover muting through bridge
This commit is contained in:
Miguel Ángel
2026-07-15 12:02:36 -04:00
committed by GitHub
parent 04954ead81
commit e038cc93c6
2 changed files with 31 additions and 3 deletions
@@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { resolveCompositionPreviewScale, resolveThumbnailSeekTime } from "./CompositionsTab";
import { describe, expect, it, vi } from "vitest";
import {
resolveCompositionPreviewScale,
resolveThumbnailSeekTime,
syncIframePlayback,
} from "./CompositionsTab";
describe("resolveCompositionPreviewScale", () => {
it("scales a 16:9 stage to fit the composition card", () => {
@@ -50,3 +54,25 @@ describe("resolveThumbnailSeekTime", () => {
expect(resolveThumbnailSeekTime(Number.NaN)).toBe(3);
});
});
describe("syncIframePlayback", () => {
it("mutes a composition-card preview before playing it", () => {
const calls: string[] = [];
const postMessage = vi.fn(() => calls.push("mute"));
const player = {
play: vi.fn(() => calls.push("play")),
};
const iframe = {
contentWindow: { __player: player, postMessage },
getRootNode: () => ({}),
} as unknown as HTMLIFrameElement;
expect(syncIframePlayback(iframe, true)).toBe(true);
expect(postMessage).toHaveBeenCalledWith(
expect.objectContaining({ action: "set-muted", muted: true }),
"*",
);
expect(calls).toEqual(["mute", "play"]);
expect(player.play).toHaveBeenCalledOnce();
});
});
@@ -1,4 +1,5 @@
import { memo, useCallback, useEffect, useRef, useState } from "react";
import { setPreviewMediaMuted } from "../../player/lib/timelineIframeHelpers";
interface CompositionsTabProps {
projectId: string;
@@ -87,12 +88,13 @@ function resolveIframeDuration(iframe: HTMLIFrameElement | null): number | null
}
}
function syncIframePlayback(iframe: HTMLIFrameElement | null, shouldPlay: boolean): boolean {
export function syncIframePlayback(iframe: HTMLIFrameElement | null, shouldPlay: boolean): boolean {
try {
const player = (iframe?.contentWindow as PreviewWindow | null)?.__player;
if (!player) return false;
if (shouldPlay) {
setPreviewMediaMuted(iframe, true);
player.play?.();
return true;
}