Skip to content

Commit 08bbba4

Browse files
committed
refactor: clearer naming, optimized polling and date retrieval logic, use of constants, general cleanup
1 parent 8126858 commit 08bbba4

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

components/use-live-comments.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { SSR } from '../lib/constants'
33
import { GET_NEW_COMMENTS, COMMENT_WITH_NEW } from '../fragments/comments'
44
import { ITEM_FULL } from '../fragments/items'
55
import { useEffect, useState } from 'react'
6-
import styles from './comments.module.css'
6+
import styles from './comment.module.css'
7+
8+
const POLL_INTERVAL = 1000 * 10 // 10 seconds
9+
const ACTIVITY_TIMEOUT = 1000 * 60 * 30 // 30 minutes
10+
const ACTIVITY_CHECK_INTERVAL = 1000 * 60 // 1 minute
711

812
export default function useLiveComments (rootId, after) {
913
const client = useApolloClient()
@@ -25,19 +29,20 @@ export default function useLiveComments (rootId, after) {
2529
const isActive = document.visibilityState === 'visible'
2630

2731
// poll only if the user is active and has been active in the last 30 minutes
28-
if (timeSinceEngaged < 1000 * 60 * 30) {
32+
if (timeSinceEngaged < ACTIVITY_TIMEOUT) {
2933
setPolling(isActive)
3034
} else {
3135
setPolling(false)
3236
}
3337
}
3438

3539
// check activity every minute
36-
const interval = setInterval(checkActivity, 1000 * 60)
40+
const interval = setInterval(checkActivity, ACTIVITY_CHECK_INTERVAL)
3741
// check activity also on visibility change
3842
document.addEventListener('visibilitychange', checkActivity)
3943

4044
return () => {
45+
// cleanup
4146
document.removeEventListener('visibilitychange', checkActivity)
4247
clearInterval(interval)
4348
}
@@ -46,25 +51,22 @@ export default function useLiveComments (rootId, after) {
4651
const { data } = useQuery(GET_NEW_COMMENTS, SSR
4752
? {}
4853
: {
49-
pollInterval: polling ? 10000 : null,
54+
pollInterval: polling ? POLL_INTERVAL : null,
5055
variables: { rootId, after: latest }
5156
})
5257

5358
useEffect(() => {
54-
if (data && data.newComments) {
55-
saveNewComments(client, rootId, data.newComments.comments)
56-
// check new comments created after the latest new comment
57-
const latestCommentCreatedAt = getLatestCommentCreatedAt(data.newComments.comments, latest)
58-
if (latestCommentCreatedAt) {
59-
setLatest(latestCommentCreatedAt)
60-
}
61-
}
62-
}, [data, client, rootId, latest])
59+
if (!data?.newComments) return
60+
61+
cacheNewComments(client, rootId, data.newComments.comments)
62+
// check new comments created after the latest new comment
63+
setLatest(prevLatest => getLatestCommentCreatedAt(data.newComments.comments, prevLatest))
64+
}, [data, client, rootId])
6365

6466
return { polling, setPolling }
6567
}
6668

67-
function saveNewComments (client, rootId, newComments) {
69+
function cacheNewComments (client, rootId, newComments) {
6870
for (const newComment of newComments) {
6971
const { parentId } = newComment
7072
const topLevel = Number(parentId) === Number(rootId)
@@ -77,7 +79,7 @@ function saveNewComments (client, rootId, newComments) {
7779
}, (data) => {
7880
if (!data) return data
7981
// we return the entire item, not just the newComments
80-
return { item: dedupeComment(data?.item, newComment) }
82+
return { item: mergeNewComments(data?.item, newComment) }
8183
})
8284
} else {
8385
// if the comment is a reply, update the parent comment
@@ -88,13 +90,13 @@ function saveNewComments (client, rootId, newComments) {
8890
}, (data) => {
8991
if (!data) return data
9092
// here we return the parent comment with the new comment added
91-
return dedupeComment(data, newComment)
93+
return mergeNewComments(data, newComment)
9294
})
9395
}
9496
}
9597
}
9698

97-
function dedupeComment (item, newComment) {
99+
function mergeNewComments (item, newComment) {
98100
const existingNewComments = item.newComments || []
99101
const existingComments = item.comments?.comments || []
100102

@@ -106,15 +108,15 @@ function dedupeComment (item, newComment) {
106108
}
107109

108110
function getLatestCommentCreatedAt (comments, latest) {
109-
if (comments.length === 0) return null
110-
111-
for (const comment of comments) {
112-
if (comment.createdAt > latest) {
113-
latest = comment.createdAt
114-
}
115-
}
116-
117-
return latest
111+
if (comments.length === 0) return latest
112+
113+
// timestamp comparison via Math.max on bare timestamps
114+
// convert all createdAt to timestamps
115+
const timestamps = comments.map(c => new Date(c.createdAt).getTime())
116+
// find the latest timestamp
117+
const maxTimestamp = Math.max(...timestamps, new Date(latest).getTime())
118+
// convert back to ISO string
119+
return new Date(maxTimestamp).toISOString()
118120
}
119121

120122
export function ShowNewComments ({ newComments = [], itemId, topLevel = false }) {

0 commit comments

Comments
 (0)