Fix live comments behavior on paginated comments and threads (#2334)
* livecomments: patches for paginated comments; broader ViewMoreReplies component live comments: - don't show the thread button for thread comments that are shown as full items (top level) - don't try to count/inject on paginated comments, just show the live comments dot - dedupe new comments being fetched with already existing comments, useful for just showing the dot, but not the button comments: - live comments dot now appears on both paginated and bottomed out comments -- merge ViewAllReplies with ReplyToAnotherPage * fix thread comment recognition, now based on depth
This commit is contained in:
parent
ef1c586231
commit
a4a0fdb060
@ -261,7 +261,7 @@ export default function Comment ({
|
|||||||
</div>
|
</div>
|
||||||
{collapse !== 'yep' && (
|
{collapse !== 'yep' && (
|
||||||
bottomedOut
|
bottomedOut
|
||||||
? <div className={styles.children}><div className={classNames(styles.comment, 'mt-3')}><ReplyOnAnotherPage item={item} /></div></div>
|
? <div className={styles.children}><div className={classNames(styles.comment, 'mt-3 pb-2')}><ViewMoreReplies item={item} navigateRoot /></div></div>
|
||||||
: (
|
: (
|
||||||
<div className={styles.children}>
|
<div className={styles.children}>
|
||||||
{item.outlawed && !me?.privates?.wildWestMode
|
{item.outlawed && !me?.privates?.wildWestMode
|
||||||
@ -281,7 +281,11 @@ export default function Comment ({
|
|||||||
{item.comments.comments.map((item) => (
|
{item.comments.comments.map((item) => (
|
||||||
<Comment depth={depth + 1} key={item.id} item={item} rootLastCommentAt={rootLastCommentAt} />
|
<Comment depth={depth + 1} key={item.id} item={item} rootLastCommentAt={rootLastCommentAt} />
|
||||||
))}
|
))}
|
||||||
{item.comments.comments.length < item.nDirectComments && <ViewAllReplies id={item.id} nhas={item.ncomments} />}
|
{item.comments.comments.length < item.nDirectComments && (
|
||||||
|
<div className={`d-block ${styles.comment} pb-2 ps-3`}>
|
||||||
|
<ViewMoreReplies item={item} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
: null}
|
: null}
|
||||||
@ -294,31 +298,24 @@ export default function Comment ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ViewAllReplies ({ id, nshown, nhas }) {
|
export function ViewMoreReplies ({ item, navigateRoot = false }) {
|
||||||
const text = `view all ${nhas} replies`
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`d-block fw-bold ${styles.comment} pb-2 ps-3`}>
|
|
||||||
<Link href={`/items/${id}`} as={`/items/${id}`} className='text-muted'>
|
|
||||||
{text}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function ReplyOnAnotherPage ({ item }) {
|
|
||||||
const root = useRoot()
|
const root = useRoot()
|
||||||
const rootId = commentSubTreeRootId(item, root)
|
|
||||||
const { cache } = useApolloClient()
|
const { cache } = useApolloClient()
|
||||||
|
const id = navigateRoot ? commentSubTreeRootId(item, root) : item.id
|
||||||
|
|
||||||
let text = 'reply on another page'
|
const href = `/items/${id}` + (navigateRoot ? '' : `?commentId=${item.id}`)
|
||||||
if (item.ncomments > 0) {
|
|
||||||
text = `view all ${item.ncomments} replies`
|
const text = navigateRoot && item.ncomments === 0
|
||||||
}
|
? 'reply on another page'
|
||||||
|
: `view all ${item.ncomments} replies`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
|
href={href}
|
||||||
|
as={`/items/${id}`}
|
||||||
|
className='fw-bold d-flex align-items-center gap-2 text-muted'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if (!item.newComments?.length) return
|
||||||
// clear new comments going to another page
|
// clear new comments going to another page
|
||||||
cache.writeFragment({
|
cache.writeFragment({
|
||||||
id: `Item:${item.id}`,
|
id: `Item:${item.id}`,
|
||||||
@ -331,9 +328,6 @@ function ReplyOnAnotherPage ({ item }) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
href={`/items/${rootId}?commentId=${item.id}`}
|
|
||||||
as={`/items/${rootId}`}
|
|
||||||
className='pb-2 fw-bold d-flex align-items-center gap-2 text-muted'
|
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
{item.newComments?.length > 0 && <div className={styles.newCommentDot} />}
|
{item.newComments?.length > 0 && <div className={styles.newCommentDot} />}
|
||||||
|
@ -74,6 +74,10 @@ function traverseNewComments (client, item, onLevel, currentDepth, inSubtree) {
|
|||||||
// if we're at the depth limit, stop traversing, we've reached the bottom of the visible thread
|
// if we're at the depth limit, stop traversing, we've reached the bottom of the visible thread
|
||||||
if (currentDepth >= COMMENT_DEPTH_LIMIT) return
|
if (currentDepth >= COMMENT_DEPTH_LIMIT) return
|
||||||
|
|
||||||
|
// if the current item shows less comments than its nDirectComments, it's paginated
|
||||||
|
// we don't want to count/inject new comments in paginated items, as they shouldn't be visible
|
||||||
|
if (item.comments?.comments?.length < item.nDirectComments) return
|
||||||
|
|
||||||
if (item.newComments && item.newComments.length > 0) {
|
if (item.newComments && item.newComments.length > 0) {
|
||||||
const dedupedNewComments = dedupeNewComments(item.newComments, item.comments?.comments)
|
const dedupedNewComments = dedupeNewComments(item.newComments, item.comments?.comments)
|
||||||
|
|
||||||
@ -161,8 +165,8 @@ export function ShowNewComments ({ topLevel, item, sort, depth = 0 }) {
|
|||||||
const client = useApolloClient()
|
const client = useApolloClient()
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
|
|
||||||
// a thread is a top-level comment
|
// a thread comment is a comment at depth 1 (parent)
|
||||||
const thread = item.path?.split('.').length === 2
|
const thread = depth === 1
|
||||||
|
|
||||||
// recurse through all new comments and their children
|
// recurse through all new comments and their children
|
||||||
// if the item is a thread, we also consider all of their existing children
|
// if the item is a thread, we also consider all of their existing children
|
||||||
|
@ -7,12 +7,13 @@ import { itemUpdateQuery, commentUpdateFragment, getLatestCommentCreatedAt } fro
|
|||||||
const POLL_INTERVAL = 1000 * 10 // 10 seconds
|
const POLL_INTERVAL = 1000 * 10 // 10 seconds
|
||||||
|
|
||||||
// merge new comment into item's newComments
|
// merge new comment into item's newComments
|
||||||
// and prevent duplicates by checking if the comment is already in item's newComments
|
// and prevent duplicates by checking if the comment is already in item's newComments or existing comments
|
||||||
function mergeNewComment (item, newComment) {
|
function mergeNewComment (item, newComment) {
|
||||||
const existingNewComments = item.newComments || []
|
const existingNewComments = item.newComments || []
|
||||||
|
const existingComments = item.comments?.comments || []
|
||||||
|
|
||||||
// is the incoming new comment already in item's new comments?
|
// is the incoming new comment already in item's new comments or existing comments?
|
||||||
if (existingNewComments.includes(newComment.id)) {
|
if (existingNewComments.includes(newComment.id) || existingComments.some(comment => comment.id === newComment.id)) {
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user