diff --git a/src/components/ForwardRefLink.jsx b/src/components/ForwardRefLink.jsx new file mode 100644 index 00000000..2e579e72 --- /dev/null +++ b/src/components/ForwardRefLink.jsx @@ -0,0 +1,26 @@ +import React, { useEffect } from "react"; +import { Link } from "react-router-dom"; + +const ForwardRefLink = React.forwardRef((props, ref) => { + const { children, setRefAndCid, onMouseOver, onMouseLeave, onClick, ...otherProps } = props; + + useEffect(() => { + if (ref.current && typeof setRefAndCid === 'function') { + setRefAndCid(ref.current); + } + }, [ref, setRefAndCid]); + + return ( + + {children} + + ); +}); + +export default ForwardRefLink; \ No newline at end of file diff --git a/src/components/Post.jsx b/src/components/Post.jsx index 1c64e4d3..be6fde1a 100644 --- a/src/components/Post.jsx +++ b/src/components/Post.jsx @@ -1,8 +1,8 @@ import React, { useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; -import { Link } from 'react-router-dom'; import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; import breaks from 'remark-breaks'; +import ForwardRefLink from './ForwardRefLink'; const Post = ({ content, postQuoteOnClick, postQuoteOnOver, postQuoteOnLeave, postQuoteRef }) => { @@ -67,28 +67,31 @@ const Post = ({ content, postQuoteOnClick, postQuoteOnOver, postQuoteOnLeave, po } const cid = matchedText.replace('c/', ''); + const linkRef = React.createRef(); newParts.push( - {}} - ref={(el) => { + ref={linkRef} + setRefAndCid={(ref) => { if (typeof postQuoteRef === 'function') { - postQuoteRef(cid, el); - } else { - return; + postQuoteRef(cid, ref); } }} onClick={() => {postQuoteOnClick(cid)}} - onMouseOver={() => {postQuoteOnOver(cid)}} + onMouseOver={() => { + postQuoteOnOver(cid); + }} onMouseLeave={() => { postQuoteOnLeave(); }} > - {matchedText} - + {matchedText} + ); + lastIndex = index + matchedText.length; } diff --git a/src/components/views/All.jsx b/src/components/views/All.jsx index 17628cac..f923ac5a 100755 --- a/src/components/views/All.jsx +++ b/src/components/views/All.jsx @@ -76,6 +76,7 @@ const All = () => { const postMenuCatalogRef = useRef(null); const backlinkRefs = useRef({}); const quoteRefs = useRef({}); + const postRefs = useRef({}); const backlinkRefsMobile = useRef({}); const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); @@ -97,11 +98,24 @@ const All = () => { const [deletePost, setDeletePost] = useState(false); const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); + const [cidTracker, setCidTracker] = useState({}); + const [displayedReplies, setDisplayedReplies] = useState([]); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; } + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + displayedReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [displayedReplies]); + + useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); + useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address); @@ -580,6 +594,7 @@ const All = () => { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; + setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; const isModerator = moderatorPermissions[thread.subplebbitAddress]; @@ -1248,7 +1263,55 @@ const All = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> @@ -1680,7 +1791,55 @@ const All = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> diff --git a/src/components/views/Board.jsx b/src/components/views/Board.jsx index 06b9b334..47240ac6 100755 --- a/src/components/views/Board.jsx +++ b/src/components/views/Board.jsx @@ -86,6 +86,7 @@ const Board = () => { const postMenuCatalogRef = useRef(null); const backlinkRefs = useRef({}); const quoteRefs = useRef({}); + const postRefs = useRef({}); const backlinkRefsMobile = useRef({}); const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); @@ -114,11 +115,22 @@ const Board = () => { const [outOfViewPosition, setOutOfViewPosition] = useState({top: 0, left: 0}); const [postOnHoverHeight, setPostOnHoverHeight] = useState(0); const [executeAnonMode, setExecuteAnonMode] = useState(false); + const [cidTracker, setCidTracker] = useState({}); + const [displayedReplies, setDisplayedReplies] = useState([]); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; } + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + displayedReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [displayedReplies]); + useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); @@ -1028,6 +1040,7 @@ const Board = () => { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; + setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; return ( @@ -1673,7 +1686,55 @@ const Board = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> @@ -2073,7 +2182,55 @@ const Board = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> diff --git a/src/components/views/Subscriptions.jsx b/src/components/views/Subscriptions.jsx index 0559edcc..ae7b5a0c 100755 --- a/src/components/views/Subscriptions.jsx +++ b/src/components/views/Subscriptions.jsx @@ -76,6 +76,7 @@ const Subscriptions = () => { const postMenuCatalogRef = useRef(null); const backlinkRefs = useRef({}); const quoteRefs = useRef({}); + const postRefs = useRef({}); const backlinkRefsMobile = useRef({}); const quoteRefsMobile = useRef({}); const postOnHoverRef = useRef(null); @@ -97,11 +98,22 @@ const Subscriptions = () => { const [deletePost, setDeletePost] = useState(false); const [moderatorPermissions, setModeratorPermissions] = useState({}); const [executeAnonMode, setExecuteAnonMode] = useState(false); + const [cidTracker, setCidTracker] = useState({}); + const [displayedReplies, setDisplayedReplies] = useState([]); const setSelectedThreadCid = (cid) => { selectedThreadCidRef.current = cid; } + // let post.jsx access full cid of user-typed short cid + useEffect(() => { + const newCidTracker = {}; + displayedReplies.forEach((reply) => { + newCidTracker[reply.shortCid] = reply.cid; + }); + setCidTracker(newCidTracker); + }, [displayedReplies]); + useAnonModeRef(selectedThreadCidRef, anonymousMode && executeAnonMode); const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: account?.subscriptions, sortType: 'active'}); @@ -590,6 +602,7 @@ const Subscriptions = () => { data={selectedFeed} itemContent={(index, thread) => { const { displayedReplies, omittedCount } = filteredRepliesByThread[thread.cid] || {}; + setDisplayedReplies(displayedReplies); const commentMediaInfo = getCommentMediaInfo(thread); const fallbackImgUrl = "assets/filedeleted-res.gif"; const isModerator = moderatorPermissions[thread.subplebbitAddress]; @@ -1258,7 +1271,55 @@ const Subscriptions = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> @@ -1690,7 +1799,55 @@ const Subscriptions = () => { }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> (...)
{ }}> {`c/${shortParentCid}`}{shortParentCid === thread.shortCid ? " (OP)" : null} - + { + postRefs.current[quoteShortParentCid] = ref; + }} + postQuoteOnClick={(quoteShortParentCid) => { + handleQuoteClick(reply, quoteShortParentCid, null) + }} + postQuoteOnOver={(quoteShortParentCid) => { + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); + + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; + + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } + + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } + }) + }} + } + postQuoteOnLeave={() => { + removeHighlight(); + setOutOfViewCid(null); + }} + /> diff --git a/src/components/views/Thread.jsx b/src/components/views/Thread.jsx index 46c61af8..ce74a1e3 100755 --- a/src/components/views/Thread.jsx +++ b/src/components/views/Thread.jsx @@ -215,8 +215,8 @@ const Thread = () => { ].sort((a, b) => a.timestamp - b.timestamp ), [accountRepliesNotYetInCommentReplies, flattenedReplies]); - - useEffect(() => { + // let post.jsx access full cid of user-typed short cid + useEffect(() => { const newCidTracker = {}; sortedReplies.forEach((reply) => { newCidTracker[reply.shortCid] = reply.cid; @@ -224,15 +224,6 @@ const Thread = () => { setCidTracker(newCidTracker); }, [sortedReplies]); - // useEffect(() => { - // console.log("postrefs cidtracker", cidTracker); - // }, [cidTracker]); - - // useEffect(() => { - // console.log("postRefs: ", postRefs) - // }, [postRefs]); - - // temporary title from JSON, gets subplebbitAddress and threadCid from URL useEffect(() => { setSelectedAddress(subplebbitAddress); @@ -1341,46 +1332,48 @@ const Thread = () => { { - postRefs.current[cid] = ref; + postQuoteRef={(quoteShortParentCid, ref) => { + postRefs.current[quoteShortParentCid] = ref; }} postQuoteOnClick={(quoteShortParentCid) => { handleQuoteClick(reply, quoteShortParentCid, null) }} postQuoteOnOver={(quoteShortParentCid) => { - handleQuoteHover(reply, quoteShortParentCid, () => { - const quoteParentCid = cidTracker[quoteShortParentCid]; - setOutOfViewCid(quoteParentCid); + const quoteParentCid = cidTracker[quoteShortParentCid]; + if (outOfViewCid !== quoteParentCid) { + handleQuoteHover(reply, quoteShortParentCid, () => { + setOutOfViewCid(quoteParentCid); - // const rect = postRefs.current[quoteParentCid].getBoundingClientRect(); - // const distanceToRight = window.innerWidth - rect.right; - // const distanceToTop = rect.top; - // const distanceToBottom = window.innerHeight - rect.bottom; - // let top; + const rect = postRefs.current[quoteShortParentCid].getBoundingClientRect(); + const distanceToRight = window.innerWidth - rect.right; + const distanceToTop = rect.top; + const distanceToBottom = window.innerHeight - rect.bottom; + let top; - // if (distanceToTop < postOnHoverHeight / 2) { - // top = window.scrollY - 5; - // } else if (distanceToBottom < postOnHoverHeight / 2) { - // top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; - // } else { - // top = rect.top + window.scrollY - postOnHoverHeight / 2; - // } + if (distanceToTop < postOnHoverHeight / 2) { + top = window.scrollY - 5; + } else if (distanceToBottom < postOnHoverHeight / 2) { + top = window.scrollY - postOnHoverHeight + window.innerHeight - 10; + } else { + top = rect.top + window.scrollY - postOnHoverHeight / 2; + } - // if (distanceToRight < 200) { - // setOutOfViewPosition({ - // top, - // right: window.innerWidth - rect.left - 10, - // maxWidth: rect.left - 5 - // }); - // } else { - // setOutOfViewPosition({ - // top, - // left: rect.left + rect.width + 5, - // maxWidth: window.innerWidth - rect.left - rect.width - 5 - // }); - // } + if (distanceToRight < 200) { + setOutOfViewPosition({ + top, + right: window.innerWidth - rect.left - 10, + maxWidth: rect.left - 5 + }); + } else { + setOutOfViewPosition({ + top, + left: rect.left + rect.width + 5, + maxWidth: window.innerWidth - rect.left - rect.width - 5 + }); + } }) }} + } postQuoteOnLeave={() => { removeHighlight(); setOutOfViewCid(null);