diff --git a/src/components/post/post-desktop/post-desktop.tsx b/src/components/post/post-desktop/post-desktop.tsx index 73370e68..e8701a00 100644 --- a/src/components/post/post-desktop/post-desktop.tsx +++ b/src/components/post/post-desktop/post-desktop.tsx @@ -1,8 +1,8 @@ -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useLocation, useParams } from 'react-router-dom'; import { Link } from 'react-router-dom'; -import { Comment, useAccount, useBlock, useEditedComment } from '@plebbit/plebbit-react-hooks'; +import { Comment, useAccount, useBlock } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from '../post.module.css'; import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../../lib/utils/media-utils'; @@ -225,14 +225,8 @@ const PostMessage = ({ post }: PostProps) => { }; const PostDesktop = ({ openReplyModal, post, roles, showAllReplies }: PostProps) => { - // handle pending mod or author edit - const { editedComment } = useEditedComment({ comment: post }); - if (editedComment) { - post = editedComment; - } const { cid, content, link, pinned, replyCount, subplebbitAddress } = post || {}; const { isDescription, isRules } = post || {}; // custom properties, not from api - const params = useParams(); const location = useLocation(); const isInPendingPostView = isPendingPostView(location.pathname, params); @@ -247,6 +241,16 @@ const PostDesktop = ({ openReplyModal, post, roles, showAllReplies }: PostProps) const repliesCount = pinned ? replyCount : replyCount - 5; const linksCount = pinned ? totallinksCount : totallinksCount - visiblelinksCount; + const replyRefs = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + const replyIndex = replies.findIndex((reply) => location.pathname.startsWith(`/p/${subplebbitAddress}/c/${reply?.cid}`)); + + if (replyIndex !== -1 && replyRefs.current[replyIndex]) { + replyRefs.current[replyIndex]?.scrollIntoView(); + } + }, [location.pathname, replies, subplebbitAddress]); + return (
@@ -285,18 +289,21 @@ const PostDesktop = ({ openReplyModal, post, roles, showAllReplies }: PostProps) !isDescription && !isRules && replies && - (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => ( -
-
-
{'>>'}
-
- - {reply.link && isValidURL(reply.link) && } - {reply.content && } + (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => { + const isRouteLinkToReply = location.pathname.startsWith(`/p/${subplebbitAddress}/c/${reply?.cid}`); + return ( +
(replyRefs.current[index] = el)}> +
+
{'>>'}
+
+ + {reply.link && isValidURL(reply.link) && } + {reply.content && } +
-
- ))} + ); + })}
); diff --git a/src/components/post/post-mobile/post-mobile.tsx b/src/components/post/post-mobile/post-mobile.tsx index e0b66f28..6487246e 100644 --- a/src/components/post/post-mobile/post-mobile.tsx +++ b/src/components/post/post-mobile/post-mobile.tsx @@ -1,7 +1,7 @@ -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Link, useLocation, useParams } from 'react-router-dom'; -import { Comment, useAccount, useEditedComment } from '@plebbit/plebbit-react-hooks'; +import { Comment, useAccount } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from '../post.module.css'; import { getCommentMediaInfo, getHasThumbnail } from '../../../lib/utils/media-utils'; @@ -182,25 +182,27 @@ const PostMessageMobile = ({ post }: PostProps) => { }; const PostMobile = ({ openReplyModal, post, roles, showAllReplies }: PostProps) => { - // handle pending mod or author edit - const { editedComment } = useEditedComment({ comment: post }); - if (editedComment) { - post = editedComment; - } const { t } = useTranslation(); const { cid, content, pinned, replyCount, subplebbitAddress } = post || {}; const { isDescription, isRules } = post || {}; // custom properties, not from api - const params = useParams(); const location = useLocation(); const isInAllView = isAllView(location.pathname); const isInPendingPostView = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); - const linksCount = useCountLinksInReplies(post); - const replies = useReplies(post); + const replyRefs = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + const replyIndex = replies.findIndex((reply) => location.pathname.startsWith(`/p/${subplebbitAddress}/c/${reply?.cid}`)); + + if (replyIndex !== -1 && replyRefs.current[replyIndex]) { + replyRefs.current[replyIndex]?.scrollIntoView(); + } + }, [location.pathname, replies, subplebbitAddress]); + return (
@@ -232,19 +234,22 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies }: PostProps) !isDescription && !isRules && replies && - (showAllReplies ? replies : replies.slice(-5)).map((reply) => ( -
-
-
-
- - {reply.content && } - + (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => { + const isRouteLinkToReply = location.pathname.startsWith(`/p/${subplebbitAddress}/c/${reply?.cid}`); + return ( +
(replyRefs.current[index] = el)}> +
+
+
+ + {reply.content && } + +
-
- ))} + ); + })}
); diff --git a/src/components/post/post.module.css b/src/components/post/post.module.css index 98015fa0..dcefd89d 100644 --- a/src/components/post/post.module.css +++ b/src/components/post/post.module.css @@ -416,6 +416,10 @@ border-top: var(--reply-backlink-mobile-border-top); } +.highlight { + background: var(--reply-highlight-background-color) !important; +} + @media (max-width: 640px) { .postDesktop { display: none; diff --git a/src/themes.css b/src/themes.css index 10c352ec..9d481db7 100644 --- a/src/themes.css +++ b/src/themes.css @@ -158,6 +158,9 @@ --reply-desktop-background-color: #f0e0d6; --reply-desktop-border: 1px solid #d9bfb7; + /* reply highlight */ + --reply-highlight-background-color: #f0c0b0; + /* reply modal */ --reply-modal-field-input-border: 1px solid #aaa; --reply-modal-field-input-border-focus: 1px solid #ea8; @@ -350,6 +353,9 @@ --reply-desktop-background-color: #d6daf0; --reply-desktop-border: 1px solid #b7c5d9; + /* reply highlight */ + --reply-highlight-background-color: #d6bad0; + /* reply modal */ --reply-modal-field-input-border: 1px solid #aaa; --reply-modal-field-input-border-focus: 1px solid #98e; @@ -513,6 +519,9 @@ --reply-desktop-background-color: #f0e0d6; --reply-desktop-border: 1px solid #d9bfb7; + /* reply highlight */ + --reply-highlight-background-color: #f0c0b0; + /* settings modal */ --settings-modal-background-color: #f0e0d6; --settings-modal-border-top: 1px solid rgba(0, 0, 0, 0.20); @@ -685,6 +694,9 @@ --reply-desktop-background-color: #d6daf0; --reply-desktop-border: 1px solid #b7c5d9; + /* reply highlight */ + --reply-highlight-background-color: #d6bad0; + /* settings modal */ --settings-modal-background-color: #d6daf0; --settings-modal-border-top: 1px solid rgba(0, 0, 0, 0.20); @@ -873,6 +885,9 @@ --reply-modal-field-border-focus: 1px solid #757575; --reply-modal-field-input-border-focus: 1px solid #757575; + /* reply highlight */ + --reply-highlight-background-color: #1d1d21; + /* select */ --select-border: 1px solid #575a60; --select-background-color: #282a2e; @@ -1049,6 +1064,9 @@ --reply-desktop-background-color: #ddd; --reply-desktop-border: 1px solid #ccc; + /* reply highlight */ + --reply-highlight-background-color: #ccc; + /* reply modal */ --reply-modal-field-input-border: 1px solid #aaa; --reply-modal-field-input-border-focus: 1px solid #ea8; diff --git a/src/views/post-page/post-page.tsx b/src/views/post-page/post-page.tsx index bd71a3b5..8cd90d3b 100644 --- a/src/views/post-page/post-page.tsx +++ b/src/views/post-page/post-page.tsx @@ -1,6 +1,6 @@ import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import { useComment, useSubplebbit } from '@plebbit/plebbit-react-hooks'; +import { Comment, useComment, useEditedComment, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { useLocation, useParams } from 'react-router-dom'; import styles from './post-page.module.css'; import { isDescriptionView, isRulesView, isSettingsView } from '../../lib/utils/view-utils'; @@ -25,7 +25,21 @@ const PostPage = () => { const { activeCid, closeModal, openReplyModal, showReplyModal, scrollY } = useReplyModal(); - const post = useComment({ commentCid }); + const comment: Comment = useComment({ commentCid }); + // if the comment is a reply, get the parent comment + const postComment = useComment({ commentCid: comment?.postCid }); + let post; + if (comment.parentCid) { + post = postComment; + } else { + post = comment; + } + // handle pending mod or author edit + const { editedComment } = useEditedComment({ comment: post }); + if (editedComment) { + post = editedComment; + } + const { deleted, locked, removed } = post || {}; const isThreadClosed = deleted || locked || removed;