<feed xmlns='http://www.w3.org/2005/Atom'>
<title>albumen.git, branch main</title>
<subtitle>Ruby/Sinatra photo album</subtitle>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/'/>
<entry>
<title>Add per-photo rotate-left/right widget to admin edit page</title>
<updated>2026-06-18T23:00:17+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-18T23:00:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=6f975533f075cc761184b5a7392522264eca6fc1'/>
<id>6f975533f075cc761184b5a7392522264eca6fc1</id>
<content type='text'>
Many older photos (especially pre-EXIF-orientation cameras) are off
by a multiple of 90 degrees with no metadata to auto-correct. Each
image row in the admin file table now has rotate buttons that
physically rotate the file (auto-orienting first to normalize any
existing EXIF tag), swap the stored width/height, and clear the
cached thumbnail so it regenerates from the corrected image.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Many older photos (especially pre-EXIF-orientation cameras) are off
by a multiple of 90 degrees with no metadata to auto-correct. Each
image row in the admin file table now has rotate buttons that
physically rotate the file (auto-orienting first to normalize any
existing EXIF tag), swap the stored width/height, and clear the
cached thumbnail so it regenerates from the corrected image.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Detect and fix non-4:2:0 chroma in H.264 MP4s during transcode</title>
<updated>2026-06-18T22:33:09+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-18T22:33:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=faec9c5448dfe3bbb7e187c7fb4d58557b70035d'/>
<id>faec9c5448dfe3bbb7e187c7fb4d58557b70035d</id>
<content type='text'>
Browsers only decode H.264 4:2:0 (Baseline/Main/High). Files reported
as codec_name=h264 could still be High 4:2:2/4:4:4 profile if an
earlier transcode pass (or the source) used non-standard chroma —
ffprobe/ffmpeg read these fine, but real browsers reject them as
unsupported. update.rb now also checks pix_fmt and re-transcodes if
it isn't yuv420p/yuvj420p, and forces -pix_fmt yuv420p on output so
this can't recur.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Browsers only decode H.264 4:2:0 (Baseline/Main/High). Files reported
as codec_name=h264 could still be High 4:2:2/4:4:4 profile if an
earlier transcode pass (or the source) used non-standard chroma —
ffprobe/ffmpeg read these fine, but real browsers reject them as
unsupported. update.rb now also checks pix_fmt and re-transcodes if
it isn't yuv420p/yuvj420p, and forces -pix_fmt yuv420p on output so
this can't recur.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Rename global search to "Album Search" and group results by album</title>
<updated>2026-06-18T21:58:04+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-18T21:58:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=c5ec42b2f42e285a95610f1b9b9efba4beef3d7e'/>
<id>c5ec42b2f42e285a95610f1b9b9efba4beef3d7e</id>
<content type='text'>
Photo search was returning every individual matching photo, which
was overkill for what's meant to be a quick way to find an album.
/search now groups matches by album (cover thumbnail + match count)
instead of listing each photo, and is relabeled "Album Search"
throughout the UI.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Photo search was returning every individual matching photo, which
was overkill for what's meant to be a quick way to find an album.
/search now groups matches by album (cover thumbnail + match count)
instead of listing each photo, and is relabeled "Album Search"
throughout the UI.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix transcoded video playback in lightbox and slideshow</title>
<updated>2026-06-18T21:57:44+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-18T21:57:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=462e0081cc9062beb29530e84d15edf2003802db'/>
<id>462e0081cc9062beb29530e84d15edf2003802db</id>
<content type='text'>
The HEVC-to-H.264 transcode kept the original file as a hidden
(non-admin) entry with transcoded_to set, but the lightbox &lt;video&gt;
element and the slideshow always pointed at the original file's URL.
Opening a transcoded video (e.g. via a direct ?photo= link) tried to
play the unsupported original codec instead of the browser-compatible
copy.

- album.erb/album.js: lightbox video now plays the transcoded file
  when present, while the "Download Original" link still serves the
  true original.
- all_media_entries: slideshow skips transcoded originals entirely
  since it has no separate download path.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The HEVC-to-H.264 transcode kept the original file as a hidden
(non-admin) entry with transcoded_to set, but the lightbox &lt;video&gt;
element and the slideshow always pointed at the original file's URL.
Opening a transcoded video (e.g. via a direct ?photo= link) tried to
play the unsupported original codec instead of the browser-compatible
copy.

- album.erb/album.js: lightbox video now plays the transcoded file
  when present, while the "Download Original" link still serves the
  true original.
- all_media_entries: slideshow skips transcoded originals entirely
  since it has no separate download path.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add "move to new person" bulk action</title>
