diff --git a/src/components/messageStream/utils/albumLayout.ts b/src/components/messageStream/utils/albumLayout.ts index 2ea0488..6d61849 100644 --- a/src/components/messageStream/utils/albumLayout.ts +++ b/src/components/messageStream/utils/albumLayout.ts @@ -34,8 +34,13 @@ export type AlbumLayout = { * Keep ratios within a sane range so one extreme image can't make the whole * mosaic absurdly tall or flat. Beyond this the cell crops (object-cover). */ -function clampRatio(ratio: number | undefined): number { +function safeRatio(ratio: number | undefined): number { if (!ratio || !Number.isFinite(ratio) || ratio <= 0) return 1; + return ratio; +} + +/** Bound a ratio so one extreme image can't make a multi-image mosaic ugly. */ +function clampRatio(ratio: number): number { return Math.min(2, Math.max(0.55, ratio)); } @@ -116,8 +121,11 @@ function layoutPrimaryPlusLine(ratios: number[]): AlbumLayout { export function computeAlbumLayout( rawRatios: (number | undefined)[], ): AlbumLayout | null { - const ratios = rawRatios.map(clampRatio); + const ratios = rawRatios.map(safeRatio); if (ratios.length < 2) return null; + // Two images keep their true ratios so each cell matches its image exactly + // (object-cover then fits with no cropping). 3+ are clamped to keep the + // mosaic tidy. if (ratios.length === 2) return layoutTwo(ratios); - return layoutPrimaryPlusLine(ratios); + return layoutPrimaryPlusLine(ratios.map(clampRatio)); }