From 97e95005d31c775d8127528ede1718b7a09ed92f Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 3 Jun 2023 16:33:59 +0200 Subject: [PATCH] implement PostOnHover component --- src/components/PostOnHover.jsx | 185 +++++++++++++++++++++++++ src/components/views/All.jsx | 86 ++++++++++-- src/components/views/Board.jsx | 101 ++++++++++---- src/components/views/Subscriptions.jsx | 86 ++++++++++-- src/components/views/Thread.jsx | 104 ++++++++++---- src/utils/handleQuoteHover.js | 5 +- 6 files changed, 495 insertions(+), 72 deletions(-) create mode 100644 src/components/PostOnHover.jsx diff --git a/src/components/PostOnHover.jsx b/src/components/PostOnHover.jsx new file mode 100644 index 00000000..095eddce --- /dev/null +++ b/src/components/PostOnHover.jsx @@ -0,0 +1,185 @@ +import React, { Fragment } from "react"; +import { Link } from "react-router-dom"; +import { useAccount, useComment } from "@plebbit/plebbit-react-hooks"; +import getDate from "../utils/getDate"; +import getCommentMediaInfo from "../utils/getCommentMediaInfo"; +import findShortParentCid from "../utils/findShortParentCid"; +import Post from "./Post"; +import EditLabel from "./EditLabel"; +import useStateString from "../hooks/useStateString"; +import { BoardForm, Container } from "./styled/views/Board.styled"; +import useGeneralStore from "../hooks/stores/useGeneralStore"; + +const PostOnHover = ({ cid, feed }) => { + const selectedStyle = useGeneralStore(state => state.selectedStyle); + const account = useAccount(); + const reply = useComment({commentCid: cid}); + const replyMediaInfo = getCommentMediaInfo(reply); + const fallbackImgUrl = "assets/filedeleted-res.gif"; + const selectedFeed = feed; + const thread = useComment({commentCid: reply.parentCid}); + const shortParentCid = findShortParentCid(reply.parentCid, selectedFeed); + const stateString = useStateString(reply); + + return ( + + +
+
+ {reply.state === 'succeeded' ? ( +
+
+
+ + {reply.author?.displayName + ? reply.author?.displayName.length > 20 + ? + + {reply.author?.displayName.slice(0, 20) + " (...)"} + + + : + {reply.author?.displayName} + : + Anonymous} +   + + (u/ + {reply.author?.shortAddress ? + ( + + {reply.author?.shortAddress} + + ) : ( + + {account?.author?.shortAddress} + + ) + } + ) + + +   + {getDate(reply.timestamp)} +   + + c/ + {reply.shortCid ? ( + {}} id="reply-button" + title="Reply to this post">{reply.shortCid} + ) : ( + Pending + )} +   + +
+ {replyMediaInfo?.url ? ( +
+ + {replyMediaInfo?.type === "webpage" ? ( +
+ + {reply.thumbnailUrl ? ( + {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> + ) : null} + +
+ ) : null} + {replyMediaInfo?.type === "image" ? ( +
+ + {replyMediaInfo.type} e.target.src = fallbackImgUrl} /> + +
+ ) : null} + {replyMediaInfo?.type === "video" ? ( + + + ) : null} + {replyMediaInfo?.type === "audio" ? ( + + + ) : null} +
+ ) : null} + {reply.content ? ( + reply.content?.length > 500 ? + +
+ {}} className="quotelink"> + {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} + + + (...) +

+ Comment too long. Click the link to view.
+
+
+ :
+ {}} className="quotelink"> + {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} + + + +
) + : null} +
+
+ ) : ( +
+ {stateString} +
+ )} +
+
+
+
+ ); +} + +export default PostOnHover; \ No newline at end of file diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index 82233bce..b6e8d602 100644 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -1,4 +1,5 @@ -import React, { Fragment, useEffect, useMemo, useState, useRef } from 'react'; +import React, { Fragment, useEffect, useLayoutEffect, useMemo, useState, useRef } from 'react'; +import { createPortal } from 'react-dom'; import { Helmet } from 'react-helmet-async'; import { Link, useNavigate } from 'react-router-dom'; import { Tooltip } from 'react-tooltip'; @@ -13,6 +14,7 @@ import ImageBanner from '../ImageBanner'; import OfflineIndicator from '../OfflineIndicator'; import Post from '../Post'; import PostLoader from '../PostLoader'; +import PostOnHover from '../PostOnHover'; import ReplyModal from '../modals/ReplyModal'; import SettingsModal from '../modals/SettingsModal'; import findShortParentCid from '../../utils/findShortParentCid'; @@ -47,6 +49,8 @@ const All = () => { const threadMenuRefs = useRef({}); const replyMenuRefs = useRef({}); + const threadBacklinkRefs = useRef({}); + const postOnHoverRef = useRef(null); const [isReplyOpen, setIsReplyOpen] = useState(false); const [prevScrollPos, setPrevScrollPos] = useState(0); @@ -54,6 +58,9 @@ const All = () => { const [rotatedStates, setRotatedStates] = useState({}); const [errorMessage, setErrorMessage] = useState(null); const [isImageSearchOpen, setIsImageSearchOpen] = useState(false); + const [outOfViewCid, setOutOfViewCid] = useState(null); + const [outOfViewPosition, setOutOfViewPosition] = useState({top: 0, left: 0}); + const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); useError(errorMessage, [errorMessage]); @@ -189,6 +196,14 @@ const All = () => { }; + useLayoutEffect(() => { + if (postOnHoverRef.current) { + const rect = postOnHoverRef.current.getBoundingClientRect(); + setPostOnHoverHeight(rect.height); + } + }, [outOfViewCid]); + + return ( <> @@ -517,12 +532,28 @@ const All = () => { {thread.replies?.pages?.topAll.comments .sort((a, b) => a.timestamp - b.timestamp) .map((reply, index) => ( -
+
{ + threadBacklinkRefs.current[reply.cid] = el; + }}> {}} className="quote-link" onClick={(event) => handleQuoteClick(reply, null, event)} - onMouseOver={(event) => handleQuoteHover(reply, null, event)} - onMouseLeave={removeHighlight}> + onMouseOver={(event) => { + event.stopPropagation(); + handleQuoteHover(reply, null, () => { + setOutOfViewCid(reply.cid); + const rect = threadBacklinkRefs.current[reply.cid].getBoundingClientRect(); + setOutOfViewPosition({ + top: rect.top + window.scrollY - rect.height / 2, + left: rect.left + rect.width + 5, + }); + }); + }} + onMouseLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }}> c/{reply.shortCid}  
@@ -702,16 +733,32 @@ const All = () => { ) : null}
-