import React from 'react'; import type { TransferState } from '../../stores/transferStore'; interface Props { loaded: number; total: number; state: TransferState; filename: string; /** Optional human-readable error surfaced as a hover tooltip when state==='failed'. */ error?: string; onPause?: () => void; onResume?: () => void; onAbort?: () => void; size?: 'tile' | 'pill'; } function fmt(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`; return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`; } export function AttachmentProgress({ loaded, total, state, filename, error, onPause, onResume, onAbort, size = 'tile' }: Props) { const pct = total > 0 ? Math.min(100, Math.round((loaded / total) * 100)) : 0; const bg = state === 'failed' ? 'bg-accent-rose/30' : state === 'paused' ? 'bg-white/5' : 'bg-accent-mint/30'; const isFinal = state === 'completed' || state === 'aborted'; // Desaturate the conic-gradient ring when paused so it can't be mistaken for // active progress. Active uses mint; paused uses a muted grey. const ringColor = state === 'paused' ? 'rgba(180,180,190,.5)' : 'rgba(180,220,200,.85)'; const ringTrack = 'rgba(255,255,255,.15)'; const ringTitle = state === 'failed' ? error : state === 'paused' ? `Paused — ${pct}%` : undefined; return (