| 1 | /** |
| 2 | * Following a running step's log: where the end of the log is against what |
| 3 | * the viewer can see. Pure; the hook that uses it is `useFollow` in |
| 4 | * routes/repo/actions-run.tsx. |
| 5 | * |
| 6 | * The end of the log is a marker after its last line. What covers the |
| 7 | * bottom of the window (a phone's tab bar, and room to breathe under the |
| 8 | * last line) is the marker's `scroll-margin-bottom`, so scrolling it into |
| 9 | * view and judging whether it is in view read the same number. |
| 10 | */ |
| 11 | |
| 12 | /** How far past what can be seen the end may be and still count as reached: rounding, not a row. */ |
| 13 | export const FOLLOW_SLACK = 2; |
| 14 | |
| 15 | export type EndBox = { top: number; bottom: number; width: number; height: number }; |
| 16 | |
| 17 | /** |
| 18 | * Where the end of the log is: folded away (a closed step draws nothing), |
| 19 | * in view above whatever covers the window's bottom (the viewer is |
| 20 | * reading the latest), or below it. |
| 21 | */ |
| 22 | export function endPlace(end: EndBox | null, view: { height: number; covered: number }): "folded" | "here" | "below" { |
| 23 | if (!end || (end.width === 0 && end.height === 0)) return "folded"; |
| 24 | return end.bottom <= view.height - view.covered + FOLLOW_SLACK ? "here" : "below"; |
| 25 | } |