From 65d8a19c8778c2858a49a9c83410564d85564675 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sat, 2 May 2026 16:02:47 +0200 Subject: [PATCH] feat(web): AttachmentProgress overlay component --- .../components/chat/AttachmentProgress.tsx | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 packages/web/src/components/chat/AttachmentProgress.tsx diff --git a/packages/web/src/components/chat/AttachmentProgress.tsx b/packages/web/src/components/chat/AttachmentProgress.tsx new file mode 100644 index 00000000..668289f1 --- /dev/null +++ b/packages/web/src/components/chat/AttachmentProgress.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import type { TransferState } from '../../stores/transferStore'; + +interface Props { + loaded: number; + total: number; + state: TransferState; + filename: 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, 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' : 'bg-accent-mint/30'; + const isFinal = state === 'completed' || state === 'aborted'; + return ( +