"use client"; import { useEffect, useRef, useState } from "react"; import { sse } from "@/lib/db/sse-endpoints"; import { getTopDonate } from "./api"; type Data = Awaited>; export default function TopDonateWidget() { const [top, setTop] = useState(); const textRef = useRef(null); const stableSize = useRef>({}); const [ping, setPing] = useState(0); useEffect(() => { async function update() { void getTopDonate().then(setTop); } queueMicrotask(update); const { clean } = sse.donate.subMany({ update, ping: update, refresh: () => location.reload(), }); const backupInterval = setInterval(update, 300000); return () => { clean(); clearInterval(backupInterval); }; }, []); useEffect(() => { const listener = () => setPing(Date.now()); window.addEventListener("resize", listener); return () => window.removeEventListener("resize", listener); }); // the most idiomatic way possible but it works useEffect(() => { if (!textRef.current) return; var fontSize = 48, count = 0; const el = textRef.current, key = `${top?.name}${top?.amount}`; if (stableSize.current[key]) { el.style.fontSize = `${stableSize.current[key]}px`; return; } const interval = setInterval(() => { console.log(el.scrollWidth, el.clientWidth); fontSize = (fontSize * el.clientWidth) / el.scrollWidth; el.style.fontSize = `${fontSize}px`; count++; if (count > 20) { stableSize.current[key] = fontSize; clearInterval(interval); } }, 100); return () => clearInterval(interval); }, [textRef, top, ping]); return top ? (
{top.name}
{top.amount}฿
) : ( "" ); }