diff --git a/src/app/components/message/MsgTypeRenderers.tsx b/src/app/components/message/MsgTypeRenderers.tsx index bec299543..fe7f418ae 100644 --- a/src/app/components/message/MsgTypeRenderers.tsx +++ b/src/app/components/message/MsgTypeRenderers.tsx @@ -417,6 +417,22 @@ type RenderImageContentProps = { markedAsSpoiler?: boolean; spoilerReason?: string; }; +// Media frame sizing. When intrinsic width/height are known, drive the box by +// aspect-ratio so its height tracks the responsive (maxWidth:100%) width — a +// fixed pixel height computed for a 400px-wide layout otherwise crops (images, +// object-fit:cover) or letterboxes (videos, object-fit:contain) on phones where +// the box narrows below 400px. On desktop the box stays 400px wide, so the +// aspect-ratio yields the identical height. Falls back to the fixed height when +// dimensions are unknown. +const attachmentMediaStyle = ( + w: number | undefined, + h: number | undefined, + fallbackHeight: number, +): CSSProperties => + w && h + ? { aspectRatio: `${w} / ${h}`, minHeight: toRem(48) } + : { height: toRem(fallbackHeight < 48 ? 48 : fallbackHeight) }; + type MImageProps = { content: IImageContent; renderImageContent: (props: RenderImageContentProps) => ReactNode; @@ -432,11 +448,7 @@ export function MImage({ content, renderImageContent, outlined }: MImageProps) { return ( - + {renderImageContent({ body: content.body || 'Image', info: imgInfo, @@ -498,11 +510,7 @@ export function MVideo({ content, renderAsFile, renderVideoContent, outlined }: } /> - + {renderVideoContent({ body: content.body || 'Video', info: videoInfo,