mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
baf69da27f
A calm panel under the card's facts: a dot with the state, the tier, a bar of today's use against the limit, what is left and the local time the count starts again. It reads when the card comes into view and every 30 seconds while it stays there and the tab is in front, says why when the services are off, revoked or cannot be read, and offers a new identity behind a confirmation unless the key comes from the environment.
28 lines
1.1 KiB
TypeScript
28 lines
1.1 KiB
TypeScript
import { useEffect, useState, type RefObject } from 'react';
|
|
|
|
/**
|
|
* Whether an element is on screen and its tab in front. Without
|
|
* IntersectionObserver (an old browser, a test) the element counts as on
|
|
* screen, so whatever depends on it still runs.
|
|
*/
|
|
export function useElementVisible(target: RefObject<Element | null>): boolean {
|
|
const [onScreen, setOnScreen] = useState(true);
|
|
const [tabShown, setTabShown] = useState(() => document.visibilityState !== 'hidden');
|
|
|
|
useEffect(() => {
|
|
const element = target.current;
|
|
if (!element || typeof IntersectionObserver === 'undefined') return;
|
|
const observer = new IntersectionObserver(([entry]) => setOnScreen(entry?.isIntersecting ?? false));
|
|
observer.observe(element);
|
|
return () => observer.disconnect();
|
|
}, [target]);
|
|
|
|
useEffect(() => {
|
|
const onChange = () => setTabShown(document.visibilityState !== 'hidden');
|
|
document.addEventListener('visibilitychange', onChange);
|
|
return () => document.removeEventListener('visibilitychange', onChange);
|
|
}, []);
|
|
|
|
return onScreen && tabShown;
|
|
}
|