stacker.news/lib/new-comments.js
soxa b5af28c48b
Server-side tracking of comments view time (#2432)
* server-side comments view tracking, model structure, mutation

* full commentsViewedAt refactor, adjust comment creation and injection, adjust item navigation

* update server-side tracking only if there's a change, light cleanup

* coalesce meCommentsViewedAt to the item's createdAt, wip PoC comment outlining

* don't update cache on item visit, use useRoot hook for outlining

* add meCommentsViewedAt to root, better naming, light cleanup

* better timestamp logic and comparisons, add lastCommentAt to root item object, added TODOs

* fix: track commentsViewedAt only for root item, use topLevelId to fetch live comments only for the current item

* only track commentsViewedAt for root item, light cleanup

* light cleanup, correct live comments timestamp deps

* worker: on midnight, untrack items that were never viewed and had no comments in the last 21 days
2025-09-02 13:13:44 -05:00

43 lines
1.5 KiB
JavaScript

const COMMENTS_VIEW_PREFIX = 'commentsViewedAt'
const COMMENTS_NUM_PREFIX = 'commentsViewNum'
export function commentsViewed (item) {
if (!item.parentId && item.lastCommentAt) {
window.localStorage.setItem(`${COMMENTS_VIEW_PREFIX}:${item.id}`, new Date(item.lastCommentAt).getTime())
window.localStorage.setItem(`${COMMENTS_NUM_PREFIX}:${item.id}`, item.ncomments)
}
}
export function commentsViewedAt (itemId) {
return Number(window.localStorage.getItem(`${COMMENTS_VIEW_PREFIX}:${itemId}`))
}
export function commentsViewedNum (itemId) {
return Number(window.localStorage.getItem(`${COMMENTS_NUM_PREFIX}:${itemId}`))
}
export function commentsViewedAfterComment (rootId, createdAt, ncomments = 1) {
window.localStorage.setItem(`${COMMENTS_VIEW_PREFIX}:${rootId}`, new Date(createdAt).getTime())
window.localStorage.setItem(`${COMMENTS_NUM_PREFIX}:${rootId}`, commentsViewedNum(rootId) + ncomments)
}
export function newComments (item) {
if (!item.parentId && item.lastCommentAt) {
// if logged, prefer server-tracked view
if (item.meCommentsViewedAt) {
const viewedAt = new Date(item.meCommentsViewedAt).getTime()
return viewedAt < new Date(item.lastCommentAt).getTime()
}
// anon fallback
const viewedAt = commentsViewedAt(item.id)
const viewNum = commentsViewedNum(item.id)
if (viewedAt && viewNum) {
return viewedAt < new Date(item.lastCommentAt).getTime() || viewNum < item.ncomments
}
}
return false
}