diff --git a/index.js b/index.js index f1e2094..fa6e228 100644 --- a/index.js +++ b/index.js @@ -110,8 +110,9 @@ export default async function now() { return `${updatedOpenTag}${displayText}${closeTag}` }) - // replace image placeholders if image is available, otherwise remove img tags + // replace image/video placeholders if available, otherwise remove tags const imageId = `${item.id}-image` + const videoId = `${item.id}-video` if (latest.image) { // html image replacement newNow = newNow.replace( @@ -135,6 +136,20 @@ export default async function now() { '', ) } + + if (latest.video) { + // html video replacement + newNow = newNow.replace( + new RegExp(`(]+src=["'])${videoId}(["'][^>]*>)`, 'gi'), + `$1${latest.video}$2`, + ) + } else { + // remove video tags if no video available + newNow = newNow.replace( + new RegExp(`]*src=["']${videoId}["'][^>]*>[\\s\\S]*?`, 'gi'), + '', + ) + } } } catch (e) { console.warn(`⚠️ Failed to fetch ${item.id}`, e) diff --git a/utils.js b/utils.js index b78ded9..d12d1e8 100644 --- a/utils.js +++ b/utils.js @@ -150,11 +150,25 @@ export async function getMastodonPost(config) { const link = item.querySelector('link')?.textContent.trim() - // extract image from media:content or description html + // extract media from media:content or description html // check for media:content (mastodon uses this for attachments) const mediaContent = item.getElementsByTagName('media:content')[0] - let image = mediaContent?.getAttribute('url') || null - if (!image) { + let image = null + let video = null + + if (mediaContent) { + const mediaUrl = mediaContent.getAttribute('url') + const mediaType = mediaContent.getAttribute('type') + // check if it's a video or image + if (mediaType?.startsWith('video/')) { + video = mediaUrl + } else if (mediaType?.startsWith('image/')) { + image = mediaUrl + } + } + + // fallback to img tags in description html + if (!image && !video) { const imgMatch = description.match(/]+src="([^"]+)"/) image = imgMatch ? imgMatch[1] : null } @@ -168,7 +182,12 @@ export async function getMastodonPost(config) { // replace URLs with a link emoji cleanText = cleanText.replace(/https?:\/\/\S+/g, '🔗').trim() - return { text: cleanText, url: link, image: showImage ? image : null } + return { + text: cleanText, + url: link, + image: showImage ? image : null, + video: showImage ? video : null, + } } // fallback to first item if no non-reply found @@ -176,11 +195,25 @@ export async function getMastodonPost(config) { const description = firstItem.querySelector('description')?.textContent || '' const link = firstItem.querySelector('link')?.textContent.trim() - // extract image from media:content or description html + // extract media from media:content or description html // check for media:content (mastodon uses this for attachments) const mediaContent = firstItem.getElementsByTagName('media:content')[0] - let image = mediaContent?.getAttribute('url') || null - if (!image) { + let image = null + let video = null + + if (mediaContent) { + const mediaUrl = mediaContent.getAttribute('url') + const mediaType = mediaContent.getAttribute('type') + // check if it's a video or image + if (mediaType?.startsWith('video/')) { + video = mediaUrl + } else if (mediaType?.startsWith('image/')) { + image = mediaUrl + } + } + + // fallback to img tags in description html + if (!image && !video) { const imgMatch = description.match(/]+src="([^"]+)"/) image = imgMatch ? imgMatch[1] : null } @@ -192,7 +225,12 @@ export async function getMastodonPost(config) { // replace URLs with link emoji cleanText = cleanText.replace(/https?:\/\/\S+/g, '🔗').trim() - return { text: cleanText, url: link, image: showImage ? image : null } + return { + text: cleanText, + url: link, + image: showImage ? image : null, + video: showImage ? video : null, + } } // ========================================================================