Merge pull request #3903 from element-hq/edge-to-edge

Allow calls to display edge-to-edge on mobile
This commit is contained in:
Robin
2026-05-04 15:40:08 +02:00
committed by GitHub
12 changed files with 70 additions and 21 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0" content="viewport-fit=cover, width=device-width, initial-scale=1.0, maximum-scale=1.0"
/> />
<title><%- brand %></title> <title><%- brand %></title>
<script> <script>
+1 -2
View File
@@ -1,10 +1,9 @@
.bar { .bar {
block-size: 64px;
flex-shrink: 0; flex-shrink: 0;
} }
.bar > header { .bar > header {
position: absolute; position: sticky;
inset-inline: 0; inset-inline: 0;
inset-block-start: 0; inset-block-start: 0;
block-size: 64px; block-size: 64px;
+3 -1
View File
@@ -12,7 +12,9 @@ Please see LICENSE in the repository root for full details.
align-items: center; align-items: center;
user-select: none; user-select: none;
flex-shrink: 0; flex-shrink: 0;
padding-inline: var(--inline-content-inset); padding-left: var(--content-inset-left);
padding-right: var(--content-inset-right);
padding-top: env(safe-area-inset-top);
} }
.nav { .nav {
+12 -4
View File
@@ -14,7 +14,11 @@ Please see LICENSE in the repository root for full details.
grid-template-areas: ". buttons layout"; grid-template-areas: ". buttons layout";
align-items: center; align-items: center;
gap: var(--cpd-space-3x); gap: var(--cpd-space-3x);
padding: var(--cpd-space-10x) var(--cpd-space-6x); /* Ensure that footer lies within the safe area */
padding-left: calc(env(safe-area-inset-left) + var(--cpd-space-6x));
padding-right: calc(env(safe-area-inset-right) + var(--cpd-space-6x));
padding-block: var(--cpd-space-10x)
calc(env(safe-area-inset-bottom) + var(--cpd-space-10x));
background: linear-gradient( background: linear-gradient(
180deg, 180deg,
rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 0%,
@@ -118,13 +122,15 @@ Once we exceed 500 we hide everything except the buttons.
@media (max-height: 800px) { @media (max-height: 800px) {
.footer { .footer {
padding-block: var(--cpd-space-8x); padding-block: var(--cpd-space-8x)
calc(env(safe-area-inset-bottom) + var(--cpd-space-8x));
} }
} }
@media (max-height: 400px) { @media (max-height: 400px) {
.footer { .footer {
padding-block: var(--cpd-space-4x); padding-block: var(--cpd-space-4x)
calc(env(safe-area-inset-bottom) + var(--cpd-space-4x));
} }
} }
@@ -140,7 +146,9 @@ Once we exceed 500 we hide everything except the buttons.
} }
.footer { .footer {
padding-block-start: var(--cpd-space-3x); padding-block-start: var(--cpd-space-3x);
padding-block-end: var(--cpd-space-2x); padding-block-end: calc(
env(safe-area-inset-bottom) + var(--cpd-space-2x)
);
} }
} }
} }
+2
View File
@@ -157,6 +157,8 @@ export const UnavailableMediaDevices: Story = {
...Default, ...Default,
args: { args: {
...Default.args, ...Default.args,
audioEnabled: false,
videoEnabled: false,
toggleAudio: undefined, toggleAudio: undefined,
toggleVideo: undefined, toggleVideo: undefined,
audioOutputSwitcher: undefined, audioOutputSwitcher: undefined,
+17 -3
View File
@@ -266,6 +266,20 @@ export function Grid<
}, []), }, []),
useCallback(() => window.innerHeight, []), useCallback(() => window.innerHeight, []),
); );
const orientation = useSyncExternalStore(
useCallback((onChange) => {
// Support for the change event is experimental
// https://developer.mozilla.org/en-US/docs/Web/API/Screen/change_event#browser_compatibility
(screen as unknown as EventTarget).addEventListener?.("change", onChange);
return (): void =>
(screen as unknown as EventTarget).removeEventListener?.(
"change",
onChange,
);
}, []),
useCallback(() => window.innerHeight, []),
);
const [layoutRoot, setLayoutRoot] = useState<HTMLElement | null>(null); const [layoutRoot, setLayoutRoot] = useState<HTMLElement | null>(null);
const [generation, setGeneration] = useState<number | null>(null); const [generation, setGeneration] = useState<number | null>(null);
const [visibleTilesCallback, setVisibleTilesCallback] = const [visibleTilesCallback, setVisibleTilesCallback] =
@@ -336,10 +350,10 @@ export function Grid<
} }
return result; return result;
// The rects may change due to the grid resizing or updating to a new // The rects may change due to the grid resizing, changing orientation, or
// generation, but eslint can't statically verify this // updating to a new generation, but eslint can't statically verify this
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [gridRoot, layoutRoot, tiles, gridBounds, generation]); }, [gridRoot, layoutRoot, tiles, gridBounds, orientation, generation]);
// The height of the portion of the grid visible at any given time // The height of the portion of the grid visible at any given time
const visibleHeight = useMemo( const visibleHeight = useMemo(
+3 -2
View File
@@ -31,8 +31,9 @@ Please see LICENSE in the repository root for full details.
position: absolute; position: absolute;
inline-size: 404px; inline-size: 404px;
block-size: 233px; block-size: 233px;
inset-block: 0; /* Ensure that spotlight tile lies within the safe area */
inset-inline: var(--cpd-space-3x); inset: 0 calc(env(safe-area-inset-right) + var(--cpd-space-3x)) 0
calc(env(safe-area-inset-left) + var(--cpd-space-3x));
} }
.fixed > .slot[data-block-alignment="start"] { .fixed > .slot[data-block-alignment="start"] {
+5 -1
View File
@@ -18,7 +18,11 @@ Please see LICENSE in the repository root for full details.
position: absolute; position: absolute;
inline-size: 135px; inline-size: 135px;
block-size: 160px; block-size: 160px;
inset: var(--cpd-space-4x); /* Ensure that PiP lies within the safe area */
inset: calc(env(safe-area-inset-top) + var(--cpd-space-4x))
var(--content-inset-right)
calc(env(safe-area-inset-bottom) + var(--cpd-space-4x))
var(--content-inset-left);
} }
@media (min-width: 600px) { @media (min-width: 600px) {
+14 -4
View File
@@ -37,10 +37,20 @@ layer(compound);
--cpd-color-border-accent: var(--cpd-color-green-800); --cpd-color-border-accent: var(--cpd-color-green-800);
/* The distance to inset non-full-width content from the edge of the window /* The distance to inset non-full-width content from the edge of the window
along the inline axis. This ramps up from 16px for typical mobile windows, to along the inline axis. This ramps up from 16px for typical mobile windows, to
96px for typical desktop windows. */ 96px for typical desktop windows, and accounts for the safe area. */
--inline-content-inset: min( --content-inset-left: calc(
var(--cpd-space-24x), env(safe-area-inset-left) +
max(var(--cpd-space-4x), calc((100vw - 900px) / 3)) min(
var(--cpd-space-24x),
max(var(--cpd-space-4x), calc((100vw - 900px) / 3))
)
);
--content-inset-right: calc(
env(safe-area-inset-right) +
min(
var(--cpd-space-24x),
max(var(--cpd-space-4x), calc((100vw - 900px) / 3))
)
); );
--small-drop-shadow: 0px 1.2px 2.4px 0px rgba(0, 0, 0, 0.15); --small-drop-shadow: 0px 1.2px 2.4px 0px rgba(0, 0, 0, 0.15);
--big-drop-shadow: 0px 0px 24px 0px #1b1d221a; --big-drop-shadow: 0px 0px 24px 0px #1b1d221a;
+2 -1
View File
@@ -57,7 +57,8 @@ Please see LICENSE in the repository root for full details.
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-inline: var(--inline-content-inset); padding-left: var(--content-inset-left);
padding-right: var(--content-inset-right);
} }
.logo { .logo {
+4 -2
View File
@@ -6,7 +6,8 @@ Please see LICENSE in the repository root for full details.
*/ */
.preview { .preview {
margin-inline: var(--inline-content-inset); margin-left: var(--content-inset-left);
margin-right: var(--content-inset-right);
min-block-size: 0; min-block-size: 0;
block-size: 50vh; block-size: 50vh;
border-radius: var(--cpd-space-4x); border-radius: var(--cpd-space-4x);
@@ -80,6 +81,7 @@ video.mirror {
} }
.buttonBar { .buttonBar {
padding-inline: var(--inline-content-inset); padding-left: var(--content-inset-left);
padding-right: var(--content-inset-right);
} }
} }
+6
View File
@@ -33,6 +33,12 @@ Please see LICENSE in the repository root for full details.
--media-view-fg-inset: 10px; --media-view-fg-inset: 10px;
} }
.maximised .item {
/* Ensure that foreground elements lie within the safe area */
--media-view-fg-inset: 10px calc(env(safe-area-inset-right) + 10px) 10px
calc(env(safe-area-inset-left) + 10px);
}
.item.snap { .item.snap {
scroll-snap-align: start; scroll-snap-align: start;
} }