Add support for multiple images from Twitter links

- Fetch all images from Twitter syndication API (photos array)
- Store images with unified 'image' media type (first = thumbnail by ID order)
- Display multi-image tweets in grid layout on detail page
- Add hover cycling through images on home grid (2s interval)
- Show image count indicator on multi-image items
- Extract shared downloadAndStoreImages() helper for create/refresh
- Add migration to convert existing thumbnail/gallery types to image
- Make images clickable to open in new tab on detail page
This commit is contained in:
soup 2026-01-17 13:28:20 -05:00
parent e917e67930
commit 007e167707
Signed by: soup
SSH key fingerprint: SHA256:GYxje8eQkJ6HZKzVWDdyOUF1TyDiprruGhE0Ym8qYDY
9 changed files with 625 additions and 403 deletions

View file

@ -22,13 +22,14 @@ const (
// VideoInfo contains information about an embedded video.
type VideoInfo struct {
Provider Provider
VideoID string
Title string
Description string
ThumbnailURL string
EmbedHTML string
VideoURL string // Direct video URL (for Twitter videos)
Provider Provider
VideoID string
Title string
Description string
ThumbnailURL string // First/primary thumbnail (for backward compatibility)
ThumbnailURLs []string // All thumbnail URLs (for multi-image tweets)
EmbedHTML string
VideoURL string // Direct video URL (for Twitter videos)
}
var (
@ -164,8 +165,13 @@ func fetchTwitter(ctx context.Context, tweetID string, originalURL string) (*Vid
// Find thumbnail and video URL from media
var thumbnailURL, videoURL string
var thumbnailURLs []string
if len(tweet.Photos) > 0 {
thumbnailURL = tweet.Photos[0].URL
// Collect all photo URLs for multi-image tweets
for _, photo := range tweet.Photos {
thumbnailURLs = append(thumbnailURLs, photo.URL)
}
} else if len(tweet.MediaDetails) > 0 {
media := tweet.MediaDetails[0]
thumbnailURL = media.MediaURLHTTPS
@ -201,13 +207,14 @@ func fetchTwitter(ctx context.Context, tweetID string, originalURL string) (*Vid
description = strings.TrimSpace(description)
return &VideoInfo{
Provider: ProviderTwitter,
VideoID: tweetID,
Title: title,
Description: description,
ThumbnailURL: thumbnailURL,
VideoURL: videoURL,
EmbedHTML: embedHTML,
Provider: ProviderTwitter,
VideoID: tweetID,
Title: title,
Description: description,
ThumbnailURL: thumbnailURL,
ThumbnailURLs: thumbnailURLs,
VideoURL: videoURL,
EmbedHTML: embedHTML,
}, nil
}