Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 10x 1x 10x 6x 8x | import type { Attachment } from "../api";
import { api } from "../api";
import { formatFileSize } from "../email-sanitizer";
import { useAsync } from "../hooks";
import { PaperclipIcon } from "./Icons";
export function AttachmentList({ messageId }: { messageId: number }) {
const { data: attachments, loading } = useAsync(
() => api.messages.attachments(messageId),
[messageId],
);
if (loading || !attachments || attachments.length === 0) return null;
return (
<div className="mt-3 pt-3 border-t border-gray-100 dark:border-gray-800">
<p className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2 flex items-center gap-1.5">
<PaperclipIcon className="w-3.5 h-3.5" />
{attachments.length} attachment{attachments.length !== 1 ? "s" : ""}
</p>
<div className="flex flex-wrap gap-2">
{attachments.map((att: Attachment) => (
<a
key={att.id}
href={`/api/attachments/${att.id}`}
download={att.filename ?? "attachment"}
className="flex items-center gap-2 px-3 py-1.5 text-xs bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 border border-gray-200 dark:border-gray-700 rounded-md transition-colors"
>
<span className="truncate max-w-[200px]">{att.filename ?? "attachment"}</span>
{att.size != null && att.size > 0 && (
<span className="text-gray-400 flex-shrink-0">{formatFileSize(att.size)}</span>
)}
</a>
))}
</div>
</div>
);
}
|