summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-22 18:22:04 +0300
committerPaul Buetow <paul@buetow.org>2026-06-22 18:22:04 +0300
commit63fbea196e34c0783526980973f33fc1b82cbe71 (patch)
tree5c57a490103dceba8bed2bef8f59467f9cbcc1f5
parent2b654d68bc450b50cfdc091912b67b0786acc57c (diff)
Cap the 2x2 feature tiles at two per page
Each tile rolled for a feature independently, so a page (or stats gallery) could fill up with large 2x2 hero tiles. append_preview_grid now counts the features it has placed and stops offering the "feature" layout to tile_layout_for once two have been used, so any single grid gets at most two feature tiles; later tiles fall back to subdivided or single. The cap is per append_preview_grid call, so it applies to both the main preview pages and the stats mini-album galleries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rwxr-xr-xbin/shuriken38
-rw-r--r--src/lib/album-render.source.sh38
2 files changed, 54 insertions, 22 deletions
diff --git a/bin/shuriken b/bin/shuriken
index b2b5dc0..8c85bb8 100755
--- a/bin/shuriken
+++ b/bin/shuriken
@@ -2643,13 +2643,23 @@ append_preview_grid() {
local -i count
local layout
local block
+ # Cap the big 2x2 feature tiles at this many per page; once reached, later
+ # tiles are no longer offered the "feature" layout (they fall back to
+ # subdivided/single), so a page never gets crowded with hero tiles.
+ local -ri max_features=2
+ local -i features_used=0
while (( i < ${#photos[@]} )); do
# Decide this tile's layout from the photos still available; the first
# photo's name is the seeded-random context so the choice is stable.
+ # Features are only offered until the per-page cap is reached.
read -r layout count < <(
- tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}"
+ tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" \
+ "$(( features_used < max_features ? 1 : 0 ))"
)
+ if [ "$layout" = feature ]; then
+ (( ++features_used ))
+ fi
block=$(build_tile_block \
"$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$(( i + 1 ))" \
"${photos[@]:i:count}")
@@ -2662,26 +2672,32 @@ append_preview_grid() {
done
}
-# Decide the layout for the next tile, printing "<layout> <photo-count>". Each
-# tile rolls first for a "feature" (one photo blown up to a 2x2 hero tile) with
-# THUMB_FEATURE_PERCENT probability, then for a subdivision with
+# Decide the layout for the next tile, printing "<layout> <photo-count>". When
+# feature_allowed is non-zero each tile rolls first for a "feature" (one photo
+# blown up to a 2x2 hero tile) with THUMB_FEATURE_PERCENT probability; the caller
+# clears feature_allowed once a page has reached its per-page feature-tile cap
+# (see append_preview_grid). Otherwise the tile rolls for a subdivision with
# THUMB_SUBDIVIDE_PERCENT probability (only into a layout that fits the photos
-# still remaining on the page); otherwise it is a single square thumbnail. The
+# still remaining on the page); failing both it is a single square thumbnail. The
# feature and subdivide rolls use independent seeded random_index namespaces, so
-# builds stay reproducible when RANDOM_SEED is set (and varied otherwise).
+# builds stay reproducible when RANDOM_SEED is set.
tile_layout_for() {
local -ri remaining="$1"; shift
local -r context="$1"; shift
+ local -ri feature_allowed="$1"; shift
local -a names=(two_wide)
local -a counts=(2)
local -i roll choice
# A feature tile always fits (it consumes a single photo), so roll for it
- # first. THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0).
- roll=$(random_index "feature:$context" 100)
- if (( roll < THUMB_FEATURE_PERCENT )); then
- printf 'feature 1\n'
- return
+ # first -- but only while the page has not used its one allowed feature.
+ # THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0).
+ if (( feature_allowed )); then
+ roll=$(random_index "feature:$context" 100)
+ if (( roll < THUMB_FEATURE_PERCENT )); then
+ printf 'feature 1\n'
+ return
+ fi
fi
# A single tile when subdivision is disabled, too few photos remain to fill
diff --git a/src/lib/album-render.source.sh b/src/lib/album-render.source.sh
index 6770b86..3024923 100644
--- a/src/lib/album-render.source.sh
+++ b/src/lib/album-render.source.sh
@@ -206,13 +206,23 @@ append_preview_grid() {
local -i count
local layout
local block
+ # Cap the big 2x2 feature tiles at this many per page; once reached, later
+ # tiles are no longer offered the "feature" layout (they fall back to
+ # subdivided/single), so a page never gets crowded with hero tiles.
+ local -ri max_features=2
+ local -i features_used=0
while (( i < ${#photos[@]} )); do
# Decide this tile's layout from the photos still available; the first
# photo's name is the seeded-random context so the choice is stable.
+ # Features are only offered until the per-page cap is reached.
read -r layout count < <(
- tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}"
+ tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" \
+ "$(( features_used < max_features ? 1 : 0 ))"
)
+ if [ "$layout" = feature ]; then
+ (( ++features_used ))
+ fi
block=$(build_tile_block \
"$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$(( i + 1 ))" \
"${photos[@]:i:count}")
@@ -225,26 +235,32 @@ append_preview_grid() {
done
}
-# Decide the layout for the next tile, printing "<layout> <photo-count>". Each
-# tile rolls first for a "feature" (one photo blown up to a 2x2 hero tile) with
-# THUMB_FEATURE_PERCENT probability, then for a subdivision with
+# Decide the layout for the next tile, printing "<layout> <photo-count>". When
+# feature_allowed is non-zero each tile rolls first for a "feature" (one photo
+# blown up to a 2x2 hero tile) with THUMB_FEATURE_PERCENT probability; the caller
+# clears feature_allowed once a page has reached its per-page feature-tile cap
+# (see append_preview_grid). Otherwise the tile rolls for a subdivision with
# THUMB_SUBDIVIDE_PERCENT probability (only into a layout that fits the photos
-# still remaining on the page); otherwise it is a single square thumbnail. The
+# still remaining on the page); failing both it is a single square thumbnail. The
# feature and subdivide rolls use independent seeded random_index namespaces, so
-# builds stay reproducible when RANDOM_SEED is set (and varied otherwise).
+# builds stay reproducible when RANDOM_SEED is set.
tile_layout_for() {
local -ri remaining="$1"; shift
local -r context="$1"; shift
+ local -ri feature_allowed="$1"; shift
local -a names=(two_wide)
local -a counts=(2)
local -i roll choice
# A feature tile always fits (it consumes a single photo), so roll for it
- # first. THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0).
- roll=$(random_index "feature:$context" 100)
- if (( roll < THUMB_FEATURE_PERCENT )); then
- printf 'feature 1\n'
- return
+ # first -- but only while the page has not used its one allowed feature.
+ # THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0).
+ if (( feature_allowed )); then
+ roll=$(random_index "feature:$context" 100)
+ if (( roll < THUMB_FEATURE_PERCENT )); then
+ printf 'feature 1\n'
+ return
+ fi
fi
# A single tile when subdivision is disabled, too few photos remain to fill