Add gallery admin and video media support.

This updates gallery handling to support video playback with generated poster thumbnails, adds authenticated admin upload/delete flows, and improves dev/runtime behavior including reliable thumbnail generation and media-safe response handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 23:01:02 +12:00
parent 509e7ccb43
commit 45b31be9a7
22 changed files with 1002 additions and 217 deletions

View File

@@ -31,6 +31,9 @@ templ GalleryGrid(images []gallery.Image) {
} else {
<span class="gallery-placeholder" aria-hidden="true"></span>
}
if img.IsVideo {
<span class="gallery-video-badge" aria-hidden="true">Video</span>
}
if img.Collection != "" {
<span class="gallery-album">{ img.Collection }</span>
} else if img.Album != "" {
@@ -49,7 +52,7 @@ templ ImageModal(img gallery.Image, prevPath, nextPath string) {
class="modal-backdrop"
hx-on:click="if (event.target === this) this.remove()"
>
<div class="modal" role="dialog" aria-modal="true" aria-label="Image viewer">
<div class="modal" role="dialog" aria-modal="true" aria-label={ modalAriaLabel(img) }>
<button
type="button"
class="modal-close"
@@ -59,7 +62,11 @@ templ ImageModal(img gallery.Image, prevPath, nextPath string) {
&times;
</button>
<figure class="modal-figure">
<img src={ img.URL } alt={ img.Filename }/>
if img.IsVideo {
<video src={ img.URL } controls playsinline preload="metadata"></video>
} else {
<img src={ img.URL } alt={ img.Filename }/>
}
if !img.Date.IsZero() {
<figcaption>{ modalCaption(img) }</figcaption>
}
@@ -98,7 +105,14 @@ func formatDate(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("2 Jan 2006")
return t.Format("Jan 2006")
}
func modalAriaLabel(img gallery.Image) string {
if img.IsVideo {
return "Video viewer"
}
return "Image viewer"
}
func modalCaption(img gallery.Image) string {