Skip to content
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

Inline Commenting: Re-order the comments in sidebar in which blocks are listed #66927

Merged
merged 9 commits into from
Dec 4, 2024
34 changes: 28 additions & 6 deletions packages/editor/src/components/collab-sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useState, useMemo } from '@wordpress/element';
import { comment as commentIcon } from '@wordpress/icons';
import { addFilter } from '@wordpress/hooks';
import { store as noticesStore } from '@wordpress/notices';
import { store as coreStore } from '@wordpress/core-data';
import { store as coreStore, useEntityBlockEditor } from '@wordpress/core-data';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { store as interfaceStore } from '@wordpress/interface';

Expand All @@ -27,6 +27,7 @@ import { store as editorStore } from '../../store';
import AddCommentButton from './comment-button';
import AddCommentToolbarButton from './comment-button-toolbar';
import { useGlobalStylesContext } from '../global-styles-provider';
import { getCommentIdsFromBlocks } from './utils';

const isBlockCommentExperimentEnabled =
window?.__experimentalEnableBlockComment;
Expand Down Expand Up @@ -220,8 +221,11 @@ export default function CollabSidebar() {
const { enableComplementaryArea } = useDispatch( interfaceStore );
const { getActiveComplementaryArea } = useSelect( interfaceStore );

const { postStatus } = useSelect( ( select ) => {
const { postId, postType, postStatus } = useSelect( ( select ) => {
const { getCurrentPostId, getCurrentPostType } = select( editorStore );
return {
postId: getCurrentPostId(),
postType: getCurrentPostType(),
postStatus:
select( editorStore ).getEditedPostAttribute( 'status' ),
};
Expand Down Expand Up @@ -262,8 +266,12 @@ export default function CollabSidebar() {
};
}, [] );

const [ blocks ] = useEntityBlockEditor( 'postType', postType, {
id: postId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can there be a case where there is no current post ID?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it does, Ill put condition there to avoid errors.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some finding, Undefined postId is already being handled under useEntityBlockEditor for cases like templates and patterns.

} );

// Process comments to build the tree structure
const resultComments = useMemo( () => {
const { resultComments, sortedThreads } = useMemo( () => {
// Create a compare to store the references to all objects by id
const compare = {};
const result = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this always an array? Why guard with result??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, i'll update that.

Expand All @@ -288,8 +296,22 @@ export default function CollabSidebar() {
}
} );

return result;
}, [ threads ] );
if ( 0 === result?.length ) {
return { resultComments: [], sortedThreads: [] };
}

const blockCommentIds = getCommentIdsFromBlocks( blocks );

const threadIdMap = new Map(
result?.map( ( thread ) => [ thread.id, thread ] )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's possible for result to not be an array, we should probably just return early?

);

const sortedComments = blockCommentIds
.map( ( id ) => threadIdMap.get( id ) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I see above that a thread can be { ...item, reply: [] }, which will cause this component to constantly re-render.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow, we are re-arranging comments here so reply comments will go under the parent comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed that this is within useMemo instead of useSelect

.filter( ( thread ) => thread !== undefined );

return { resultComments: result, sortedThreads: sortedComments };
}, [ threads, blocks ] );

// Get the global styles to set the background color of the sidebar.
const { merged: GlobalStyles } = useGlobalStylesContext();
Expand Down Expand Up @@ -338,7 +360,7 @@ export default function CollabSidebar() {
headerClassName="editor-collab-sidebar__header"
>
<CollabSidebarContent
comments={ resultComments }
comments={ sortedThreads }
showCommentBoard={ showCommentBoard }
setShowCommentBoard={ setShowCommentBoard }
styles={ {
Expand Down
36 changes: 36 additions & 0 deletions packages/editor/src/components/collab-sidebar/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,39 @@
export function sanitizeCommentString( str ) {
return str.trim();
}

/**
* Extracts comment IDs from an array of blocks.
*
* This function recursively traverses the blocks and their inner blocks to
* collect all comment IDs found in the block attributes.
*
* @param {Array} blocks - The array of blocks to extract comment IDs from.
* @return {Array} An array of comment IDs extracted from the blocks.
*/
export function getCommentIdsFromBlocks( blocks ) {
// Recursive function to extract comment IDs from blocks
const extractCommentIds = ( items ) => {
return items.reduce( ( commentIds, block ) => {
// Check for comment IDs in the current block's attributes
if (
block.attributes &&
block.attributes.blockCommentId &&
! commentIds.includes( block.attributes.blockCommentId )
) {
commentIds.push( block.attributes.blockCommentId );
}

// Recursively check inner blocks
if ( block.innerBlocks && block.innerBlocks.length > 0 ) {
const innerCommentIds = extractCommentIds( block.innerBlocks );
commentIds.push( ...innerCommentIds );
}

return commentIds;
}, [] );
};

// Extract all comment IDs recursively
return extractCommentIds( blocks );
}
Loading