From 27f9dbbc4590a69936533922348873daf097ae71 Mon Sep 17 00:00:00 2001 From: TerryM Date: Sat, 30 May 2026 02:25:01 +0800 Subject: [PATCH] fix(album): keep true aspect ratios for two-image layouts Split clampRatio into a sanity-check helper (safeRatio: reject zero / NaN / negatives) and the actual aspect clamp. Two-image albums now keep each image's real ratio so the cells match the images exactly with no object-cover cropping. Three-plus image layouts still clamp ratios to a 0.55-2 band so a single extreme image cannot warp the mosaic. --- src/components/messageStream/utils/albumLayout.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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)); }