diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-15 13:26:28 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-15 23:50:40 +0300 |
| commit | 6e47246dbbc97821b97aa9c45352abc9c2a9aa4a (patch) | |
| tree | aa893f4ef633f76faab5731313de2d694a1de94e /src | |
| parent | 3adeaa68af3bac73450a4156edb51fd1ec88347a (diff) | |
Stats/camera pages: blurred background, album-like camera thumbs, spacing
Three refinements to the stats site:
- Stats and per-camera pages now get a random blurred background image (same
seeded pick the album preview pages use) instead of a plain black page. Adds
_stats_random_background + STATS_BLURS_DIR; falls back to black when no photos
exist (e.g. isolated unit tests).
- Per-camera thumbnails now behave like the main album: they link to each
photo's album view page (navigation, details, EXIF tooltip) and carry the same
seeded animation class, instead of linking to the raw image. render_album_pages
records a photo -> "<page>-<preview>" map (ALBUM_VIEW_PAGE_BY_PHOTO) that the
camera pages read; photos with no recorded view page fall back to the image.
- Spacing: the camera leaderboard rows get padding + a separator line so the long
wrapping camera names are distinguishable, and the stats sections, headings,
bar rows, back-link, and camera grid get moderate extra spacing so nothing
looks cramped.
Tests updated for the new camera-thumbnail markup and extended to assert the
stats background and the album view-page links; camera.tmpl comment corrected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/album.source.sh | 15 | ||||
| -rw-r--r-- | src/lib/stats.source.sh | 63 |
2 files changed, 67 insertions, 11 deletions
diff --git a/src/lib/album.source.sh b/src/lib/album.source.sh index 4914642..65282f1 100644 --- a/src/lib/album.source.sh +++ b/src/lib/album.source.sh @@ -1,3 +1,10 @@ +# Maps each album photo filename to its view-page basename ("<page>-<preview>") +# as assigned during render_album_pages. The stats camera pages read this so +# their thumbnails link into the album view (with navigation, details, and the +# EXIF tooltip) exactly like the main album, instead of the raw image. Declared +# globally so it always exists for callers even when no album was rendered. +declare -gA ALBUM_VIEW_PAGE_BY_PHOTO=() + album_photo_files() { local -r photos_dir="$1"; shift @@ -741,6 +748,10 @@ render_album_pages() { # shellcheck disable=SC2034 local -a rendered_view_pages=() + # Rebuild the photo -> view-page map for this album from scratch so a + # re-generate (or a smaller incoming set) does not keep stale entries. + ALBUM_VIEW_PAGE_BY_PHOTO=() + name=$(album_page_name "$num") start_preview_page \ @@ -785,6 +796,10 @@ render_album_pages() { render_failed record_rendered_view_page rendered_view_pages rendered_last_views \ "$num" "$i" + # Read later by the stats camera pages (render_camera_pages); shellcheck + # cannot see that cross-function use. + # shellcheck disable=SC2034 + ALBUM_VIEW_PAGE_BY_PHOTO["$photo"]="$num-$i" done < <(album_photo_files "$photos_dir") finish_preview_page "$name" "$html_dir" "$backhref" "$tarball_name" diff --git a/src/lib/stats.source.sh b/src/lib/stats.source.sh index b0a1646..527ea1f 100644 --- a/src/lib/stats.source.sh +++ b/src/lib/stats.source.sh @@ -614,15 +614,22 @@ _stats_bar_row() { } # Open a <section> with an escaped heading and the <ul> bar container. Split from -# the row emitters so every section shares identical chrome. +# the row emitters so every section shares identical chrome. An optional second +# argument adds an extra CSS class to the <ul> (e.g. the leaderboard uses it to +# space out and separate its rows of long, wrapping camera names). _stats_section_open() { local -r heading="$1"; shift + local -r list_class="${1:-}" local heading_html + local ul_class='stats-bars' + if [ -n "$list_class" ]; then + ul_class+=" $list_class" + fi heading_html=$(_html_escape "$heading") printf '<section class="stats-section">\n' printf '<h2>%s</h2>\n' "$heading_html" - printf '<ul class="stats-bars">\n' + printf '<ul class="%s">\n' "$ul_class" } _stats_section_close() { @@ -645,7 +652,7 @@ _stats_render_camera_section() { return fi max=$(_stats_max_count STATS_CAMERAS) - _stats_section_open 'Camera leaderboard' + _stats_section_open 'Camera leaderboard' 'stats-leaderboard' while IFS= read -r label; do label_html=$(_html_escape "$label") slug="${STATS_CAMERA_SLUGS[$label]}" @@ -824,18 +831,31 @@ _stats_build_body() { # html_dir is the dist-relative output directory (top-level album: "."), # backhref is the relative path back to the album root ("." for a top-level # stats.html), and page_name defaults to "stats" -> stats.html. +# Pick a seeded-random photo for a stats/camera page's blurred background, the +# same way the album preview pages do. The context seeds the choice so each page +# gets a stable (per RANDOM_SEED) but varied background. Degrades to an empty +# string (plain black background) when no photos exist, e.g. unit tests that +# render the page without a populated photos directory. +_stats_random_background() { + local -r context="$1"; shift + + randomphoto "$STATS_CAMERA_PHOTOS_DIR" "$context" 2>/dev/null || true +} + render_stats_page() { local -r html_dir="$1"; shift local -r backhref="$1"; shift local -r page_name="${1:-stats}" local stats_body + local background_image stats_body=$(_stats_build_body) + background_image=$(_stats_random_background "$page_name.html") template header "$page_name.html" \ html_dir "$html_dir" \ backhref "$backhref" \ - blurs_dir '' \ - background_image '' \ + blurs_dir "$STATS_BLURS_DIR" \ + background_image "$background_image" \ show_header_bar 'yes' template stats "$page_name.html" \ html_dir "$html_dir" \ @@ -874,6 +894,9 @@ render_stats_page() { # pages link to the same assets the album pages do. declare -gr STATS_CAMERA_PHOTOS_DIR='photos' declare -gr STATS_CAMERA_THUMBS_DIR='thumbs' +# Dist-relative directory of blurred images used for the page background, the +# same one render_album_pages passes to the album preview pages. +declare -gr STATS_BLURS_DIR='blurs' # Emit one thumbnail anchor for the camera grid: a thumb image (from thumbs/) # wrapped in a link to the full-size image (from photos/), both resolved through @@ -884,12 +907,28 @@ _stats_camera_thumbnail() { local -r backhref_html="$1"; shift local -r photo="$1"; shift local photo_html + local animation_class + local view_page photo_html=$(_html_escape "$photo") - printf ' <a href="%s/%s/%s">' \ - "$backhref_html" "$STATS_CAMERA_PHOTOS_DIR" "$photo_html" - printf '<img class="thumb" src="%s/%s/%s" /></a>\n' \ - "$backhref_html" "$STATS_CAMERA_THUMBS_DIR" "$photo_html" + # Same seeded animation the album thumbnail uses for this photo, so camera + # pages animate identically. + animation_class=$(random_animation_css_class slow "$photo") + # Link to the photo's album view page (navigation, details, EXIF tooltip) + # so a camera page behaves exactly like the main album. Fall back to the + # full-size image when the album mapping is unknown (e.g. unit tests that + # render camera pages without a rendered album). + view_page="${ALBUM_VIEW_PAGE_BY_PHOTO[$photo]:-}" + if [ -n "$view_page" ]; then + printf ' <a name="%s" href="%s/%s.html">' \ + "$photo_html" "$backhref_html" "$view_page" + else + printf ' <a href="%s/%s/%s">' \ + "$backhref_html" "$STATS_CAMERA_PHOTOS_DIR" "$photo_html" + fi + printf '<img class="thumb %s" src="%s/%s/%s" /></a>\n' \ + "$animation_class" "$backhref_html" "$STATS_CAMERA_THUMBS_DIR" \ + "$photo_html" } # Build the full thumbnail grid for one camera from its newline-separated photo @@ -919,15 +958,17 @@ _stats_render_camera_page() { local -r photos="$1"; shift local backhref_html local camera_thumbs + local background_image local -r page="camera-$slug.html" backhref_html=$(_html_escape "$backhref") camera_thumbs=$(_stats_build_camera_thumbs "$backhref_html" "$photos") + background_image=$(_stats_random_background "$page") template header "$page" \ html_dir "$html_dir" \ backhref "$backhref" \ - blurs_dir '' \ - background_image '' \ + blurs_dir "$STATS_BLURS_DIR" \ + background_image "$background_image" \ show_header_bar 'yes' template camera "$page" \ html_dir "$html_dir" \ |
