1
1
import { COMMENT_DEPTH_LIMIT } from './constants'
2
- import { commentUpdateFragment , getLatestCommentCreatedAt } from '../components/use-live-comments'
3
2
import { commentsViewedAfterComment } from './new-comments'
4
- import { COMMENT_WITH_NEW_RECURSIVE } from '../fragments/comments'
3
+ import { COMMENT_WITH_NEW_RECURSIVE , COMMENT_WITH_NEW_LIMITED } from '../fragments/comments'
4
+ import { ITEM_FULL } from '../fragments/items'
5
5
6
+ // updates the ncomments field of all ancestors of an item/comment in the cache
6
7
export function updateAncestorsCommentCount ( cache , ancestors , increment ) {
7
8
// update all ancestors
8
9
ancestors . forEach ( id => {
@@ -19,11 +20,58 @@ export function updateAncestorsCommentCount (cache, ancestors, increment) {
19
20
}
20
21
21
22
// live comments - cache manipulations
23
+ // updates the item query in the cache
24
+ // this is used by live comments to update a top level item's newComments field
25
+ export function itemUpdateQuery ( client , id , sort , fn ) {
26
+ client . cache . updateQuery ( {
27
+ query : ITEM_FULL ,
28
+ // updateQuery needs the correct variables to update the correct item
29
+ // the Item query might have the router.query.sort in the variables, so we need to pass it in if it exists
30
+ variables : sort ? { id, sort } : { id }
31
+ } , ( data ) => {
32
+ if ( ! data ) return data
33
+ return { item : fn ( data . item ) }
34
+ } )
35
+ }
36
+
37
+ // updates a comment fragment in the cache, with a fallback for comments lacking CommentsRecursive
38
+ export function commentUpdateFragment ( client , id , fn ) {
39
+ let result = client . cache . updateFragment ( {
40
+ id : `Item:${ id } ` ,
41
+ fragment : COMMENT_WITH_NEW_RECURSIVE ,
42
+ fragmentName : 'CommentWithNewRecursive'
43
+ } , ( data ) => {
44
+ if ( ! data ) return data
45
+ return fn ( data )
46
+ } )
47
+
48
+ // sometimes comments can reach their depth limit, and lack adherence to the CommentsRecursive fragment
49
+ // for this reason, we update the fragment with a limited version that only includes the CommentFields fragment
50
+ if ( ! result ) {
51
+ result = client . cache . updateFragment ( {
52
+ id : `Item:${ id } ` ,
53
+ fragment : COMMENT_WITH_NEW_LIMITED ,
54
+ fragmentName : 'CommentWithNewLimited'
55
+ } , ( data ) => {
56
+ if ( ! data ) return data
57
+ return fn ( data )
58
+ } )
59
+ }
60
+
61
+ return result
62
+ }
63
+
64
+ // filters out new comments, by id, that already exist in the item's comments
65
+ // preventing duplicate comments from being injected
22
66
export function dedupeNewComments ( newComments , comments ) {
67
+ console . log ( 'dedupeNewComments' , newComments , comments )
23
68
const existingIds = new Set ( comments . map ( c => c . id ) )
24
69
return newComments . filter ( id => ! existingIds . has ( id ) )
25
70
}
26
71
72
+ // recursively collects all new comments from an item and its children
73
+ // by respecting the depth limit, we avoid collecting new comments to inject in places
74
+ // that are too deep in the tree
27
75
export function collectAllNewComments ( item , currentDepth = 1 ) {
28
76
const allNewComments = [ ...( item . newComments || [ ] ) ]
29
77
if ( item . comments ?. comments && currentDepth < ( COMMENT_DEPTH_LIMIT - 1 ) ) {
@@ -34,6 +82,8 @@ export function collectAllNewComments (item, currentDepth = 1) {
34
82
return allNewComments
35
83
}
36
84
85
+ // prepares and creates a new comments fragment for injection into the cache
86
+ // returns a function that can be used to update an item's comments field
37
87
export function prepareComments ( client , newComments ) {
38
88
return ( data ) => {
39
89
// newComments is an array of comment ids that allows us
@@ -69,6 +119,7 @@ export function prepareComments (client, newComments) {
69
119
const rootId = data . path . split ( '.' ) [ 0 ]
70
120
commentsViewedAfterComment ( rootId , latestCommentCreatedAt )
71
121
122
+ // return the updated item with the new comments injected
72
123
return {
73
124
...data ,
74
125
comments : { ...data . comments , comments : [ ...freshNewComments , ...data . comments . comments ] } ,
@@ -78,6 +129,8 @@ export function prepareComments (client, newComments) {
78
129
}
79
130
}
80
131
132
+ // recursively processes and displays all new comments for a thread
133
+ // handles comment injection at each level, respecting depth limits
81
134
export function showAllNewCommentsRecursively ( client , item , currentDepth = 1 ) {
82
135
// handle new comments at this item level
83
136
if ( item . newComments && item . newComments . length > 0 ) {
@@ -96,3 +149,11 @@ export function showAllNewCommentsRecursively (client, item, currentDepth = 1) {
96
149
}
97
150
}
98
151
}
152
+
153
+ // finds the most recent createdAt timestamp from an array of comments
154
+ export function getLatestCommentCreatedAt ( comments , latest ) {
155
+ return comments . reduce (
156
+ ( max , { createdAt } ) => ( createdAt > max ? createdAt : max ) ,
157
+ latest
158
+ )
159
+ }
0 commit comments