49 lines
2.3 KiB
TypeScript
49 lines
2.3 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
|
|
/** How long the quiet has to hold before the screen calls itself ready. */
|
|
const quietMs = 150;
|
|
|
|
/**
|
|
* The readiness signal for the screenshot loop. `networkidle` will not do and cannot do: a live
|
|
* run keeps the SSE open by construction. The screen says by itself when it has decided what to
|
|
* draw — and "I am waiting" is a decision too, for a route that is shot for the sake of the
|
|
* waiting.
|
|
*
|
|
* ⚠ The flag is ONE-WAY: once it has settled it never goes out again. It answers the screenshot
|
|
* loop's question "has the screen come together already?", not "is the network quiet right now":
|
|
* a background refetch on focus return and an update from a live run happen constantly and by
|
|
* construction, and without the latch the frame would be shot in a race with them. A route shot for
|
|
* the sake of the waiting does not touch the latch — it never gets as far as "ready".
|
|
*
|
|
* Two conditions of the latch, and each one was bought with a frame:
|
|
*
|
|
* 1. While NOT A SINGLE request has flown, there is no attribute at all. On the first effect
|
|
* nothing is in flight, and the previous edition announced `ready` at that moment — the gate
|
|
* shot the frame before the first read had started (found by acceptance S3.6). The absence of
|
|
* the attribute the loop waits out silently, and the library is read by every screen.
|
|
* 2. The quiet has to HOLD. The reads of the second wave — the book, the chapters, the bank — turn
|
|
* on only after the library has answered, and between the waves the counter honestly drops to
|
|
* zero: a latch without the hold closed in that pit, and `/scale` was shot with the line
|
|
* "loading chapters…" (measured with a frame, not with reasoning).
|
|
*/
|
|
export function useScreenshotFlag(waiting: boolean): void {
|
|
const started = useRef(false);
|
|
const settled = useRef(false);
|
|
|
|
useEffect(() => {
|
|
if (waiting) started.current = true;
|
|
if (!started.current) return;
|
|
if (waiting || settled.current) {
|
|
document.documentElement.dataset.screen = settled.current ? 'ready' : 'loading';
|
|
return;
|
|
}
|
|
|
|
const timer = setTimeout(() => {
|
|
settled.current = true;
|
|
document.documentElement.dataset.screen = 'ready';
|
|
}, quietMs);
|
|
return () => {
|
|
clearTimeout(timer);
|
|
};
|
|
}, [waiting]);
|
|
}
|