scaling based on component size instead webview size

This commit is contained in:
Timo K.
2026-09-04 14:16:40 +02:00
parent f5458bb03e
commit 38c28a1c8f
11 changed files with 293 additions and 14 deletions
+69 -1
View File
@@ -14,7 +14,7 @@ import {
type MockedFunction,
vi,
} from "vitest";
import { render, type RenderResult } from "@testing-library/react";
import { act, render, type RenderResult } from "@testing-library/react";
import { type LocalParticipant } from "livekit-client";
import { BehaviorSubject, of } from "rxjs";
import { BrowserRouter } from "react-router-dom";
@@ -51,6 +51,7 @@ import { AppBar } from "../AppBar";
import { type MatrixInfo } from "./VideoPreview";
import { ProcessorProvider } from "../livekit/TrackProcessorContext";
import { initializeWidget } from "../widget";
import { RootElementProvider } from "../RootElementContext";
initializeWidget();
vi.hoisted(
@@ -263,4 +264,71 @@ describe("ActiveCall", () => {
// Rendering at all proves ActiveCall created all of its view models
expect(await findByTestId("incall_leave")).toBeVisible();
});
it("lays the call out for the size of its root element", async () => {
// jsdom has no layout and no ResizeObserver: the root reports whatever
// size we say, and the observer notifies whenever we tell it to
let size = { width: 1000, height: 800 };
const root = document.createElement("div");
Object.defineProperty(root, "clientWidth", { get: () => size.width });
Object.defineProperty(root, "clientHeight", { get: () => size.height });
document.body.appendChild(root);
const observers: (() => void)[] = [];
const originalResizeObserver = window.ResizeObserver;
window.ResizeObserver = class {
public constructor(private readonly callback: ResizeObserverCallback) {}
public observe(): void {
observers.push(() => this.callback([], this as ResizeObserver));
}
public unobserve(): void {}
public disconnect(): void {}
} as unknown as typeof ResizeObserver;
try {
const mediaDevices = mockMediaDevices({});
const { rtcSession, matrixRoom } = getBasicRTCSession([local, alice]);
const { findByTestId, container } = render(
<BrowserRouter>
<RootElementProvider value={root}>
<MediaDevicesContext value={mediaDevices}>
<ProcessorProvider>
<TooltipProvider>
<RoomContext value={mockLivekitRoom({ localParticipant })}>
<ActiveCall
client={matrixRoom.client}
rtcSession={rtcSession.asMockedSession()}
matrixRoom={matrixRoom}
muteStates={mockMuteStates()}
matrixInfo={matrixInfo}
onShareClick={null}
e2eeSystem={{ kind: E2eeType.NONE }}
onLeft={(): void => {}}
/>
</RoomContext>
</TooltipProvider>
</ProcessorProvider>
</MediaDevicesContext>
</RootElementProvider>
</BrowserRouter>,
{ container: root },
);
await findByTestId("incall_leave");
const call = container.querySelector("[data-layout]")!;
expect(call.getAttribute("data-layout")).not.toBe("pip");
// The host shrinks the container to a corner of its page. The window has
// not changed at all — what matters is the element we were given.
size = { width: 300, height: 300 };
act(() => observers.forEach((notify) => notify()));
expect(call.getAttribute("data-layout")).toBe("pip");
size = { width: 1000, height: 800 };
act(() => observers.forEach((notify) => notify()));
expect(call.getAttribute("data-layout")).not.toBe("pip");
} finally {
window.ResizeObserver = originalResizeObserver;
root.remove();
}
});
});