-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Block comments: Add comment indicators in the block toolbar #71271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
e34c8c2
1f2a1db
73400a9
d8cf981
2e82c39
2520dfd
b286b3f
58e11a8
db5c16c
d9bf2ae
d46bbae
e9cc58e
970dda7
ff766e4
9f5f11a
237d7aa
0425317
b9defa9
342f655
24edb96
43bb5a3
22ab72b
b33eb7b
0f4d335
65ea1fd
c11a5c8
71df444
089d6fb
7d42184
97877fd
7b86a9a
e48d5ad
d42b3c4
6bff632
781e4d6
88f1954
c2080f1
a8acf34
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,87 +19,109 @@ import { store as editorStore } from '../../store'; | |
| const { CommentIconToolbarSlotFill } = unlock( blockEditorPrivateApis ); | ||
|
|
||
| const CommentAvatarIndicator = ( { onClick } ) => { | ||
| const { threadParticipants, hasUnresolved } = useSelect( ( select ) => { | ||
| const { getBlockAttributes, getSelectedBlockClientId } = | ||
| select( blockEditorStore ); | ||
| const { getCurrentPostId } = select( editorStore ); | ||
| const selectedBlock = getSelectedBlockClientId(); | ||
| const selectedBlockAttributes = selectedBlock | ||
| ? getBlockAttributes( selectedBlock ) | ||
| : null; | ||
| const postId = getCurrentPostId(); | ||
|
|
||
| // Get comment data for this block | ||
| const blockCommentIdValue = selectedBlockAttributes?.blockCommentId; | ||
| const participantsMap = new Map(); | ||
| let isResolved = false; | ||
|
|
||
| if ( blockCommentIdValue && postId ) { | ||
| const comments = select( coreStore ).getEntityRecords( | ||
| 'root', | ||
| 'comment', | ||
| { | ||
| const { threadParticipants, hasUnresolved, hasMoreComments } = useSelect( | ||
| ( select ) => { | ||
| const { getBlockAttributes, getSelectedBlockClientId } = | ||
| select( blockEditorStore ); | ||
| const { getCurrentPostId } = select( editorStore ); | ||
| const selectedBlock = getSelectedBlockClientId(); | ||
| const selectedBlockAttributes = selectedBlock | ||
| ? getBlockAttributes( selectedBlock ) | ||
| : null; | ||
| const postId = getCurrentPostId(); | ||
|
|
||
| // Get comment data for this block | ||
| const blockCommentIdValue = selectedBlockAttributes?.blockCommentId; | ||
| const participantsMap = new Map(); | ||
| let isResolved = false; | ||
| let moreCommentsExist = false; | ||
|
|
||
| if ( blockCommentIdValue && postId ) { | ||
| const queryArgs = { | ||
| post: postId, | ||
| type: 'block_comment', | ||
| status: 'any', | ||
| per_page: 100, | ||
adamsilverstein marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| ); | ||
|
|
||
| if ( comments ) { | ||
| // Get all comments in this thread | ||
| // Main comment has id === blockCommentIdValue | ||
| // Replies have parent === blockCommentIdValue | ||
| const threadComments = comments.filter( | ||
| ( comment ) => | ||
| comment.status !== 'trash' && | ||
| ( comment.id === blockCommentIdValue || | ||
| comment.parent === blockCommentIdValue ) | ||
| ); | ||
| }; | ||
|
|
||
| // Sort by date to show participants in chronological order | ||
| threadComments.sort( | ||
| ( a, b ) => new Date( a.date ) - new Date( b.date ) | ||
| const comments = select( coreStore ).getEntityRecords( | ||
| 'root', | ||
| 'comment', | ||
| queryArgs | ||
| ); | ||
|
|
||
| // Find the main thread comment (first comment) | ||
| const mainComment = threadComments.find( | ||
| ( comment ) => comment.id === blockCommentIdValue | ||
| // Check if there are more pages available | ||
| const totalPages = select( coreStore ).getEntityTotalPages( | ||
| 'root', | ||
| 'comment', | ||
| queryArgs | ||
| ); | ||
|
|
||
| // Thread is resolved if the main comment is approved | ||
| if ( mainComment ) { | ||
| isResolved = mainComment.status === 'approved'; | ||
| // If we have more than 1 page, there are more comments | ||
| if ( totalPages && totalPages > 1 ) { | ||
| moreCommentsExist = true; | ||
| } | ||
|
|
||
| threadComments.forEach( ( comment ) => { | ||
| // Track thread participants (original commenter + repliers) | ||
| if ( comment.author_name && comment.author_avatar_urls ) { | ||
| const authorKey = `${ comment.author }-${ comment.author_name }`; | ||
| if ( ! participantsMap.has( authorKey ) ) { | ||
| participantsMap.set( authorKey, { | ||
| name: comment.author_name, | ||
| avatar: | ||
| comment.author_avatar_urls?.[ '48' ] || | ||
| comment.author_avatar_urls?.[ '96' ], | ||
| isOriginalCommenter: | ||
| comment.id === blockCommentIdValue, | ||
| date: comment.date, | ||
| } ); | ||
| } | ||
| if ( comments ) { | ||
| // Get all comments in this thread | ||
| // Main comment has id === blockCommentIdValue | ||
| // Replies have parent === blockCommentIdValue | ||
| const threadComments = comments.filter( | ||
| ( comment ) => | ||
| comment.status !== 'trash' && | ||
| ( comment.id === blockCommentIdValue || | ||
| comment.parent === blockCommentIdValue ) | ||
| ); | ||
|
|
||
| // Sort by date to show participants in chronological order | ||
| threadComments.sort( | ||
| ( a, b ) => new Date( a.date ) - new Date( b.date ) | ||
| ); | ||
|
|
||
| // Find the main thread comment (first comment) | ||
| const mainComment = threadComments.find( | ||
| ( comment ) => comment.id === blockCommentIdValue | ||
| ); | ||
|
|
||
| // Thread is resolved if the main comment is approved | ||
| if ( mainComment ) { | ||
| isResolved = mainComment.status === 'approved'; | ||
| } | ||
| } ); | ||
|
|
||
| threadComments.forEach( ( comment ) => { | ||
| // Track thread participants (original commenter + repliers) | ||
| if ( | ||
| comment.author_name && | ||
| comment.author_avatar_urls | ||
| ) { | ||
| const authorKey = `${ comment.author }-${ comment.author_name }`; | ||
| if ( ! participantsMap.has( authorKey ) ) { | ||
| participantsMap.set( authorKey, { | ||
| name: comment.author_name, | ||
| avatar: | ||
| comment.author_avatar_urls?.[ '48' ] || | ||
|
||
| comment.author_avatar_urls?.[ '96' ], | ||
|
||
| isOriginalCommenter: | ||
| comment.id === blockCommentIdValue, | ||
| date: comment.date, | ||
| } ); | ||
| } | ||
| } | ||
| } ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Convert to array and maintain chronological order | ||
| const participants = Array.from( participantsMap.values() ); | ||
| // Convert to array and maintain chronological order | ||
| const participants = Array.from( participantsMap.values() ); | ||
|
|
||
| return { | ||
| threadParticipants: participants, | ||
| hasUnresolved: ! isResolved, | ||
| }; | ||
| }, [] ); | ||
| return { | ||
| threadParticipants: participants, | ||
| hasUnresolved: ! isResolved, | ||
| hasMoreComments: moreCommentsExist, | ||
| }; | ||
| }, | ||
| [] | ||
| ); | ||
|
|
||
| if ( ! threadParticipants.length ) { | ||
| return null; | ||
|
|
@@ -110,6 +132,15 @@ const CommentAvatarIndicator = ( { onClick } ) => { | |
| const visibleParticipants = threadParticipants.slice( 0, maxAvatars ); | ||
| const overflowCount = Math.max( 0, threadParticipants.length - maxAvatars ); | ||
|
|
||
| // If we hit the comment limit, show "100+" instead of exact overflow count | ||
| const overflowText = | ||
| hasMoreComments && overflowCount > 0 ? '100+' : `+${ overflowCount }`; | ||
yashjawale marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const overflowTitle = | ||
| hasMoreComments && overflowCount > 0 | ||
| ? '100+ participants' | ||
| : `+${ overflowCount } more participants`; | ||
yashjawale marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return ( | ||
| <CommentIconToolbarSlotFill.Fill> | ||
| <ToolbarButton | ||
|
|
@@ -135,9 +166,9 @@ const CommentAvatarIndicator = ( { onClick } ) => { | |
| <div | ||
| className="comment-avatar-overflow" | ||
| style={ { zIndex: 0 } } | ||
| title={ `+${ overflowCount } more participants` } | ||
| title={ overflowTitle } | ||
| > | ||
| +{ overflowCount } | ||
| { overflowText } | ||
| </div> | ||
| ) } | ||
| </div> | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.