import { t } from '../i18n'; import { bytes, num } from '../lib/format'; import { useData } from '../store'; import { Icon, type IconName } from './icons'; const ICON: Record = { job: ['refresh', 'tone-bg-accent'], ok: ['check', 'tone-bg-ok'], bad: ['alertCircle', 'tone-bg-bad'], info: ['info', 'tone-bg-info'] }; /** Background jobs and results, bottom right. Jobs show progress and a Cancel button; results close by themselves. */ export function Toasts() { const d = useData(); return (
{d.toasts.map(x => { const [icon, cls] = ICON[x.kind]!; const p = x.progress; const big = p && p.total > 10_000; return (
{x.title}{x.detail && {x.detail}}
{x.kind === 'job' && ( <> {p ? (
{big ? `${bytes(p.done)} / ${bytes(p.total)}` : `${num(p.done)} / ${num(p.total)}`}{Math.round((p.done / Math.max(1, p.total)) * 100)}%
) :
} {x.lines && x.lines.length > 1 && (
{t('toast.log', { count: x.lines.length })}
{x.lines.join('\n')}
)} {x.job &&
} )}
); })}
); }