diff --git a/src/components/modals/ReplyModal.jsx b/src/components/modals/ReplyModal.jsx index 7a72c837..96fb2235 100755 --- a/src/components/modals/ReplyModal.jsx +++ b/src/components/modals/ReplyModal.jsx @@ -229,8 +229,10 @@ const ReplyModal = ({ isOpen, closeModal }) => { }, [selectedParentCid, anonymousMode, account]); useEffect(() => { - updateSigner(); - }, [updateSigner]); + if (anonymousMode) { + updateSigner(); + } + }, [updateSigner, anonymousMode]); useEffect(() => { diff --git a/src/components/styled/views/Board.styled.jsx b/src/components/styled/views/Board.styled.jsx index 81c3b8c4..c2cb1312 100644 --- a/src/components/styled/views/Board.styled.jsx +++ b/src/components/styled/views/Board.styled.jsx @@ -2016,6 +2016,16 @@ export const BoardForm = styled.div` } video { + width: 100%; + height: auto; + } + + iframe { + width: 100%; + height: auto; + } + + #video-thumbnail-mobile { width: 100px; } @@ -3804,7 +3814,7 @@ export const BoardForm = styled.div` color: #707070; font-weight: 700; background-color: rgb(27,28,30); - border: 1px solid #282A2E; + border: 1px solid #2D2F33; background-image: url(assets/buttonfade-dark.png); background-repeat: repeat-x; text-decoration: none; diff --git a/src/components/styled/views/Thread.styled.jsx b/src/components/styled/views/Thread.styled.jsx index 6c1f8cc2..09b9c343 100644 --- a/src/components/styled/views/Thread.styled.jsx +++ b/src/components/styled/views/Thread.styled.jsx @@ -1193,7 +1193,13 @@ export const BoardForm = styled.div` } video { - width: 100px; + width: 100%; + height: auto; + } + + iframe { + width: 100%; + height: auto; } img { @@ -2932,7 +2938,7 @@ export const BoardForm = styled.div` color: #707070; font-weight: 700; background-color: rgb(27,28,30); - border: 1px solid #282A2E; + border: 1px solid #2D2F33; background-image: url(assets/buttonfade-dark.png); background-repeat: repeat-x; text-decoration: none; diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index a4a4a254..27f960b3 100755 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -102,6 +102,8 @@ const All = () => { const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); + const [isThumbnailClicked, setIsThumbnailClicked] = useState({}); + const [isMobileThumbnailClicked, setIsMobileThumbnailClicked] = useState({}); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; @@ -117,6 +119,20 @@ const All = () => { const stateString = useFeedStateString(subplebbits); + const handleThumbnailClick = (index, isMobile=false) => { + if (isMobile) { + setIsMobileThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } else { + setIsThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } + }; + useEffect(() => { let permissions = {}; @@ -618,56 +634,110 @@ const All = () => {
{comment.content ? ( <> diff --git a/src/components/views/Subscriptions.jsx b/src/components/views/Subscriptions.jsx index 714a72fb..f050e422 100755 --- a/src/components/views/Subscriptions.jsx +++ b/src/components/views/Subscriptions.jsx @@ -102,6 +102,8 @@ const Subscriptions = () => { const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); + const [isThumbnailClicked, setIsThumbnailClicked] = useState({}); + const [isMobileThumbnailClicked, setIsMobileThumbnailClicked] = useState({}); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; @@ -116,6 +118,21 @@ const Subscriptions = () => { const stateString = useFeedStateString(subplebbits); + const handleThumbnailClick = (index, isMobile=false) => { + if (isMobile) { + setIsMobileThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } else { + setIsThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } + }; + + useEffect(() => { let permissions = {}; @@ -628,56 +645,110 @@ const Subscriptions = () => {
{commentMediaInfo?.url ? ( --{thread.link ? ( -- Link: - { - commentMediaInfo?.url.length > 30 ? - commentMediaInfo?.url.slice(0, 30) + "(...)" : - commentMediaInfo?.url - } ({commentMediaInfo?.type}) -- {commentMediaInfo?.type === "webpage" ? ( -- - {thread.thumbnailUrl ? ( ++ ) : null} {thread.title ? ( thread.title.length > 75 ? @@ -1572,51 +1643,108 @@ const Subscriptions = () => {+- ) : null} + ) : null} ++ Link: + { + commentMediaInfo?.url.length > 30 ? + commentMediaInfo?.url.slice(0, 30) + "(...)" : + commentMediaInfo?.url + } ({commentMediaInfo?.type === "iframe" ? "video" : commentMediaInfo?.type}) + {isThumbnailClicked[index] ? ( + + -[ + {handleThumbnailClick(index)}}>Close + ] + + ) : null} ++ {commentMediaInfo?.type === 'iframe' && ( ++ + {(isThumbnailClicked[index] || !commentMediaInfo.thumbnail) && commentMediaInfo.embedUrl ? ( + + ) : ( ++ )} + {commentMediaInfo?.type === "webpage" ? ( +{handleThumbnailClick(index)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} /> + )} + +
+ + {thread.thumbnailUrl ? ( ++ ) : null} + {commentMediaInfo?.type === "image" ? ( +e.target.src = fallbackImgUrl} /> + ) : null} + +
++ ) : null} + {commentMediaInfo?.type === "video" ? ( +e.target.src = fallbackImgUrl} /> - ) : null} + +
+ + {isThumbnailClicked[index] ? ( +- ) : null} - {commentMediaInfo?.type === "image" ? ( -e.target.src = fallbackImgUrl} + /> + ) : ( + {handleThumbnailClick(index)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} + /> + )} + ) : null} + {commentMediaInfo?.type === "audio" ? ( -- ) : null} - {commentMediaInfo?.type === "video" ? ( - -e.target.src = fallbackImgUrl} /> -
e.target.src = fallbackImgUrl} /> - - ) : null} - {commentMediaInfo?.type === "audio" ? ( - -e.target.src = fallbackImgUrl} /> - - ) : null} -- {commentMediaInfo?.url ? ( - commentMediaInfo.type === "webpage" ? ( -+ ) : null} {thread.content ? ( thread.content?.length > 500 ?- - {thread.thumbnailUrl ? ( ++ ) : commentMediaInfo.type === "video" ? ( + + {isMobileThumbnailClicked[index] ? ( ++ {commentMediaInfo?.type === 'iframe' && ( +- ) : null} ++ + {(isMobileThumbnailClicked[index] || !commentMediaInfo.thumbnail) && commentMediaInfo.embedUrl ? ( ++ )} + {commentMediaInfo?.url ? ( + commentMediaInfo.type === "webpage" ? ( ++ ++ ) : ( +{handleThumbnailClick(index, true)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} /> + )} + {commentMediaInfo?.type === "video" || "iframe" ? ( + isMobileThumbnailClicked[index] ? ( +
+ {handleThumbnailClick(index, true)}} + >Close ++ ) : ( +video+ )) :video} + ++ + {thread.thumbnailUrl ? ( ++ ) : commentMediaInfo.type === "image" ? ( +e.target.src = fallbackImgUrl} /> + ) : null} +
{commentMediaInfo?.type}+ ++- ) : commentMediaInfo.type === "image" ? ( -e.target.src = fallbackImgUrl} /> - ) : null} -
{commentMediaInfo?.type}- -- -- ) : commentMediaInfo.type === "video" ? ( - -e.target.src = fallbackImgUrl} /> -
{commentMediaInfo?.type}- -e.target.src = fallbackImgUrl} /> - - ) : commentMediaInfo.type === "audio" ? ( - -{commentMediaInfo?.type}-e.target.src = fallbackImgUrl} /> - - ) : null - ) : null} -{commentMediaInfo?.type}-{commentMediaInfo?.type}+ +e.target.src = fallbackImgUrl} /> + ) : ( + + ) : commentMediaInfo.type === "audio" ? ( + +{handleThumbnailClick(index, true)}} + style={{cursor: "pointer"}} + id="video-thumbnail-mobile" + onError={(e) => e.target.src = fallbackImgUrl} + /> + )} + {commentMediaInfo?.type === "video" || "iframe" ? ( + isMobileThumbnailClicked[index] ? ( + + {handleThumbnailClick(index, true)}} + >Close ++ ) : ( +video+ )) :video} +e.target.src = fallbackImgUrl} /> + + ) : null + ) : null} +{commentMediaInfo?.type}+diff --git a/src/components/views/Thread.jsx b/src/components/views/Thread.jsx index b134cec7..ad7813a3 100755 --- a/src/components/views/Thread.jsx +++ b/src/components/views/Thread.jsx @@ -111,6 +111,8 @@ const Thread = () => { const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); const [executeAnonMode, setExecuteAnonMode] = useState(false); const [cidTracker, setCidTracker] = useState({}); + const [isThumbnailClicked, setIsThumbnailClicked] = useState({}); + const [isMobileThumbnailClicked, setIsMobileThumbnailClicked] = useState({}); useAnonMode(selectedThread, anonymousMode && executeAnonMode); @@ -126,6 +128,21 @@ const Thread = () => { const fallbackImgUrl = "assets/filedeleted-res.gif"; + const handleThumbnailClick = (index, isMobile=false) => { + if (isMobile) { + setIsMobileThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } else { + setIsThumbnailClicked(prevState => ({ + ...prevState, + [index]: !prevState[index], + })); + } + }; + + useEffect(() => { if (subplebbit.roles !== undefined) { const role = subplebbit.roles[account?.author?.address]?.role; @@ -397,8 +414,10 @@ const Thread = () => { }, [selectedThread, anonymousMode, account]); useEffect(() => { - updateSigner(); - }, [updateSigner]); + if (anonymousMode) { + updateSigner(); + } + }, [updateSigner, anonymousMode]); useEffect(() => { @@ -794,52 +813,106 @@ const Thread = () => { - {commentMediaInfo?.url ? ( --+ {commentMediaInfo?.url ? ( ++) : null}Link: - { + { commentMediaInfo?.url.length > 30 ? commentMediaInfo?.url.slice(0, 30) + "(...)" : commentMediaInfo?.url - } ({commentMediaInfo?.type}) + } ({commentMediaInfo?.type === "iframe" ? "video" : commentMediaInfo?.type}) + {isThumbnailClicked[index] ? ( + + -[ + {handleThumbnailClick(index)}}>Close + ] + + ) : null}+ {commentMediaInfo?.type === 'iframe' && ( ++ + {(isThumbnailClicked[index] || !commentMediaInfo.thumbnail) && commentMediaInfo.embedUrl ? ( + + ) : ( ++ )} {commentMediaInfo?.type === "webpage" ? ( -{handleThumbnailClick(index)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} /> + )} + +
- +- {commentMediaInfo?.url ? ( - commentMediaInfo.type === "webpage" ? ( -+ {comment.thumbnailUrl ? ( -) : null} {commentMediaInfo?.type === "image" ? ( -e.target.src = fallbackImgUrl} /> ) : null}
- -) : null} {commentMediaInfo?.type === "video" ? ( - -+ +
e.target.src = fallbackImgUrl} />
e.target.src = fallbackImgUrl} /> + + + {isThumbnailClicked[index] ? ( +) : null} {commentMediaInfo?.type === "audio" ? ( - -e.target.src = fallbackImgUrl} + /> + ) : ( + +{handleThumbnailClick(index)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} + /> + )} + ) : null} @@ -1559,54 +1632,108 @@ const Thread = () => { }}}>{comment.shortCid}e.target.src = fallbackImgUrl} /> -+ ) : commentMediaInfo.type === "video" ? ( + + {isMobileThumbnailClicked[index] ? ( +- - {comment.thumbnailUrl ? ( -- ) : commentMediaInfo.type === "image" ? ( -+ {commentMediaInfo?.type === 'iframe' && ( +
+ + {(isMobileThumbnailClicked[index] || !commentMediaInfo.thumbnail) && commentMediaInfo.embedUrl ? ( ++ )} + {commentMediaInfo?.url ? ( + commentMediaInfo.type === "webpage" ? ( ++ ++ ) : ( +{handleThumbnailClick(index, true)}} + style={{cursor: "pointer"}} + onError={(e) => e.target.src = fallbackImgUrl} /> + )} + {commentMediaInfo?.type === "video" || "iframe" ? ( + isMobileThumbnailClicked[index] ? ( +
+ {handleThumbnailClick(index, true)}} + >Close ++ ) : ( +video+ )) :video} + ++ + {comment.thumbnailUrl ? ( ++ ) : commentMediaInfo.type === "image" ? ( +e.target.src = fallbackImgUrl} /> + ) : null} +
{commentMediaInfo?.type}+ ++ +-e.target.src = fallbackImgUrl} /> - ) : null} -
{commentMediaInfo.type}- --- ) : commentMediaInfo.type === "video" ? ( -- --e.target.src = fallbackImgUrl} /> -
{commentMediaInfo.type}- -- -- ) : commentMediaInfo.type === "audio" ? ( -e.target.src = fallbackImgUrl} /> - -{commentMediaInfo.type}-- -- ) : null +e.target.src = fallbackImgUrl} /> - -{commentMediaInfo.type}-{commentMediaInfo?.type}+ +e.target.src = fallbackImgUrl} /> + ) : ( + + ) : commentMediaInfo.type === "audio" ? ( + +{handleThumbnailClick(index, true)}} + style={{cursor: "pointer"}} + id="video-thumbnail-mobile" + onError={(e) => e.target.src = fallbackImgUrl} + /> + )} + {commentMediaInfo?.type === "video" || "iframe" ? ( + isMobileThumbnailClicked[index] ? ( + + {handleThumbnailClick(index, true)}} + >Close ++ ) : ( +video+ )) :video} +e.target.src = fallbackImgUrl} /> + + ) : null + ) : null} +{commentMediaInfo?.type}+{comment.content ? ( diff --git a/src/utils/getCommentMediaInfo.js b/src/utils/getCommentMediaInfo.js index 6d237b50..fc26ac3a 100644 --- a/src/utils/getCommentMediaInfo.js +++ b/src/utils/getCommentMediaInfo.js @@ -7,34 +7,80 @@ const getCommentMediaInfo = (comment) => { if (comment?.link) { try { - new URL(comment.link); + const url = new URL(comment.link); + const host = url.hostname; + let embedUrl = null; + + if (['youtube.com', 'www.youtube.com', 'youtu.be'].includes(host)) { + const videoId = host === 'youtu.be' ? url.pathname.slice(1) : url.searchParams.get('v'); + embedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`; + } else if (host.includes('odysee.com')) { + const pathComponents = url.pathname.split('/'); + const channelAndId = pathComponents[1]; + const videoAndId = pathComponents[2]; + embedUrl = `https://odysee.com/$/embed/${channelAndId}/${videoAndId}`; + + // TODO: add support for Rumble, video id is dynamic + + // } else if (host.includes('rumble.com')) { + // const regex = /(\/v.+?)-/; + // const match = regex.exec(url.pathname); + // if (match) { + // const videoId = match[1].slice(1); + // embedUrl = `https://rumble.com/embed/${videoId}/?pub=4`; + // } + + + } else if (host.includes('bitchute.com')) { + const videoId = url.pathname.split('/')[2]; + embedUrl = `https://www.bitchute.com/embed/${videoId}/`; + } else if (host.includes('streamable.com')) { + const videoId = url.pathname.split('/')[1]; + embedUrl = `https://streamable.com/e/${videoId}?quality=highest`; + + // TODO: Add support for Giphy (doesn't have thumbnails, size is variable) + + // } else if (host.includes('giphy.com')) { + // const hyphenComponents = url.pathname.split('-'); + // const gifId = hyphenComponents[hyphenComponents.length - 1]; + // embedUrl = `https://giphy.com/embed/${gifId}`; + } + + if (embedUrl) { + return { + url: comment.link, + embedUrl, + type: 'iframe', + thumbnail: comment.thumbnailUrl, + }; + } + + const mime = extName(url.pathname.replace('/', ''))[0]?.mime; + + if (mime?.startsWith('image')) { + return { + url: comment.link, + type: 'image', + }; + } + + if (mime?.startsWith('video')) { + return { + url: comment.link, + type: 'video', + thumbnail: comment.thumbnailUrl, + }; + } + + if (mime?.startsWith('audio')) { + return { + url: comment.link, + type: 'audio', + }; + } } catch (error) { - // console.error("Invalid URL:", comment.link); return; } - - const mime = extName(new URL(comment?.link).pathname.replace('/', ''))[0]?.mime; - - if (mime?.startsWith('image')) { - return { - url: comment.link, - type: 'image', - }; - } - - if (mime?.startsWith('video')) { - return { - url: comment.link, - type: 'video', - }; - } - - if (mime?.startsWith('audio')) { - return { - url: comment.link, - type: 'audio', - }; - } } if (comment?.thumbnailUrl && comment?.thumbnailUrl !== comment?.link) {