"use client"; /** * 元素全可见性 hook * * 原始 Dart: `visibility_detector` 包的 `VisibilityDetector`(chat_screen 用法: * onVisibilityChanged: (info) { if (info.visibleFraction == 1.0) ... })。 * * 用 IntersectionObserver,threshold=1.0 触发 `isIntersecting` 即视为「完全可见」。 * 返回 `[isVisible, ref]`,与 Flutter `VisibilityDetector` 的语义对齐。 * * 用法: * const [isVisible, ref] = useFullVisibility(); * useEffect(() => { dispatch(isVisible ? Visible() : Invisible()); }, [isVisible]); */ import { useEffect, useRef, useState } from "react"; export function useFullVisibility( threshold = 1.0, ): readonly [boolean, React.RefObject] { const ref = useRef(null); const [visible, setVisible] = useState(false); useEffect(() => { const el = ref.current; if (!el || typeof IntersectionObserver === "undefined") return; const observer = new IntersectionObserver( (entries) => { const entry = entries[0]; if (!entry) return; setVisible( entry.isIntersecting && entry.intersectionRatio >= threshold, ); }, { threshold: [threshold] }, ); observer.observe(el); return () => observer.disconnect(); }, [threshold]); return [visible, ref] as const; }