From de1547d26119c19ae8f29ed0537b74aca89c1f34 Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 29 Mar 2024 13:54:11 +0100 Subject: [PATCH] add media component --- src/components/media/index.ts | 1 + src/components/media/media.module.css | 31 ++++++++++ src/components/media/media.tsx | 83 +++++++++++++++++++++++++ src/components/post/post.module.css | 27 +++++++- src/components/post/post.tsx | 46 ++++++++++---- src/hooks/use-fetch-gif-first-frame.ts | 85 ++++++++++++++++++++++++++ src/themes.css | 4 ++ 7 files changed, 263 insertions(+), 14 deletions(-) create mode 100644 src/components/media/index.ts create mode 100644 src/components/media/media.module.css create mode 100644 src/components/media/media.tsx create mode 100644 src/hooks/use-fetch-gif-first-frame.ts diff --git a/src/components/media/index.ts b/src/components/media/index.ts new file mode 100644 index 00000000..dd4f5658 --- /dev/null +++ b/src/components/media/index.ts @@ -0,0 +1 @@ +export { Thumbnail, Media } from './media'; diff --git a/src/components/media/media.module.css b/src/components/media/media.module.css new file mode 100644 index 00000000..0da43d01 --- /dev/null +++ b/src/components/media/media.module.css @@ -0,0 +1,31 @@ +.thumbnail { + float: left; + padding: 3px 20px 5px 0; + width: var(--width, 250px); + height: var(--height, 250px); +} + +.thumbnailHidden { + display: none; +} + +.thumbnailVisible { + display: block; +} + +.thumbnailWrapper { + background-color: var(--background-thumbnail); + height: 250px; + width: 250px; + display: inline-block; +} + +.transparentThumbnailWrapper { + background-color: transparent; + opacity: 1; +} + +.thumbnail img, .thumbnail video { + width: 100%; + height: 100%; +} diff --git a/src/components/media/media.tsx b/src/components/media/media.tsx new file mode 100644 index 00000000..7e4fff97 --- /dev/null +++ b/src/components/media/media.tsx @@ -0,0 +1,83 @@ +import styles from './media.module.css'; +import { Link } from 'react-router-dom'; +import { CommentMediaInfo } from '../../lib/utils/media-utils'; +import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; + +interface ThumbnailProps { + cid?: string; + commentMediaInfo?: CommentMediaInfo; + expanded?: boolean; + isReply: boolean; + link: string; + linkHeight?: number; + linkWidth?: number; + subplebbitAddress?: string; + toggleExpanded?: () => void; +} + +export const Thumbnail = ({ + cid, + commentMediaInfo, + expanded = false, + isReply = false, + link, + linkHeight, + linkWidth, + subplebbitAddress, + toggleExpanded, +}: ThumbnailProps) => { + const iframeThumbnail = commentMediaInfo?.patternThumbnailUrl || commentMediaInfo?.thumbnail; + let displayWidth, displayHeight, hasLinkDimensions; + const routeOrLink = isReply ? link : `/p/${subplebbitAddress}/c/${cid}`; + const thumbnailClass = expanded ? styles.thumbnailHidden : styles.thumbnailVisible; + + if (linkWidth && linkHeight) { + let scale = Math.min(1, 250 / Math.max(linkWidth, linkHeight)); + displayWidth = `${linkWidth * scale}px`; + displayHeight = `${linkHeight * scale}px`; + hasLinkDimensions = true; + } else { + displayWidth = '250px'; + displayHeight = '250px'; + hasLinkDimensions = false; + } + + const style = hasLinkDimensions ? ({ '--width': displayWidth, '--height': displayHeight } as React.CSSProperties) : {}; + + let mediaComponent = null; + const gifFrameUrl = useFetchGifFirstFrame(commentMediaInfo?.type === 'gif' ? commentMediaInfo.url : undefined); + + if (commentMediaInfo?.type === 'image') { + mediaComponent = ; + } else if (commentMediaInfo?.type === 'video') { + mediaComponent = commentMediaInfo.thumbnail ? :