From d57a45eeeae09b2fd1cb01789209592ad125a4d1 Mon Sep 17 00:00:00 2001 From: Soxasora Date: Fri, 25 Apr 2025 05:58:48 -0500 Subject: [PATCH] highlight new nested comments; track ncomments of a comment thread; refactor ViewAllReplies and ReplyOnAnotherPage --- components/comment.js | 85 ++++++++++++++++++++++++++++++++----------- lib/new-comments.js | 10 ++++- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/components/comment.js b/components/comment.js index 73e64d0c3..e07ac22f1 100644 --- a/components/comment.js +++ b/components/comment.js @@ -28,6 +28,7 @@ import LinkToContext from './link-to-context' import Boost from './boost-button' import { gql, useApolloClient } from '@apollo/client' import classNames from 'classnames' +import { commentThreadNumViewed, commentThreadNum } from '@/lib/new-comments' function Parent ({ item, rootText }) { const root = useRoot() @@ -147,6 +148,17 @@ export default function Comment ({ } }, [item.id]) + // if the comment has a thread, track the number of comments in the thread + useEffect(() => { + const path = item.path.split('.') + console.log('path', path) + if (path.length > COMMENT_DEPTH_LIMIT) { + if (commentThreadNum(item) < item.ncomments || !commentThreadNum(item)) { + commentThreadNumViewed(item, item.ncomments) + } + } + }, [item.id, item.ncomments]) + const bottomedOut = depth === COMMENT_DEPTH_LIMIT || (item.comments?.comments.length === 0 && item.nDirectComments > 0) // Don't show OP badge when anon user comments on anon user posts const op = root.user.name === item.user.name && Number(item.user.id) !== USER_ID.anon @@ -252,7 +264,7 @@ export default function Comment ({ {collapse !== 'yep' && ( bottomedOut - ?
+ ?
: (
{item.outlawed && !me?.privates?.wildWestMode @@ -269,7 +281,7 @@ export default function Comment ({ {item.comments.comments.map((item) => ( ))} - {item.comments.comments.length < item.nDirectComments && } + {item.comments.comments.length < item.nDirectComments && } ) : null} @@ -282,31 +294,60 @@ export default function Comment ({ ) } -export function ViewAllReplies ({ id, nshown, nhas }) { - const text = `view all ${nhas} replies` +export function MoreReplies ({ item, onAnotherPage }) { + const root = useRoot() + const rootId = onAnotherPage ? commentSubTreeRootId(item, root) : null + const router = useRouter() + const ref = useRef(null) + const { cache } = useApolloClient() - return ( -
- - {text} - -
- ) -} + useEffect(() => { + if (router.query.commentsViewedAt) { + const lastViewedNumComments = parseInt(window.localStorage.getItem(`commentsViewNumThread:${item.id}`), 10) + // get the updated number of comments in the thread from cache + const comment = cache.readFragment({ + id: `Item:${item.id}`, + fragment: gql` + fragment NComments on Item { + ncomments + }` + }) + // if the last viewed number of comments in the thread + // is less than the updated number of comments in it, highlight it + if (lastViewedNumComments && lastViewedNumComments < comment?.ncomments) { + ref.current.classList.add('outline-new-comment') + } + } + }, [item.id]) -function ReplyOnAnotherPage ({ item }) { - const root = useRoot() - const rootId = commentSubTreeRootId(item, root) + // distinguish between reply on another page and view all replies + const className = onAnotherPage + ? classNames(styles.comment, 'mt-3') + : `d-block fw-bold ${styles.comment} pb-2 ps-3` - let text = 'reply on another page' - if (item.ncomments > 0) { - text = `view all ${item.ncomments} replies` - } + // if item has replies, show view all n replies, otherwise show reply on another page + const text = item.ncomments > 0 + ? `view all ${item.ncomments} replies` + : 'reply on another page' return ( - - {text} - +
ref.current.classList.add('outline-new-comment-unset')} + onTouchStart={() => ref.current.classList.add('outline-new-comment-unset')} + > + {onAnotherPage + ? ( + + {text} + + ) + : ( + + {text} + + )} +
) } diff --git a/lib/new-comments.js b/lib/new-comments.js index 20ae8dd49..faa69006d 100644 --- a/lib/new-comments.js +++ b/lib/new-comments.js @@ -1,6 +1,6 @@ const COMMENTS_VIEW_PREFIX = 'commentsViewedAt' const COMMENTS_NUM_PREFIX = 'commentsViewNum' - +const COMMENTS_NUM_PREFIX_THREAD = 'commentsViewNumThread' export function commentsViewed (item) { if (!item.parentId && item.lastCommentAt) { window.localStorage.setItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`, new Date(item.lastCommentAt).getTime()) @@ -30,3 +30,11 @@ export function newComments (item) { return false } + +export function commentThreadNumViewed (item) { + window.localStorage.setItem(`${COMMENTS_NUM_PREFIX_THREAD}:${item.id}`, item.ncomments) +} + +export function commentThreadNum (item) { + return window.localStorage.getItem(`${COMMENTS_NUM_PREFIX_THREAD}:${item.id}`) +}