// ===== widgets.jsx ===== // Global floating widgets: LiveFeed (bottom-right), MobileStickyCTA (bottom bar). const { useState: useSW, useEffect: useEW, useRef: useRW } = React; function LiveFeed() { const feed = MOCK.LIVE_FEED; const [idx, setIdx] = useSW(0); const [closed, setClosed] = useSW(false); const [show, setShow] = useSW(false); // Surface after a small delay on first load useEW(() => { const t = setTimeout(() => setShow(true), 2500); return () => clearTimeout(t); }, []); // Rotate every 8s useEW(() => { if (closed) return; const id = setInterval(() => setIdx(i => (i + 1) % feed.length), 8000); return () => clearInterval(id); }, [closed, feed.length]); if (closed) return null; const item = feed[idx]; const risk = item.aigc < 30 ? { label: '低风险', tone: 'text-ok-600', dot: 'bg-ok-500' } : item.aigc < 55 ? { label: '中风险', tone: 'text-warn-600', dot: 'bg-warn-500' } : { label: '高风险', tone: 'text-bad-600', dot: 'bg-bad-500' }; return (
实时 {item.ago}
{item.name} 完成了 {item.words.toLocaleString()} 字检测
AIGC {item.aigc}% · {risk.label}
); } function MobileStickyCTA({ navigate, route }) { // Don't show on the order page, the report page, the admin page or while uploading if (route === 'order' || route === 'admin' || route === 'report') return null; return (
); } window.LiveFeed = LiveFeed; window.MobileStickyCTA = MobileStickyCTA;