From 4664206e77c0331cd827a4cfa1e400d4e2922105 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Sat, 7 Sep 2024 14:11:33 +0200 Subject: [PATCH] feat(post): show media dimensions if available --- .../comment-media/comment-media.tsx | 6 ++- src/components/post-desktop/post-desktop.tsx | 7 ++- src/lib/utils/media-utils.ts | 43 ++++++++++++++++++- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/components/comment-media/comment-media.tsx b/src/components/comment-media/comment-media.tsx index ebdaf4ec..96464484 100644 --- a/src/components/comment-media/comment-media.tsx +++ b/src/components/comment-media/comment-media.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Comment } from '@plebbit/plebbit-react-hooks'; import styles from './comment-media.module.css'; -import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../lib/utils/media-utils'; +import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils'; import { getHostname } from '../../lib/utils/url-utils'; import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; import useIsMobile from '../../hooks/use-is-mobile'; @@ -109,6 +109,7 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => { const { thumbnail, type, url } = commentMediaInfo || {}; const isMobile = useIsMobile(); const mediaClass = isMobile ? styles.mediaMobile : isReply ? styles.mediaDesktopReply : styles.mediaDesktopOp; + const mediaDimensions = getMediaDimensions(commentMediaInfo); return ( @@ -128,7 +129,8 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => { {url && url.length > 30 ? url.slice(0, 30) + '...' : url} {' '} - ({getDisplayMediaInfoType(type, t)}) + ({getDisplayMediaInfoType(type, t)} + {mediaDimensions && `, ${mediaDimensions}`}) )} {isMobile && (type === 'iframe' || type === 'video' || type === 'audio') && ( diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 7b5ed3c9..a1b536c5 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -4,7 +4,7 @@ import { Link, useLocation, useParams } from 'react-router-dom'; import { Comment, useAccount, useAuthorAvatar, useComment, useEditedComment } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from '../../views/post/post.module.css'; -import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../lib/utils/media-utils'; +import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils'; import { hashStringToColor, getTextColorForBackground } from '../../lib/utils/post-utils'; import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { isValidURL } from '../../lib/utils/url-utils'; @@ -229,6 +229,8 @@ const PostMedia = ({ post }: PostProps) => { const hasThumbnail = getHasThumbnail(commentMediaInfo, link); const [showThumbnail, setShowThumbnail] = useState(true); + const mediaDimensions = getMediaDimensions(commentMediaInfo); + return (
@@ -236,7 +238,8 @@ const PostMedia = ({ post }: PostProps) => { {spoiler ? _.capitalize(t('spoiler')) : url && url.length > 30 ? url.slice(0, 30) + '...' : url} {' '} - ({type && _.lowerCase(getDisplayMediaInfoType(type, t))}) + ({type && _.lowerCase(getDisplayMediaInfoType(type, t))} + {mediaDimensions && `, ${mediaDimensions}`}) {!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && ( {' '} diff --git a/src/lib/utils/media-utils.ts b/src/lib/utils/media-utils.ts index dd676416..61f879a8 100644 --- a/src/lib/utils/media-utils.ts +++ b/src/lib/utils/media-utils.ts @@ -9,6 +9,7 @@ export interface CommentMediaInfo { type: string; thumbnail?: string; patternThumbnailUrl?: string; + post?: Comment; } export const getDisplayMediaInfoType = (type: string, t: any) => { @@ -106,8 +107,46 @@ export const getCommentMediaInfo = (comment: Comment): CommentMediaInfo | undefi } const linkInfo = comment.link ? getLinkMediaInfo(comment.link) : undefined; if (linkInfo) { - linkInfo.thumbnail = comment.thumbnailUrl || linkInfo.thumbnail; - return linkInfo; + return { + ...linkInfo, + thumbnail: comment.thumbnailUrl || linkInfo.thumbnail, + post: comment, + }; } return; }; + +export const getMediaDimensions = (commentMediaInfo: CommentMediaInfo | undefined): string => { + if (!commentMediaInfo) return ''; + + const { type, url, post } = commentMediaInfo; + + if (type === 'iframe' && url) { + const embedUrl = new URL(url); + if (canEmbed(embedUrl)) { + // hardcoded dimensions from embed.module.css + if (embedUrl.hostname.includes('youtube.com') || embedUrl.hostname.includes('youtu.be')) { + return '800x450'; + } else if (embedUrl.hostname.includes('instagram.com')) { + return '360x420'; + } else if (embedUrl.hostname.includes('reddit.com')) { + return '500x520'; + } else if (embedUrl.hostname.includes('tiktok.com')) { + return '400x780'; + } else if (embedUrl.hostname.includes('x.com') || embedUrl.hostname.includes('twitter.com')) { + return '550x580'; + } else if (embedUrl.hostname.includes('soundcloud.com')) { + return '700x166'; + } + } + } else if (type === 'audio') { + return '700x240'; // hardcoded dimensions from embed.module.css + } else if (type === 'image' || type === 'video' || type === 'gif') { + // media dimensions calculated by API + if (post?.linkWidth && post?.linkHeight) { + return `${post.linkWidth}x${post.linkHeight}`; + } + } + + return ''; +};