From bc60e4c42a29fcecb944f1ca5fa7d68d12d083ff Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Mon, 22 Jun 2026 11:06:56 +0300 Subject: Reuse the album tile grid for stats mini-album galleries (DRY) The per-camera and per-filter stats mini-album galleries rendered their own plain img.thumb grid, so they did not get the dynamic tiles. Make them reuse the album's shared grid builder instead. Generalize append_preview_grid (and build_tile_block / build_subdivided_tile / build_preview_thumbnail) to take an href_prefix rather than a page number: the main album passes "-" (view pages "-.html") and the stats mini-albums pass "" (view pages bare ".html") -- the only difference between the two grids. The duplicate _stats_filter_thumbnail is removed; _stats_build_filter_thumbs now calls append_preview_grid, and camera.tmpl wraps the result in the same thumbs-grid container. Stats galleries now get the identical 2x2 feature tiles, subdivided sub-thumbnails, entry animations and hover effects as the main overview. Co-Authored-By: Claude Opus 4.8 --- src/lib/album-render.source.sh | 55 +++++++++++++++++++++--------------- src/lib/stats-filter-album.source.sh | 45 +++++++++++++---------------- 2 files changed, 52 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/lib/album-render.source.sh b/src/lib/album-render.source.sh index d97d05f..6770b86 100644 --- a/src/lib/album-render.source.sh +++ b/src/lib/album-render.source.sh @@ -115,8 +115,10 @@ render_full_preview_page() { # also groups the page's photos into tiles (some subdivided into smaller # thumbnails), so the per-page ordering and preview numbering stay here. local preview_thumbs='' + # The main album's view pages are "-.html", so the + # shared grid builder gets "-" as the href prefix. append_preview_grid preview_thumbs \ - "$thumbs_dir" "$backhref" "$page_num" "$@" + "$thumbs_dir" "$backhref" "$page_num-" "$@" template previewpage "$page_name.html" \ html_dir "$html_dir" \ preview_thumbs "$preview_thumbs" @@ -183,19 +185,22 @@ queue_preview_page_render_job() { render_job_labels_ref["$!"]="template render job for preview $page_name" } -# Build a page's whole thumbnail-grid buffer by walking its photos and grouping +# Build a whole thumbnail-grid buffer by walking a list of photos and grouping # them into tiles. Most tiles are a single square thumbnail, but (controlled by -# THUMB_SUBDIVIDE_PERCENT) some are subdivided into several smaller thumbnails -# packed into the same square footprint. Each photo keeps its 1-based page -# position as its preview number (subdivision only groups CONSECUTIVE photos -# visually, never reorders them), so the view-page links stay correct. Tile -# blocks are separated by a single newline; the previewpage template adds the -# trailing newline, matching the old per-thumbnail rendering. +# THUMB_FEATURE_PERCENT / THUMB_SUBDIVIDE_PERCENT) some become a 2x2 feature tile +# or are subdivided into several smaller thumbnails. Each photo keeps its 1-based +# position as its preview number (tiling only groups CONSECUTIVE photos visually, +# never reorders them), so the view-page links stay correct. The view-page link +# is "${href_prefix}${preview_num}.html": the main album passes "-"; the +# stats mini-albums pass "" (their view pages are bare ".html"). This is +# the single shared grid builder for both the main preview pages and the stats +# mini-album galleries. Tile blocks are separated by a single newline; the +# template adds the trailing newline. append_preview_grid() { local -n buffer_ref="$1"; shift local -r thumbs_dir="$1"; shift local -r backhref="$1"; shift - local -r page_num="$1"; shift + local -r href_prefix="$1"; shift local -a photos=("$@") local -i i=0 local -i count @@ -209,7 +214,7 @@ append_preview_grid() { tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" ) block=$(build_tile_block \ - "$thumbs_dir" "$backhref" "$page_num" "$layout" "$(( i + 1 ))" \ + "$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$(( i + 1 ))" \ "${photos[@]:i:count}") if [ -z "$buffer_ref" ]; then buffer_ref="$block" @@ -277,7 +282,7 @@ tile_layout_for() { build_tile_block() { local -r thumbs_dir="$1"; shift local -r backhref="$1"; shift - local -r page_num="$1"; shift + local -r href_prefix="$1"; shift local -r layout="$1"; shift local -ri start_preview="$1"; shift local -a photos=("$@") @@ -293,13 +298,13 @@ build_tile_block() { anchor_class='feature' fi build_preview_thumbnail \ - "$thumbs_dir" "$backhref" "$page_num" "$start_preview" \ + "$thumbs_dir" "$backhref" "$href_prefix" "$start_preview" \ "${photos[0]}" "$animation_class" thumb "$anchor_class" return ;; esac build_subdivided_tile \ - "$thumbs_dir" "$backhref" "$page_num" "$layout" "$start_preview" \ + "$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$start_preview" \ "${photos[@]}" } @@ -315,7 +320,7 @@ build_tile_block() { build_subdivided_tile() { local -r thumbs_dir="$1"; shift local -r backhref="$1"; shift - local -r page_num="$1"; shift + local -r href_prefix="$1"; shift local -r layout="$1"; shift local -ri start_preview="$1"; shift local -a photos=("$@") @@ -334,7 +339,7 @@ build_subdivided_tile() { for (( k = 0; k < ${#photos[@]}; k++ )); do animation_class=$(random_animation_css_class slow "${photos[k]}") build_preview_thumbnail \ - "$thumbs_dir" "$backhref" "$page_num" "$(( start_preview + k ))" \ + "$thumbs_dir" "$backhref" "$href_prefix" "$(( start_preview + k ))" \ "${photos[k]}" "$animation_class" subthumb "${anchor_classes[k]:-}" printf '\n' done @@ -343,15 +348,19 @@ build_subdivided_tile() { # Render the HTML for a single preview thumbnail (HTML-escaping every value the # way preview.tmpl's context_html fields did). Returned without a trailing -# newline so callers control separators. img_class defaults to 'thumb' (the full -# square); subdivided tiles pass 'subthumb'. anchor_class is an optional extra -# class on the ('wide' marks the full-width strip inside a subdivided tile); -# when empty the has no class attribute, keeping the single-tile output -# byte-identical to before. +# newline so callers control separators. The view-page link is +# "${href_prefix}${preview_num}.html", so the main album passes "-" and +# the stats mini-albums (whose view pages are bare ".html") pass "" -- the +# only thing that differs between the two grids, keeping one shared builder. +# img_class defaults to 'thumb' (the full square); subdivided tiles pass +# 'subthumb'. anchor_class is an optional extra class on the ('wide' marks the +# full-width strip inside a subdivided tile, 'feature' a 2x2 hero tile); when empty +# the has no class attribute, keeping the single-tile output byte-identical to +# before. build_preview_thumbnail() { local -r thumbs_dir="$1"; shift local -r backhref="$1"; shift - local -r page_num="$1"; shift + local -r href_prefix="$1"; shift local -r preview_num="$1"; shift local -r photo_file="$1"; shift local -r animation_class="$1"; shift @@ -371,10 +380,10 @@ build_preview_thumbnail() { anchor_class_html=$(_html_escape "$anchor_class") printf '\n' \ "'$photo_html'" "'$anchor_class_html'" \ - "'$page_num-$preview_num.html'" + "'${href_prefix}${preview_num}.html'" else printf '\n' \ - "'$photo_html'" "'$page_num-$preview_num.html'" + "'$photo_html'" "'${href_prefix}${preview_num}.html'" fi printf " %s\n" \ "$img_class" "$anim_html" "$photo_html" "$backhref_html" \ diff --git a/src/lib/stats-filter-album.source.sh b/src/lib/stats-filter-album.source.sh index 49eb390..eedb474 100644 --- a/src/lib/stats-filter-album.source.sh +++ b/src/lib/stats-filter-album.source.sh @@ -38,40 +38,35 @@ declare -gr STATS_DIR='stats' # the album root (dist/), used for shared assets and album links. declare -gr STATS_FILTER_BACKHREF='../..' -# Emit one thumbnail anchor for a filter gallery: a thumb image (from thumbs/) -# linking to this filter's view page for that photo (--.html). -# The photo filename is HTML-escaped; the pagebase and index are filename-safe. -_stats_filter_thumbnail() { - local -r backhref_html="$1"; shift - local -ri index="$1"; shift - local -r photo="$1"; shift - local photo_html - local animation_class - - photo_html=$(_html_escape "$photo") - # Same seeded animation the album thumbnail uses for this photo. - animation_class=$(random_animation_css_class slow "$photo") - # The view page sits in the same directory as this gallery, so link to it by - # bare index; the thumbnail image lives at the album root via backhref. - printf ' ' "$photo_html" "$index" - printf '%s\n' \ - "$animation_class" "$photo_html" "$backhref_html" "$STATS_THUMBS_DIR" "$photo_html" -} - # Build the full thumbnail grid for one filter from its newline-separated photo # list, preserving aggregation (encounter) order for deterministic output. +# +# This reuses the album's shared grid builder (append_preview_grid), so a filter +# mini-album gallery gets EXACTLY the same tiles as the main overview: 2x2 +# feature tiles, subdivided tiles with sub-thumbnails, the seeded entry +# animations and the dramatic hover. The only mini-album-specific detail is the +# link target -- its view pages are bare ".html" in the same directory -- +# so the href prefix is empty (the main album passes "-"). The +# thumbnail images come from the shared thumbs/ dir, reached via the gallery's +# backhref (../..). The result is wrapped by camera.tmpl in the same +#
container the main pages use. _stats_build_filter_thumbs() { local -r backhref_html="$1"; shift local -r photos="$1"; shift + local -a photo_list=() local photo - local -i index=0 + local thumbs='' while IFS= read -r photo; do - if [ -n "$photo" ]; then - (( ++index )) - _stats_filter_thumbnail "$backhref_html" "$index" "$photo" - fi + [ -n "$photo" ] && photo_list+=("$photo") done <<< "$photos" + + if (( ${#photo_list[@]} == 0 )); then + return + fi + append_preview_grid thumbs \ + "$STATS_THUMBS_DIR" "$backhref_html" '' "${photo_list[@]}" + printf '%s\n' "$thumbs" } # Render a filter gallery page (.html): header + camera.tmpl (heading + -- cgit v1.2.3