import { useEffect, useState } from 'react'; import { NavLink } from 'react-router'; import type { QueueInfo, QueueItem } from '../../shared/api.ts'; import { api } from '../lib/api.ts'; const LINKS = [ ['/', 'Исходники'], ['/projects', 'Проекты'], ] as const; export function Nav() { return ( ); } function counts(list: QueueItem[]): string { const c = new Map(); list.forEach(x => c.set(x.kind, (c.get(x.kind) ?? 0) + 1)); return [...c].map(([k, n]) => k + (n > 1 ? ' ×' + n : '')).join(', '); } /** Состояние очереди ComfyUI: свободен / чем занят и сколько ждёт / недоступен. Обновляется каждые 2 с. */ function QueueIndicator() { const [q, setQ] = useState(null); const [error, setError] = useState(''); useEffect(() => { let alive = true; const update = async () => { if (document.hidden) return; try { const info = await api('/api/queue'); if (alive) { setQ(info); setError(''); } } catch (e) { if (alive) setError((e as Error).message); } }; void update(); const t = setInterval(update, 2000); document.addEventListener('visibilitychange', update); return () => { alive = false; clearInterval(t); document.removeEventListener('visibilitychange', update); }; }, []); if (error) return ComfyUI недоступен; if (!q) return ComfyUI…; if (!q.running.length && !q.pending.length) return ComfyUI свободен; return ( ComfyUI: {counts(q.running) || '—'} {q.pending.length > 0 && <> · в очереди {q.pending.length}} ); }