<updated>2026-06-18T21:57:30+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-18T21:57:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=547b51c0ec6be8786eea625423d24f0ae1a884c0'/>
<id>547b51c0ec6be8786eea625423d24f0ae1a884c0</id>
<content type='text'>
People bulk-move previously required moving members into an existing
person, the pool, or the blacklist; this adds a "new person" target
that creates a fresh cluster from the selected faces.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
People bulk-move previously required moving members into an existing
person, the pool, or the blacklist; this adds a "new person" target
that creates a fresh cluster from the selected faces.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Exclude transcoded originals from video count for non-admins</title>
<updated>2026-06-16T19:24:42+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-16T19:24:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=121e29cecd39112193b7275be343ca0d7c87019a'/>
<id>121e29cecd39112193b7275be343ca0d7c87019a</id>
<content type='text'>
Mirrors the browse page filter: files with transcoded_to set are hidden
from unprivileged users, so the album video badge now matches what they
actually see.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Mirrors the browse page filter: files with transcoded_to set are hidden
from unprivileged users, so the album video badge now matches what they
actually see.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Split album count into separate photo and video counts</title>
<updated>2026-06-16T19:18:45+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-16T19:18:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=7eff38478b64cb67de9599f4239705a3afbb183a'/>
<id>7eff38478b64cb67de9599f4239705a3afbb183a</id>
<content type='text'>
Replace media_count helper with media_counts returning {photos, videos}.
Album overview shows photo count as before, plus a coloured ▶ N badge
only when an album (or its sub-albums) contains videos.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Replace media_count helper with media_counts returning {photos, videos}.
Album overview shows photo count as before, plus a coloured ▶ N badge
only when an album (or its sub-albums) contains videos.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Transcode HEVC/non-H264 MP4 files to H.264 for browser compatibility</title>
<updated>2026-06-16T19:09:54+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-16T19:09:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=612afca9f70e65de8b6511b7b0c008e563313a39'/>
<id>612afca9f70e65de8b6511b7b0c008e563313a39</id>
<content type='text'>
Firefox has no HEVC support. Pixel 9a (and newer phones) record video
in HEVC by default. update.rb now probes the codec of every .mp4/.m4v
file via ffprobe and transcodes non-web-friendly codecs (anything not
h264/vp8/vp9/av1) to H.264 MP4 with a .h264.mp4 suffix, same as the
existing MOV→MP4 flow. The original is kept and hidden from non-admins.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Firefox has no HEVC support. Pixel 9a (and newer phones) record video
in HEVC by default. update.rb now probes the codec of every .mp4/.m4v
file via ffprobe and transcodes non-web-friendly codecs (anything not
h264/vp8/vp9/av1) to H.264 MP4 with a .h264.mp4 suffix, same as the
existing MOV→MP4 flow. The original is kept and hidden from non-admins.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix OG image for photo links: use thumbnail, drop false dimension tags</title>
<updated>2026-06-16T18:58:34+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-16T18:58:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=f2095eeb14db8db6558812225e5a0638d9fc9cd0'/>
<id>f2095eeb14db8db6558812225e5a0638d9fc9cd0</id>
<content type='text'>
When ?photo= is in the URL, @og_use_media was forcing the full-res
image (2-3MB) as the og:image. WhatsApp fetched it but showed no
preview, likely due to size or timeout. Now uses the thumbnail.

Also removed hardcoded og:image:width/height (1200x630) from individual
photo/album pages — those dimensions only apply to the default fallback
image and were causing WhatsApp to reject previews when the actual image
dimensions didn't match the declared ones.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When ?photo= is in the URL, @og_use_media was forcing the full-res
image (2-3MB) as the og:image. WhatsApp fetched it but showed no
preview, likely due to size or timeout. Now uses the thumbnail.

Also removed hardcoded og:image:width/height (1200x630) from individual
photo/album pages — those dimensions only apply to the default fallback
image and were causing WhatsApp to reject previews when the actual image
dimensions didn't match the declared ones.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix WhatsApp/OG link previews: https URLs and correct image dimensions</title>
<updated>2026-06-16T18:43:26+00:00</updated>
<author>
<name>Ken D'Ambrosio</name>
<email>ken@jots.org</email>
</author>
<published>2026-06-16T18:43:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.jots.org/albumen.git/commit/?id=a0803c8e87f375b1f138c7d1650ba21108f1cc62'/>
<id>a0803c8e87f375b1f138c7d1650ba21108f1cc62</id>
<content type='text'>
nginx was sending X-Forwarded-Proto: http (its own scheme) rather than
https (the edge scheme), so og:url and og:image were http:// URLs.
Fixed by hardcoding https in the nginx proxy_set_header since HTTPS is
always terminated at the upstream Apache router.

Added a 1200x630 landscape og-default.png (WhatsApp requires ~1.91:1
ratio) and explicit og:image:width/height meta tags. Also tracks the
nginx site config in the repo.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
nginx was sending X-Forwarded-Proto: http (its own scheme) rather than
https (the edge scheme), so og:url and og:image were http:// URLs.
Fixed by hardcoding https in the nginx proxy_set_header since HTTPS is
always terminated at the upstream Apache router.

Added a 1200x630 landscape og-default.png (WhatsApp requires ~1.91:1
ratio) and explicit og:image:width/height meta tags. Also tracks the
nginx site config in the repo.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
