import { useEffect, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { pauseMutation, pauseQuery } from "@/lib/queries"; import InlineError from "@/lib/InlineError"; import { buttonClass, insetFocusRing } from "@/ui/classes"; const DURATIONS = [ { label: "60 seconds", seconds: 60 }, { label: "5 minutes", seconds: 300 }, { label: "30 minutes", seconds: 1800 }, { label: "Indefinitely", seconds: null }, ] as const; export function formatRemaining(totalSeconds: number): string { const clamped = Math.max(0, totalSeconds); const hours = Math.floor(clamped / 3600); const minutes = Math.floor((clamped % 3600) / 60); const seconds = clamped % 60; const pad = (n: number) => String(n).padStart(2, "0"); return hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${minutes}:${pad(seconds)}`; } function nowSeconds(): number { return Math.floor(Date.now() / 1000); } function useNowSeconds(active: boolean): number { const [now, setNow] = useState(nowSeconds); useEffect(() => { if (!active) return; setNow(nowSeconds()); const id = setInterval(() => setNow(nowSeconds()), 1000); return () => clearInterval(id); }, [active]); return now; } const triggerButtonClass = `${buttonClass} disabled:text-zinc-400 dark:disabled:text-zinc-600`; export default function PauseWidget() { const queryClient = useQueryClient(); const { data } = useQuery({ ...pauseQuery(), refetchInterval: (query) => (query.state.data?.paused === true ? 5000 : false), }); const mutation = useMutation(pauseMutation(queryClient)); const [menuOpen, setMenuOpen] = useState(false); const now = useNowSeconds(data?.paused === true && data.until !== null); const paused = data?.paused === true; const { reset } = mutation; useEffect(() => reset(), [paused, reset]); if (data === undefined) { return ( ); } if (data.paused) { return (
{data.until === null ? "Paused" : `Paused ${formatRemaining(data.until - now)}`}
); } return (
{ if (e.key === "Escape") setMenuOpen(false); }} > {menuOpen && (
{DURATIONS.map(({ label, seconds }) => ( ))}
)}
); }