Files
beaver-plugin-obsidian/src/inset.ts
T
hh 70cf985aa1 refactor(inset): the bottom-inset arithmetic becomes testable, and is tested
The measurement lived inside the view, where the only way to check it was to
run Obsidian on a phone. It moves to a pure `insetFor(leaf, bars, visible)`
against the numbers a phone reports - including the case the events hid: while
the keyboard is up the navbar is behind it, so the deeper of the two is the
inset and adding them would push the composer twice as far as it must go.
2026-09-05 00:49:54 +02:00

48 lines
1.4 KiB
TypeScript

/**
* 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));
}