Files
sprite-ai/src/components/Nav.tsx
T
2026-09-23 21:56:40 +03:00

58 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 (
<nav className="nav">
{LINKS.map(([to, text]) => <NavLink key={to} to={to} end>{text}</NavLink>)}
<QueueIndicator />
</nav>
);
}
function counts(list: QueueItem[]): string {
const c = new Map<string, number>();
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<QueueInfo | null>(null);
const [error, setError] = useState('');
useEffect(() => {
let alive = true;
const update = async () => {
if (document.hidden) return;
try {
const info = await api<QueueInfo>('/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 <span className="queue down" title={error}><span className="dot" />ComfyUI недоступен</span>;
if (!q) return <span className="queue"><span className="dot" />ComfyUI…</span>;
if (!q.running.length && !q.pending.length) return <span className="queue idle"><span className="dot" />ComfyUI свободен</span>;
return (
<span className="queue busy" title={q.pending.length ? 'Ждут: ' + counts(q.pending) : ''}>
<span className="dot" />ComfyUI: <b>{counts(q.running) || '—'}</b>
{q.pending.length > 0 && <> · в очереди <b>{q.pending.length}</b></>}
</span>
);
}