8f2fe7a8e6
* feat(web): add agent message comments * fix(web): harden agent message comments * fix(web): address message comment review findings * fix(web): allow comments on legacy agent messages * fix(web): address latest message comment review * fix(web): address follow-up message comment review * fix(web): address remaining message comment review * fix(web): keep failed mobile comments open * fix(web): preserve selections over message comments
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
export type FloatingBounds = {
|
|
left: number;
|
|
top: number;
|
|
right: number;
|
|
bottom: number;
|
|
};
|
|
|
|
export function floatingBounds(rect?: Pick<DOMRect, "left" | "top" | "right" | "bottom"> | null) {
|
|
return rect
|
|
? { left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom }
|
|
: { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight };
|
|
}
|
|
|
|
function clamp(value: number, minimum: number, maximum: number) {
|
|
return Math.min(Math.max(value, minimum), maximum);
|
|
}
|
|
|
|
export function placeFloatingRect({
|
|
left,
|
|
topCandidates,
|
|
width,
|
|
height,
|
|
bounds,
|
|
margin = 8,
|
|
}: {
|
|
left: number;
|
|
topCandidates: number[];
|
|
width: number;
|
|
height: number;
|
|
bounds: FloatingBounds;
|
|
margin?: number;
|
|
}) {
|
|
const minimumLeft = bounds.left + margin;
|
|
const maximumLeft = Math.max(minimumLeft, bounds.right - width - margin);
|
|
const minimumTop = bounds.top + margin;
|
|
const maximumTop = Math.max(minimumTop, bounds.bottom - height - margin);
|
|
const fittingTop = topCandidates.find(
|
|
(candidate) => candidate >= minimumTop && candidate <= maximumTop,
|
|
);
|
|
|
|
return {
|
|
left: clamp(left, minimumLeft, maximumLeft),
|
|
top: fittingTop ?? clamp(topCandidates[0] ?? minimumTop, minimumTop, maximumTop),
|
|
};
|
|
}
|