diff --git a/assets/reader.css b/assets/reader.css index 2e11659..432882c 100644 --- a/assets/reader.css +++ b/assets/reader.css @@ -2537,3 +2537,45 @@ margin: 0 0.05em; } +/* Gallery items — positioned for ALT badge overlay */ +.ap-card__gallery-item { + position: relative; +} + +/* ALT text badges */ +.ap-media__alt-badge { + position: absolute; + bottom: 0.5rem; + left: 0.5rem; + background: rgba(0, 0, 0, 0.7); + color: white; + font-size: 0.65rem; + font-weight: 700; + padding: 0.15rem 0.35rem; + border-radius: var(--border-radius-small); + border: none; + cursor: pointer; + text-transform: uppercase; + letter-spacing: 0.03em; + z-index: 1; +} + +.ap-media__alt-badge:hover { + background: rgba(0, 0, 0, 0.9); +} + +.ap-media__alt-text { + position: absolute; + bottom: 2.2rem; + left: 0.5rem; + right: 0.5rem; + background: rgba(0, 0, 0, 0.85); + color: white; + font-size: var(--font-size-s); + padding: 0.5rem; + border-radius: var(--border-radius-small); + max-height: 8rem; + overflow-y: auto; + z-index: 2; +} + diff --git a/lib/controllers/explore-utils.js b/lib/controllers/explore-utils.js index 03a95a6..197ee94 100644 --- a/lib/controllers/explore-utils.js +++ b/lib/controllers/explore-utils.js @@ -84,7 +84,14 @@ export function mapMastodonStatusToItem(status, instance) { const url = att.url || att.remote_url || ""; if (!url) continue; if (att.type === "image" || att.type === "gifv") { - photo.push(url); + photo.push({ + url, + alt: att.description || "", + width: att.meta?.original?.width || null, + height: att.meta?.original?.height || null, + blurhash: att.blurhash || "", + focus: att.meta?.focus || null, + }); } else if (att.type === "video") { video.push(url); } else if (att.type === "audio") { @@ -144,7 +151,12 @@ export function mapMastodonStatusToItem(status, instance) { for (const att of q.media_attachments || []) { const attUrl = att.url || att.remote_url || ""; if (attUrl && (att.type === "image" || att.type === "gifv")) { - qPhoto.push(attUrl); + qPhoto.push({ + url: attUrl, + alt: att.description || "", + width: att.meta?.original?.width || null, + height: att.meta?.original?.height || null, + }); } } diff --git a/lib/timeline-store.js b/lib/timeline-store.js index 714de76..e843ccb 100644 --- a/lib/timeline-store.js +++ b/lib/timeline-store.js @@ -256,7 +256,12 @@ export async function extractObjectData(object, options = {}) { const mediaType = att.mediaType?.toLowerCase() || ""; if (mediaType.startsWith("image/")) { - photo.push(mediaUrl); + photo.push({ + url: mediaUrl, + alt: att.name?.toString() || "", + width: att.width || null, + height: att.height || null, + }); } else if (mediaType.startsWith("video/")) { video.push(mediaUrl); } else if (mediaType.startsWith("audio/")) { diff --git a/package.json b/package.json index cc32142..e84f176 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "2.5.2", + "version": "2.5.3", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "keywords": [ "indiekit", diff --git a/views/partials/ap-item-media.njk b/views/partials/ap-item-media.njk index 33adefd..c19def0 100644 --- a/views/partials/ap-item-media.njk +++ b/views/partials/ap-item-media.njk @@ -6,14 +6,23 @@ {% set extraCount = item.photo.length - 4 %} {% set totalPhotos = item.photo.length %} {% endif %} {% endfor %} @@ -24,7 +33,9 @@ {% if totalPhotos > 1 %} {% endif %} - + {% if totalPhotos > 1 %}
diff --git a/views/partials/ap-quote-embed.njk b/views/partials/ap-quote-embed.njk index 15d1a24..66466ef 100644 --- a/views/partials/ap-quote-embed.njk +++ b/views/partials/ap-quote-embed.njk @@ -25,8 +25,9 @@
{{ item.quote.content.html | safe }}
{% endif %} {% if item.quote.photo and item.quote.photo.length > 0 %} + {% set qPhoto = item.quote.photo[0] %}
- + {{ qPhoto.alt if qPhoto.alt else '' }}
{% endif %}