Let page background shine through the footer

By visually separating it from other page content with an additional gradient background only when necessary.
This commit is contained in:
Robin
2026-06-25 18:37:54 +02:00
parent a3d3a1e951
commit 900d0abd27
12 changed files with 84 additions and 78 deletions

View File

@@ -208,6 +208,7 @@ export type WindowMode = "normal" | "narrow" | "flat" | "pip";
interface LayoutScanState {
layout: Layout | null;
overflowing: boolean;
tiles: TileStore;
}
@@ -360,6 +361,10 @@ export interface CallViewModel {
* and header as overlays.
*/
edgeToEdge$: Behavior<boolean>;
/**
* Whether the call layout is overflowing the interface (causing it to scroll).
*/
overflowing$: Behavior<boolean>;
settingsOpen$: Behavior<boolean>;
setSettingsOpen$: Behavior<(open: boolean) => void>;
@@ -1467,7 +1472,7 @@ export function createCallViewModel$(
// There is a cyclical dependency here: the layout algorithms want to know
// which tiles are on screen, but to know which tiles are on screen we have to
// first render a layout. To deal with this we assume initially that no tiles
// first render a layout. To deal with this we assume initially that all tiles
// are visible, and loop the data back into the layouts with a Subject.
const visibleTiles$ = new Subject<number>();
const setVisibleTiles = (value: number): void => visibleTiles$.next(value);
@@ -1475,7 +1480,7 @@ export function createCallViewModel$(
const layoutInternals$ = scope.behavior<LayoutScanState & { layout: Layout }>(
combineLatest([
layoutMedia$,
visibleTiles$.pipe(startWith(0), distinctUntilChanged()),
visibleTiles$.pipe(startWith(Infinity), distinctUntilChanged()),
]).pipe(
scan<
[LayoutMedia, number],
@@ -1486,6 +1491,7 @@ export function createCallViewModel$(
let layout: Layout;
let newTiles: TileStore;
let pip: GridTileViewModel | undefined;
let overflowing = false;
switch (media.type) {
case "grid":
case "spotlight-landscape":
@@ -1497,6 +1503,7 @@ export function createCallViewModel$(
setVisibleTiles,
prevTiles,
);
overflowing = newTiles.gridTiles.length > visibleTiles;
break;
case "spotlight-expanded":
[layout, newTiles] = spotlightExpandedLayout(
@@ -1531,9 +1538,9 @@ export function createCallViewModel$(
tile.setShowOutline(tile === pip);
}
return { layout, tiles: newTiles };
return { layout, overflowing, tiles: newTiles };
},
{ layout: null, tiles: TileStore.empty() },
{ layout: null, overflowing: false, tiles: TileStore.empty() },
),
),
);
@@ -1545,6 +1552,10 @@ export function createCallViewModel$(
layoutInternals$.pipe(map(({ layout }) => layout)),
);
const overflowing$ = scope.behavior<boolean>(
layoutInternals$.pipe(map(({ overflowing }) => overflowing)),
);
/**
* The current generation of the tile store, exposed for debugging purposes.
*/
@@ -1786,6 +1797,7 @@ export function createCallViewModel$(
settingsOpen$: settingsOpen$,
setSettingsOpen$: setSettingsOpen$,
edgeToEdge$,
overflowing$,
earpieceMode$: earpieceMode$,
audioOutputSwitcher$: audioOutputSwitcher$,
reconnecting$: localMembership.reconnecting$,