mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-10 21:55:19 +00:00
fix layout in spotlight (top inset)
This commit is contained in:
@@ -92,6 +92,32 @@ test("keeps its modals inside the container it was given", async ({ page }) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("keeps the call inside the container, wherever the host put it", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const { username, roomId } = await createUserAndRoom("tileswithin");
|
||||||
|
const panes = await startHarness(page, username, roomId);
|
||||||
|
const pane = panes.first();
|
||||||
|
const container = pane.getByTestId("call-container");
|
||||||
|
|
||||||
|
// Large enough for the layout switch to be offered
|
||||||
|
await resizeContainer(container, { width: 900, height: 640 });
|
||||||
|
await pane.getByTestId("lobby_joinCall").click({ timeout: 60_000 });
|
||||||
|
await expect(pane.getByTestId("footer-container")).toBeVisible({
|
||||||
|
timeout: 60_000,
|
||||||
|
});
|
||||||
|
|
||||||
|
// The spotlight layout draws its tile in the fixed grid, which is positioned
|
||||||
|
// against Element Call's root rather than laid out in flow. The harness puts
|
||||||
|
// the container below a header of its own, so a grid offset measured from
|
||||||
|
// the top of the page instead of from the root would land the tile on top of
|
||||||
|
// the footer and out of the bottom of the container.
|
||||||
|
await pane.getByRole("radio", { name: "Spotlight" }).check();
|
||||||
|
const tile = pane.getByTestId("videoTile").first();
|
||||||
|
await expect(tile).toBeVisible({ timeout: 60_000 });
|
||||||
|
await expectWithin(tile, container);
|
||||||
|
});
|
||||||
|
|
||||||
test("leaves the host's own page unstyled", async ({ page }) => {
|
test("leaves the host's own page unstyled", async ({ page }) => {
|
||||||
const { username, roomId } = await createUserAndRoom("hoststyles");
|
const { username, roomId } = await createUserAndRoom("hoststyles");
|
||||||
const panes = await startHarness(page, username, roomId);
|
const panes = await startHarness(page, username, roomId);
|
||||||
|
|||||||
+16
-2
@@ -267,6 +267,20 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
// Merge the refs so they can attach to the same element
|
// Merge the refs so they can attach to the same element
|
||||||
const containerRef = useMergedRefs(containerRef1, containerRef2);
|
const containerRef = useMergedRefs(containerRef1, containerRef2);
|
||||||
|
|
||||||
|
// The fixed grid is positioned against Element Call's root, so offsets
|
||||||
|
// handed to it have to be measured from there rather than from the
|
||||||
|
// viewport. Standalone the two are the same, the root being the page; for a
|
||||||
|
// component the root sits wherever the host put it, and measuring from the
|
||||||
|
// viewport would push the grid down by that much again. Taken at the same
|
||||||
|
// moment as `bounds`, so that the two agree however the host has scrolled.
|
||||||
|
const rootElement = useRootElement();
|
||||||
|
const rootTop = useMemo(
|
||||||
|
() => rootElement.getBoundingClientRect().top,
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[rootElement, bounds],
|
||||||
|
);
|
||||||
|
const topWithinRoot = bounds.top - rootTop;
|
||||||
|
|
||||||
const { showControls, header: headerStyle } = useUrlParams();
|
const { showControls, header: headerStyle } = useUrlParams();
|
||||||
|
|
||||||
const muteAllAudio = useBehavior(muteAllAudio$);
|
const muteAllAudio = useBehavior(muteAllAudio$);
|
||||||
@@ -564,7 +578,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
className={styles.fixedGrid}
|
className={styles.fixedGrid}
|
||||||
style={{
|
style={{
|
||||||
// If not edge-to-edge, consume the header insets right here.
|
// If not edge-to-edge, consume the header insets right here.
|
||||||
insetBlockStart: edgeToEdge ? 0 : bounds.top + headerBounds.height,
|
insetBlockStart: edgeToEdge ? 0 : topWithinRoot + headerBounds.height,
|
||||||
height: edgeToEdge ? "100%" : gridBounds.height,
|
height: edgeToEdge ? "100%" : gridBounds.height,
|
||||||
// If edge-to-edge, compute new safe area insets that account for the
|
// If edge-to-edge, compute new safe area insets that account for the
|
||||||
// header and footer, passing them down to the tiles.
|
// header and footer, passing them down to the tiles.
|
||||||
@@ -575,7 +589,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
// itself. Otherwise account for the safe area and header size
|
// itself. Otherwise account for the safe area and header size
|
||||||
// as part of the InCallView.
|
// as part of the InCallView.
|
||||||
headerStyle === HeaderStyle.AppBar
|
headerStyle === HeaderStyle.AppBar
|
||||||
? `${bounds.top}px`
|
? `${topWithinRoot}px`
|
||||||
: `calc(env(safe-area-inset-top) + ${headerBounds.height}px)`
|
: `calc(env(safe-area-inset-top) + ${headerBounds.height}px)`
|
||||||
: undefined,
|
: undefined,
|
||||||
"--call-view-safe-area-inset-bottom":
|
"--call-view-safe-area-inset-bottom":
|
||||||
|
|||||||
Reference in New Issue
Block a user