/** * How much of a leaf's bottom is covered by something the operator cannot * move: Obsidian's desktop status bar, a phone's navbar (which paints over a * leaf rather than shortening it), and the software keyboard, which shrinks * the visual viewport while the layout keeps its full height. * * Pure on purpose - the view feeds it live rectangles, the tests feed it the * numbers a phone actually reports. */ export interface Rect { bottom: number; height: number; left: number; right: number; top: number; } export interface Visible { /** `visualViewport.height`: what is left once the keyboard is up. */ height: number; /** `visualViewport.offsetTop`: where the visible area starts. */ offsetTop: number; } export function insetFor( leaf: Rect, bars: Rect[], visible: Visible | null ): number { if (leaf.height <= 0) { return 0; } let overlap = 0; for (const bar of bars) { // A bar that does not sit over this leaf horizontally covers nothing of // it - the desktop status bar next to a left-hand sidedock, say. if (bar.height > 0 && bar.left < leaf.right && bar.right > leaf.left) { overlap = Math.max(overlap, leaf.bottom - bar.top); } } if (visible) { const floor = visible.offsetTop + visible.height; overlap = Math.max(overlap, leaf.bottom - floor); } return Math.max(0, Math.round(overlap)); }