import React from 'react';
import type { Attachment } from '@backspace/shared';
import { useUIStore } from '../../stores/uiStore';
import { Tooltip } from '../ui/Tooltip';
interface AttachmentRendererProps {
attachment: Attachment;
}
function formatFileSize(bytes: number): string {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / 1048576).toFixed(1)} MB`;
}
export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
const openImagePreview = useUIStore((s) => s.openImagePreview);
const attUrl =
attachment.filename.startsWith('http') || attachment.filename.startsWith('/')
? attachment.filename
: `/api/uploads/${attachment.filename}`;
const thumbUrl = attachment.thumbnailFilename
? attachment.thumbnailFilename.startsWith('http') || attachment.thumbnailFilename.startsWith('/')
? attachment.thumbnailFilename
: `/api/uploads/${attachment.thumbnailFilename}`
: null;
const { mimetype, originalName, size } = attachment;
// Federation status — build tooltip text
const federationTooltip = (() => {
if (!attachment.federationStatus) return null;
if (attachment.federationStatus === 'remote') {
let senderName = 'the sender';
if (attachment.federationMeta) {
try {
const meta = JSON.parse(attachment.federationMeta);
if (meta.sourceUsername) senderName = meta.sourceUsername;
} catch { /* ignore */ }
}
return { text: `Hosted on ${senderName}'s instance. Download to keep a local copy.`, type: 'remote' as const };
}
if (attachment.federationStatus === 'remote_partial') {
let text = 'Some recipients cannot cache this file locally.';
if (attachment.federationMeta) {
try {
const meta: Array<{ username: string; limit: number }> = JSON.parse(attachment.federationMeta);
if (meta.length > 0) {
const parts = meta.map(u => {
const limitMb = Math.round(u.limit / (1024 * 1024));
return `${u.username}'s instance (limit: ${limitMb} MB)`;
});
text = `File couldn't be cached on ${parts.join(' and ')}. They can still view it from yours.`;
}
} catch { /* ignore */ }
}
return { text, type: 'remote_partial' as const };
}
return null;
})();
// Inline badge — sits next to file size or below media, never absolute-positioned
const federationInlineBadge = federationTooltip ? (
{originalName}
{formatFileSize(size)}
{federationInlineBadge}{originalName}
{formatFileSize(size)}
{federationInlineBadge}