Honor media aspect ratios in masonry cards #3

Merged
salix merged 2 commits from t3code/fix-masonry-media-aspect-ratios into main 2026-10-03 17:45:35 +02:00
Owner

The masonry layout sized every media box from a hash of the post ID ([320, 400, 480, 360][masonry_card_variant(post)]) and cropped the image to fit (ContentFit::Cover), so a 2:3 portrait and a 9:1 panorama both landed in the same shapeless box. Column weights used the same fake heights, so packing ignored what the posts actually looked like.

Reddit listings declare the media's native pixel size, so this carries it through PostSummary (media_width/media_height, serde defaults keep old cached feeds valid) and derives each card's media height from the real aspect ratio against the live column width, clamped to 160–560 px so extremes crop instead of dominating a column. Posts without declared dimensions keep the old varied estimates, which measured heights already replace once rows allocate.

  • core: extract dimensions from preview.images[0].source, the gallery cover's media_metadata.s.x/y, and video rendition sizes, with thumbnail_width/height as a fallback (api.rs)
  • adwaita: masonry_media_height now scales height / width × column width instead of hashing; the same heights drive both the rendered media box and the column-packing weights

Before

before

The stairwell (2:3 portrait) and the square cat photo are cropped into nearly the same flat box as the wide shots.

After

after

Portrait and square media keep their shape and the columns pack by real height.

Tests

  • masonry_media_keeps_the_declared_aspect_ratio (adwaita): portrait fills, panorama clamps, heights scale with column width, unknown/zero dimensions fall back
  • dimension assertions added to the existing image/gallery/video parsing tests (core)

cargo test: core 114 passed, adwaita 75 passed (no-default-features; the default-feature build hits a pre-existing boring-sys/clang issue in this sandbox).

The masonry layout sized every media box from a hash of the post ID (`[320, 400, 480, 360][masonry_card_variant(post)]`) and cropped the image to fit (`ContentFit::Cover`), so a 2:3 portrait and a 9:1 panorama both landed in the same shapeless box. Column weights used the same fake heights, so packing ignored what the posts actually looked like. Reddit listings declare the media's native pixel size, so this carries it through `PostSummary` (`media_width`/`media_height`, serde defaults keep old cached feeds valid) and derives each card's media height from the real aspect ratio against the live column width, clamped to 160–560 px so extremes crop instead of dominating a column. Posts without declared dimensions keep the old varied estimates, which measured heights already replace once rows allocate. - `core`: extract dimensions from `preview.images[0].source`, the gallery cover's `media_metadata.s.x/y`, and video rendition sizes, with `thumbnail_width/height` as a fallback (`api.rs`) - `adwaita`: `masonry_media_height` now scales `height / width × column width` instead of hashing; the same heights drive both the rendered media box and the column-packing weights ### Before ![before](https://git.salix.host/salix/threado/raw/branch/t3code/fix-masonry-media-aspect-ratios/adwaita/screenshots/masonry-aspect-before.png) The stairwell (2:3 portrait) and the square cat photo are cropped into nearly the same flat box as the wide shots. ### After ![after](https://git.salix.host/salix/threado/raw/branch/t3code/fix-masonry-media-aspect-ratios/adwaita/screenshots/masonry-aspect-after.png) Portrait and square media keep their shape and the columns pack by real height. ### Tests - `masonry_media_keeps_the_declared_aspect_ratio` (adwaita): portrait fills, panorama clamps, heights scale with column width, unknown/zero dimensions fall back - dimension assertions added to the existing image/gallery/video parsing tests (core) `cargo test`: core 114 passed, adwaita 75 passed (no-default-features; the default-feature build hits a pre-existing boring-sys/clang issue in this sandbox).
salix merged commit 04c43b95d2 into main 2026-10-03 17:45:35 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
salix/threado!3
No description provided.