fix(federation): use inline badge for all attachment types

Overlay badges inside overflow-hidden containers (images, video)
were invisible. Use inline badges below the media for all types.
This commit is contained in:
Jannis Braun
2026-03-27 05:20:58 +01:00
parent dd3ddd9cc2
commit c5c7ab571a
@@ -64,21 +64,7 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
return null; return null;
})(); })();
// Overlay badge for media (images/video) — absolute positioned inside overflow-hidden container // Inline badge — sits next to file size or below media, never absolute-positioned
const federationOverlayBadge = federationTooltip ? (
<Tooltip content={federationTooltip.text} position="top">
<div className={`absolute top-2 right-2 flex items-center gap-1 px-1.5 py-0.5 rounded glass-pill text-xs ${federationTooltip.type === 'remote' ? 'text-txt-muted' : 'text-accent-amber'}`}>
<svg className="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
{federationTooltip.type === 'remote'
? <path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
: <><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" /><line x1="12" y1="9" x2="12" y2="13" /><line x1="12" y1="17" x2="12.01" y2="17" /></>
}
</svg>
</div>
</Tooltip>
) : null;
// Inline badge for file cards (audio/generic) — sits inside the card layout, not absolute
const federationInlineBadge = federationTooltip ? ( const federationInlineBadge = federationTooltip ? (
<Tooltip content={federationTooltip.text} position="top"> <Tooltip content={federationTooltip.text} position="top">
<div className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded glass-pill text-xs cursor-default ${federationTooltip.type === 'remote' ? 'text-txt-muted' : 'text-accent-amber'}`}> <div className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded glass-pill text-xs cursor-default ${federationTooltip.type === 'remote' ? 'text-txt-muted' : 'text-accent-amber'}`}>
@@ -95,8 +81,9 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
if (mimetype.startsWith('image/')) { if (mimetype.startsWith('image/')) {
const { width, height } = attachment; const { width, height } = attachment;
return ( return (
<div className="mt-1 max-w-fit">
<div <div
className="relative max-w-fit mt-1 rounded-lg overflow-hidden border border-white/[0.06]" className="relative rounded-lg overflow-hidden border border-white/[0.06]"
style={width && height ? { aspectRatio: `${width}/${height}`, maxWidth: Math.min(width, 400), maxHeight: 300 } : undefined} style={width && height ? { aspectRatio: `${width}/${height}`, maxWidth: Math.min(width, 400), maxHeight: 300 } : undefined}
> >
<img <img
@@ -106,7 +93,8 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
onClick={() => openImagePreview(attUrl)} onClick={() => openImagePreview(attUrl)}
loading="lazy" loading="lazy"
/> />
{federationOverlayBadge} </div>
{federationInlineBadge && <div className="mt-1">{federationInlineBadge}</div>}
</div> </div>
); );
} }
@@ -115,8 +103,9 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
const { width, height } = attachment; const { width, height } = attachment;
const hasDimensions = width && height; const hasDimensions = width && height;
return ( return (
<div className="mt-1 max-w-[400px]">
<div <div
className="relative mt-1 max-w-[400px] max-h-[300px] rounded-lg overflow-hidden" className="relative max-h-[300px] rounded-lg overflow-hidden"
style={hasDimensions ? { aspectRatio: `${width}/${height}`, maxHeight: 300 } : undefined} style={hasDimensions ? { aspectRatio: `${width}/${height}`, maxHeight: 300 } : undefined}
> >
<video <video
@@ -128,7 +117,8 @@ export function AttachmentRenderer({ attachment }: AttachmentRendererProps) {
<source src={attUrl} type={mimetype} /> <source src={attUrl} type={mimetype} />
Your browser does not support video playback. Your browser does not support video playback.
</video> </video>
{federationOverlayBadge} </div>
{federationInlineBadge && <div className="mt-1">{federationInlineBadge}</div>}
</div> </div>
); );
} }