stacker.news/components/use-comments-view.js
soxa fbeba23e27
Fix comments view tracking (#2485)
* backport useCommentsView from comments refactor

* adapt live comments and creation to useCommentsView; better outline conditions

* better deps usage, remove unused props

* safer usage of root and item

* light cleanup

* cleanup: remove unused useRoot on live comments

* light cleanup and affirm purpose of each function

* fallback to createdAt if no lastCommentAt only if we actually visit the item, not by default

* fix: don't track comments, remove unused useRoot, fix signature
2025-09-06 20:03:04 -05:00

47 lines
1.6 KiB
JavaScript

import { useMutation } from '@apollo/client'
import { useCallback } from 'react'
import { UPDATE_ITEM_USER_VIEW } from '@/fragments/items'
import { commentsViewedAfterComment, commentsViewed, newComments } from '@/lib/new-comments'
import { useMe } from './me'
export default function useCommentsView (itemId, { updateCache = true } = {}) {
const { me } = useMe()
const [updateCommentsViewAt] = useMutation(UPDATE_ITEM_USER_VIEW, {
update (cache, { data: { updateCommentsViewAt } }) {
if (!updateCache || !itemId) return
cache.modify({
id: `Item:${itemId}`,
fields: { meCommentsViewedAt: () => updateCommentsViewAt }
})
}
})
const updateViewedAt = useCallback((latest, anonFallbackFn) => {
if (me?.id) {
updateCommentsViewAt({ variables: { id: Number(itemId), meCommentsViewedAt: latest } })
} else {
anonFallbackFn()
}
}, [me?.id, itemId, updateCommentsViewAt])
// update meCommentsViewedAt on comment injection
const markCommentViewedAt = useCallback((latest, { ncomments } = {}) => {
if (!latest) return
updateViewedAt(latest, () => commentsViewedAfterComment(itemId, latest, ncomments))
}, [itemId, updateViewedAt])
// update meCommentsViewedAt on item view
const markItemViewed = useCallback((item, latest) => {
if (!item || item.parentId || (item?.meCommentsViewedAt && !newComments(item))) return
const lastAt = latest || item?.lastCommentAt || item?.createdAt
const newLatest = new Date(lastAt)
updateViewedAt(newLatest, () => commentsViewed(item))
}, [updateViewedAt])
return { markCommentViewedAt, markItemViewed }
}