summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/shuriken57
-rw-r--r--share/templates/default/header.tmpl10
-rw-r--r--src/lib/album-render.source.sh8
-rw-r--r--src/lib/album-thumbnail-html.source.sh24
-rw-r--r--src/lib/album-tile-layout.source.sh21
-rw-r--r--src/lib/stats-filter-album.source.sh4
6 files changed, 104 insertions, 20 deletions
diff --git a/bin/shuriken b/bin/shuriken
index 72adeb8..9a27dd7 100755
--- a/bin/shuriken
+++ b/bin/shuriken
@@ -2927,9 +2927,12 @@ _grid_merge_singles_to_remove() {
# Render one tile's markup (no trailing newline). A "single" tile is the plain
# square thumbnail, byte-identical to the previous per-thumbnail output. A
# "feature" tile is the same single thumbnail but with the 'feature' anchor class
-# that makes CSS span it across a 2x2 block. Any other layout is a subdivided
-# tile. The tile's photos are the trailing args and their preview numbers run
-# from start_preview upward.
+# that makes CSS span it across a 2x2 block. A "fill" tile is one thumbnail with
+# the 'fill-row' anchor class that spans the WHOLE row (grid-column: 1 / -1) at
+# any breakpoint -- used for the leftover photo on the album's short final page so
+# its bottom edge is flush instead of an orphaned corner. Any other layout is a
+# subdivided tile. The tile's photos are the trailing args and their preview
+# numbers run from start_preview upward.
build_tile_block() {
local -r thumbs_dir="$1"; shift
local -r backhref="$1"; shift
@@ -2940,14 +2943,16 @@ build_tile_block() {
local animation_class
case "$layout" in
- single|feature)
+ single|feature|fill)
animation_class=$(random_animation_css_class slow "${photos[0]}")
# 'single' -> no anchor class (legacy output); 'feature' -> the
- # 'feature' anchor class CSS spans across a 2x2 grid block.
+ # 'feature' anchor class CSS spans a 2x2 block; 'fill' -> the
+ # 'fill-row' anchor class spans the whole row at any column count.
local anchor_class=''
- if [ "$layout" = feature ]; then
- anchor_class='feature'
- fi
+ case "$layout" in
+ feature) anchor_class='feature' ;;
+ fill) anchor_class='fill-row' ;;
+ esac
build_preview_thumbnail \
"$thumbs_dir" "$backhref" "$href_prefix" "$start_preview" \
"${photos[0]}" "$animation_class" thumb "$anchor_class"
@@ -3034,6 +3039,11 @@ append_preview_grid() {
local -r thumbs_dir="$1"; shift
local -r backhref="$1"; shift
local -r href_prefix="$1"; shift
+ # 'yes' only for the main album's LAST page: when such a page cannot be
+ # aligned to a multiple of 12 (a short final page with a leftover photo), its
+ # final single tile is widened to span the whole row so the bottom stays
+ # flush. Callers that must not do this (stats mini-albums) pass 'no'.
+ local -r fill_last="$1"; shift
local -a photos=("$@")
local -i i=0
local -i count
@@ -3077,6 +3087,25 @@ append_preview_grid() {
_align_page_tiles_to_grid \
tile_layouts tile_starts tile_counts "$total_cells"
+ # Pass 2b: if this is the album's last page and it still could not be aligned
+ # to a multiple of 12 (a short final page), widen its final single tile to a
+ # full-row "fill" tile so the bottom edge is flush at every breakpoint instead
+ # of an orphaned corner. Recompute the post-alignment cell total first.
+ if [ "$fill_last" = yes ] && (( ${#tile_layouts[@]} > 0 )); then
+ local -i aligned_cells=0
+ for (( t = 0; t < ${#tile_layouts[@]}; t++ )); do
+ if [ "${tile_layouts[t]}" = feature ]; then
+ (( aligned_cells += 4 ))
+ else
+ (( ++aligned_cells ))
+ fi
+ done
+ local -i last=$(( ${#tile_layouts[@]} - 1 ))
+ if (( aligned_cells % 12 != 0 )) && [ "${tile_layouts[last]}" = single ]; then
+ tile_layouts[last]=fill
+ fi
+ fi
+
# Pass 3: emit the tile blocks in order.
for (( t = 0; t < ${#tile_layouts[@]}; t++ )); do
block=$(build_tile_block \
@@ -3355,10 +3384,16 @@ 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 album's last page (no "next" link) is the only one allowed to widen a
+ # leftover final tile to a full row, so a short final page stays flush.
+ local fill_last='no'
+ if [ -z "$next_page" ]; then
+ fill_last='yes'
+ fi
# The main album's view pages are "<page_num>-<preview_num>.html", so the
# shared grid builder gets "<page_num>-" as the href prefix.
append_preview_grid preview_thumbs \
- "$thumbs_dir" "$backhref" "$page_num-" "$@"
+ "$thumbs_dir" "$backhref" "$page_num-" "$fill_last" "$@"
template previewpage "$page_name.html" \
html_dir "$html_dir" \
preview_thumbs "$preview_thumbs"
@@ -5060,8 +5095,10 @@ _stats_build_filter_thumbs() {
if (( ${#photo_list[@]} == 0 )); then
return
fi
+ # 'no' fill_last: stats mini-albums never widen a leftover tile to a full row
+ # (that orphan-final-page treatment is for the main album only).
append_preview_grid thumbs \
- "$STATS_THUMBS_DIR" "$backhref_html" '' "${photo_list[@]}"
+ "$STATS_THUMBS_DIR" "$backhref_html" '' no "${photo_list[@]}"
printf '%s\n' "$thumbs"
}
diff --git a/share/templates/default/header.tmpl b/share/templates/default/header.tmpl
index c0a0fac..5d1b2e6 100644
--- a/share/templates/default/header.tmpl
+++ b/share/templates/default/header.tmpl
@@ -247,6 +247,16 @@ cat <<END
grid-row: span 2;
}
+ /* A "fill-row" tile spans the whole row at ANY column count
+ (grid-column: 1 / -1). Used for the single leftover photo on the
+ album's short final page so the bottom edge stays flush at every
+ breakpoint instead of an orphaned corner; object-fit: cover crops it
+ to the wide banner shape without distortion. */
+ div.thumbs-grid a.fill-row {
+ grid-column: 1 / -1;
+ aspect-ratio: 3 / 1;
+ }
+
/* A subdivided thumbnail tile fills one grid cell with its own 2x2 inner
grid packing several smaller thumbnails. Anchor order + the "wide"
class (a full-width strip spanning both columns) produce the quad /
diff --git a/src/lib/album-render.source.sh b/src/lib/album-render.source.sh
index 4c65f69..fa8173f 100644
--- a/src/lib/album-render.source.sh
+++ b/src/lib/album-render.source.sh
@@ -121,10 +121,16 @@ 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 album's last page (no "next" link) is the only one allowed to widen a
+ # leftover final tile to a full row, so a short final page stays flush.
+ local fill_last='no'
+ if [ -z "$next_page" ]; then
+ fill_last='yes'
+ fi
# The main album's view pages are "<page_num>-<preview_num>.html", so the
# shared grid builder gets "<page_num>-" as the href prefix.
append_preview_grid preview_thumbs \
- "$thumbs_dir" "$backhref" "$page_num-" "$@"
+ "$thumbs_dir" "$backhref" "$page_num-" "$fill_last" "$@"
template previewpage "$page_name.html" \
html_dir "$html_dir" \
preview_thumbs "$preview_thumbs"
diff --git a/src/lib/album-thumbnail-html.source.sh b/src/lib/album-thumbnail-html.source.sh
index add5f36..d9f17db 100644
--- a/src/lib/album-thumbnail-html.source.sh
+++ b/src/lib/album-thumbnail-html.source.sh
@@ -34,6 +34,11 @@ append_preview_grid() {
local -r thumbs_dir="$1"; shift
local -r backhref="$1"; shift
local -r href_prefix="$1"; shift
+ # 'yes' only for the main album's LAST page: when such a page cannot be
+ # aligned to a multiple of 12 (a short final page with a leftover photo), its
+ # final single tile is widened to span the whole row so the bottom stays
+ # flush. Callers that must not do this (stats mini-albums) pass 'no'.
+ local -r fill_last="$1"; shift
local -a photos=("$@")
local -i i=0
local -i count
@@ -77,6 +82,25 @@ append_preview_grid() {
_align_page_tiles_to_grid \
tile_layouts tile_starts tile_counts "$total_cells"
+ # Pass 2b: if this is the album's last page and it still could not be aligned
+ # to a multiple of 12 (a short final page), widen its final single tile to a
+ # full-row "fill" tile so the bottom edge is flush at every breakpoint instead
+ # of an orphaned corner. Recompute the post-alignment cell total first.
+ if [ "$fill_last" = yes ] && (( ${#tile_layouts[@]} > 0 )); then
+ local -i aligned_cells=0
+ for (( t = 0; t < ${#tile_layouts[@]}; t++ )); do
+ if [ "${tile_layouts[t]}" = feature ]; then
+ (( aligned_cells += 4 ))
+ else
+ (( ++aligned_cells ))
+ fi
+ done
+ local -i last=$(( ${#tile_layouts[@]} - 1 ))
+ if (( aligned_cells % 12 != 0 )) && [ "${tile_layouts[last]}" = single ]; then
+ tile_layouts[last]=fill
+ fi
+ fi
+
# Pass 3: emit the tile blocks in order.
for (( t = 0; t < ${#tile_layouts[@]}; t++ )); do
block=$(build_tile_block \
diff --git a/src/lib/album-tile-layout.source.sh b/src/lib/album-tile-layout.source.sh
index cbddb6d..3d0fa23 100644
--- a/src/lib/album-tile-layout.source.sh
+++ b/src/lib/album-tile-layout.source.sh
@@ -228,9 +228,12 @@ _grid_merge_singles_to_remove() {
# Render one tile's markup (no trailing newline). A "single" tile is the plain
# square thumbnail, byte-identical to the previous per-thumbnail output. A
# "feature" tile is the same single thumbnail but with the 'feature' anchor class
-# that makes CSS span it across a 2x2 block. Any other layout is a subdivided
-# tile. The tile's photos are the trailing args and their preview numbers run
-# from start_preview upward.
+# that makes CSS span it across a 2x2 block. A "fill" tile is one thumbnail with
+# the 'fill-row' anchor class that spans the WHOLE row (grid-column: 1 / -1) at
+# any breakpoint -- used for the leftover photo on the album's short final page so
+# its bottom edge is flush instead of an orphaned corner. Any other layout is a
+# subdivided tile. The tile's photos are the trailing args and their preview
+# numbers run from start_preview upward.
build_tile_block() {
local -r thumbs_dir="$1"; shift
local -r backhref="$1"; shift
@@ -241,14 +244,16 @@ build_tile_block() {
local animation_class
case "$layout" in
- single|feature)
+ single|feature|fill)
animation_class=$(random_animation_css_class slow "${photos[0]}")
# 'single' -> no anchor class (legacy output); 'feature' -> the
- # 'feature' anchor class CSS spans across a 2x2 grid block.
+ # 'feature' anchor class CSS spans a 2x2 block; 'fill' -> the
+ # 'fill-row' anchor class spans the whole row at any column count.
local anchor_class=''
- if [ "$layout" = feature ]; then
- anchor_class='feature'
- fi
+ case "$layout" in
+ feature) anchor_class='feature' ;;
+ fill) anchor_class='fill-row' ;;
+ esac
build_preview_thumbnail \
"$thumbs_dir" "$backhref" "$href_prefix" "$start_preview" \
"${photos[0]}" "$animation_class" thumb "$anchor_class"
diff --git a/src/lib/stats-filter-album.source.sh b/src/lib/stats-filter-album.source.sh
index aac6834..cc4cf2e 100644
--- a/src/lib/stats-filter-album.source.sh
+++ b/src/lib/stats-filter-album.source.sh
@@ -64,8 +64,10 @@ _stats_build_filter_thumbs() {
if (( ${#photo_list[@]} == 0 )); then
return
fi
+ # 'no' fill_last: stats mini-albums never widen a leftover tile to a full row
+ # (that orphan-final-page treatment is for the main album only).
append_preview_grid thumbs \
- "$STATS_THUMBS_DIR" "$backhref_html" '' "${photo_list[@]}"
+ "$STATS_THUMBS_DIR" "$backhref_html" '' no "${photo_list[@]}"
printf '%s\n' "$thumbs"
}