33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
import { useEffect, useRef } from "react";
|
|
import { createLocalStats, type StatsStore } from "./readingStats";
|
|
|
|
const TICK = 30; // 秒:可见期间心跳粒度
|
|
|
|
/** Reader 页挂一次:可见期间每 30s 落一笔,隐藏/卸载即 flush。 */
|
|
export function useReadingSession(store: StatsStore = createLocalStats()) {
|
|
const acc = useRef(0);
|
|
const last = useRef(0);
|
|
useEffect(() => {
|
|
last.current = Date.now(); // 渲染期不取时钟,effect 内初始化起算点
|
|
const flush = () => {
|
|
const now = Date.now();
|
|
if (document.visibilityState === "visible") acc.current += (now - last.current) / 1000;
|
|
last.current = now;
|
|
if (acc.current >= 1) {
|
|
store.record(acc.current);
|
|
acc.current = 0;
|
|
}
|
|
};
|
|
const t = setInterval(flush, TICK * 1000);
|
|
const onVis = () => flush();
|
|
document.addEventListener("visibilitychange", onVis);
|
|
globalThis.addEventListener?.("pagehide", onVis);
|
|
return () => {
|
|
clearInterval(t);
|
|
document.removeEventListener("visibilitychange", onVis);
|
|
globalThis.removeEventListener?.("pagehide", onVis);
|
|
flush();
|
|
};
|
|
}, [store]);
|
|
}
|