Skip to content

Commit 31b8937

Browse files
committed
enhance: give the possibility to show all new comments of a thread, even nested
1 parent 450f7bc commit 31b8937

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

components/comment.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import LinkToContext from './link-to-context'
2828
import Boost from './boost-button'
2929
import { gql, useApolloClient } from '@apollo/client'
3030
import classNames from 'classnames'
31-
import { ShowNewComments } from './show-new-comments'
31+
import { ShowAllNewComments, ShowNewComments } from './show-new-comments'
3232

3333
function Parent ({ item, rootText }) {
3434
const root = useRoot()
@@ -262,9 +262,9 @@ export default function Comment ({
262262
<Reply depth={depth + 1} item={item} replyOpen={replyOpen} onCancelQuote={cancelQuote} onQuoteReply={quoteReply} quote={quote}>
263263
{root.bounty && !bountyPaid && <PayBounty item={item} />}
264264
<div className='ms-auto'>
265-
{item.newComments?.length > 0 && (
266-
<ShowNewComments comments={item.comments.comments} newComments={item.newComments} itemId={item.id} />
267-
)}
265+
{item.path.split('.').length === 2
266+
? <ShowAllNewComments item={item} />
267+
: <ShowNewComments comments={item.comments.comments} newComments={item.newComments} itemId={item.id} />}
268268
</div>
269269
</Reply>}
270270
{children}

components/show-new-comments.js

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,71 @@ function prepareComments (client, newComments) {
4242
}
4343
}
4444

45+
function showAllNewCommentsRecursively (client, item) {
46+
// handle new comments at this item level
47+
if (item.newComments && item.newComments.length > 0) {
48+
const dedupedNewComments = dedupeNewComments(item.newComments, item.comments?.comments)
49+
50+
if (dedupedNewComments.length > 0) {
51+
const payload = prepareComments(client, dedupedNewComments)
52+
commentUpdateFragment(client, item.id, payload)
53+
}
54+
}
55+
56+
// recursively handle new comments in child comments
57+
if (item.comments?.comments) {
58+
for (const childComment of item.comments.comments) {
59+
showAllNewCommentsRecursively(client, childComment)
60+
}
61+
}
62+
}
63+
64+
function dedupeNewComments (newComments, comments) {
65+
const existingIds = new Set(comments.map(c => c.id))
66+
return newComments.filter(id => !existingIds.has(id))
67+
}
68+
69+
function collectAllNewComments (item) {
70+
const allNewComments = [...(item.newComments || [])]
71+
if (item.comments?.comments) {
72+
for (const comment of item.comments.comments) {
73+
allNewComments.push(...collectAllNewComments(comment))
74+
}
75+
}
76+
return allNewComments
77+
}
78+
79+
// TODO: merge this with ShowNewComments
80+
export function ShowAllNewComments ({ item }) {
81+
const client = useApolloClient()
82+
83+
const newComments = useMemo(() => collectAllNewComments(item), [item])
84+
85+
const showNewComments = useCallback(() => {
86+
showAllNewCommentsRecursively(client, item)
87+
}, [client, item])
88+
89+
if (newComments.length === 0) {
90+
return null
91+
}
92+
93+
return (
94+
<div
95+
onClick={showNewComments}
96+
className='d-flex align-items-center gap-2 px-3 pointer'
97+
>
98+
{newComments.length > 1
99+
? `show all ${newComments.length} new comments`
100+
: 'show new comment'}
101+
<div className={styles.newCommentDot} />
102+
</div>
103+
)
104+
}
105+
45106
// ShowNewComments is a component that dedupes, refreshes and injects newComments into the comments field
46107
export function ShowNewComments ({ topLevel = false, comments, newComments = [], itemId, sort }) {
47108
const client = useApolloClient()
48-
49-
const dedupedNewComments = useMemo(() => {
50-
const existingIds = new Set(comments.map(c => c.id))
51-
return newComments.filter(id => !existingIds.has(id))
52-
}, [newComments, comments])
109+
const dedupedNewComments = useMemo(() => dedupeNewComments(newComments, comments), [newComments, comments])
53110

54111
const showNewComments = useCallback(() => {
55112
// fetch the latest version of the comments from the cache by their ids

0 commit comments

Comments
 (0)