From ccf3d2512edcba4fef047ca3204b5a00842cdbb0 Mon Sep 17 00:00:00 2001 From: akasunil Date: Thu, 28 Nov 2024 15:56:46 +0530 Subject: [PATCH 01/11] Refactored comments components and show replies on button click --- .../components/collab-sidebar/comment-form.js | 5 +- .../src/components/collab-sidebar/comments.js | 461 +++++++++--------- .../src/components/collab-sidebar/style.scss | 4 + 3 files changed, 246 insertions(+), 224 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comment-form.js b/packages/editor/src/components/collab-sidebar/comment-form.js index 052fd3cdd26568..bd139a682f5cb7 100644 --- a/packages/editor/src/components/collab-sidebar/comment-form.js +++ b/packages/editor/src/components/collab-sidebar/comment-form.js @@ -42,7 +42,10 @@ function CommentForm( { onSubmit, onCancel, thread, submitButtonText } ) { __next40pxDefaultSize accessibleWhenDisabled variant="primary" - onClick={ () => onSubmit( inputComment ) } + onClick={ () => { + onSubmit( inputComment ); + setInputComment( '' ); + } } disabled={ 0 === sanitizeCommentString( inputComment ).length } diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index 7a03068787c81e..f5d95621cb250b 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -6,7 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ -import { useState, RawHTML } from '@wordpress/element'; +import { useState, RawHTML, useEffect } from '@wordpress/element'; import { __experimentalHStack as HStack, __experimentalVStack as VStack, @@ -16,7 +16,7 @@ import { Tooltip, } from '@wordpress/components'; import { Icon, check, published, moreVertical } from '@wordpress/icons'; -import { __, _x } from '@wordpress/i18n'; +import { __, _x, sprintf } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; @@ -44,25 +44,7 @@ export function Comments( { onCommentDelete, onCommentResolve, } ) { - const [ actionState, setActionState ] = useState( false ); - const [ isConfirmDialogOpen, setIsConfirmDialogOpen ] = useState( false ); - - const handleConfirmDelete = () => { - onCommentDelete( actionState.id ); - setActionState( false ); - setIsConfirmDialogOpen( false ); - }; - - const handleConfirmResolve = () => { - onCommentResolve( actionState.id ); - setActionState( false ); - setIsConfirmDialogOpen( false ); - }; - - const handleCancelDelete = () => { - setActionState( false ); - setIsConfirmDialogOpen( false ); - }; + const [ focusThread, setFocusThread ] = useState( null ); const blockCommentId = useSelect( ( select ) => { const clientID = select( blockEditorStore ).getSelectedBlockClientId(); @@ -72,101 +54,11 @@ export function Comments( { ); }, [] ); - const CommentBoard = ( { thread, parentThread } ) => { - return ( - <> - { - setActionState( { - action: 'resolve', - id: parentThread?.id ?? thread.id, - } ); - setIsConfirmDialogOpen( true ); - } } - onEdit={ () => - setActionState( { action: 'edit', id: thread.id } ) - } - onDelete={ () => { - setActionState( { action: 'delete', id: thread.id } ); - setIsConfirmDialogOpen( true ); - } } - onReply={ - ! parentThread - ? () => - setActionState( { - action: 'reply', - id: thread.id, - } ) - : undefined - } - status={ parentThread?.status ?? thread.status } - /> - - - { 'edit' === actionState?.action && - thread.id === actionState?.id && ( - { - onEditComment( thread.id, value ); - setActionState( false ); - } } - onCancel={ () => setActionState( false ) } - thread={ thread } - submitButtonText={ _x( 'Update', 'verb' ) } - /> - ) } - { ( ! actionState || - 'edit' !== actionState?.action ) && ( - { thread?.content?.raw } - ) } - - - { 'resolve' === actionState?.action && - thread.id === actionState?.id && ( - - { - // translators: message displayed when confirming an action - __( - 'Are you sure you want to mark this comment as resolved?' - ) - } - - ) } - { 'delete' === actionState?.action && - thread.id === actionState?.id && ( - - { - // translators: message displayed when confirming an action - __( - 'Are you sure you want to delete this comment?' - ) - } - - ) } - - ); - }; + useEffect( () => { + if ( blockCommentId ) { + setFocusThread( blockCommentId ); + } + }, [ blockCommentId ] ); return ( <> @@ -186,7 +78,6 @@ export function Comments( { ) } - { Array.isArray( threads ) && threads.length > 0 && threads.map( ( thread ) => ( @@ -196,98 +87,157 @@ export function Comments( { 'editor-collab-sidebar-panel__thread', { 'editor-collab-sidebar-panel__active-thread': - blockCommentId && - blockCommentId === thread.id, + focusThread && focusThread === thread.id, } ) } id={ thread.id } spacing="3" + onClick={ () => setFocusThread( thread.id ) } > - - { 0 < thread?.reply?.length && - thread.reply.map( ( reply ) => ( - - - - ) ) } - { 'reply' === actionState?.action && - thread.id === actionState?.id && ( - - - - - - { - onAddReply( - inputComment, - thread.id - ); - setActionState( false ); - } } - onCancel={ () => - setActionState( false ) - } - submitButtonText={ _x( - 'Reply', - 'Add reply comment' - ) } - /> - - - ) } + ) ) } ); } -/** - * Renders the header of a comment in the collaboration sidebar. - * - * @param {Object} props - The component props. - * @param {Object} props.thread - The comment thread object. - * @param {Function} props.onResolve - The function to resolve the comment. - * @param {Function} props.onEdit - The function to edit the comment. - * @param {Function} props.onDelete - The function to delete the comment. - * @param {Function} props.onReply - The function to reply to the comment. - * @param {string} props.status - The status of the comment. - * @return {React.ReactNode} The rendered comment header. - */ -function CommentHeader( { +function Thread( { + thread, + onEditComment, + onAddReply, + onCommentDelete, + onCommentResolve, +} ) { + const [ showMoreReply, setShowMoreReply ] = useState( false ); + const [ showReplyInput, setShowReplyInput ] = useState( false ); + + const handleReply = () => { + setShowReplyInput( true ); + }; + + return ( + <> + + { 0 < thread?.reply?.length && ( + <> + { ! showMoreReply && ( + + ) } + + { showMoreReply && + thread.reply.map( ( reply ) => ( + + + + ) ) } + + ) } + { 'approved' !== thread.status && showReplyInput && ( + + + + + + { + onAddReply( inputComment, thread.id ); + } } + onCancel={ () => setShowReplyInput( false ) } + submitButtonText={ _x( + 'Reply', + 'Add reply comment' + ) } + /> + + + ) } + + ); +} + +const CommentBoard = ( { thread, onResolve, onEdit, onDelete, onReply, status, -} ) { +} ) => { + const [ actionState, setActionState ] = useState( false ); + const [ showConfirmDialog, setShowConfirmDialog ] = useState( false ); + + const handleConfirmDelete = () => { + onDelete( thread.id ); + setActionState( false ); + setShowConfirmDialog( false ); + }; + + const handleConfirmResolve = () => { + onResolve( thread.id ); + setActionState( false ); + setShowConfirmDialog( false ); + }; + + const handleCancel = () => { + setActionState( false ); + setShowConfirmDialog( false ); + }; + const actions = [ { title: _x( 'Edit', 'Edit comment' ), - onClick: onEdit, + onClick: () => { + setActionState( 'edit' ); + }, }, { title: _x( 'Delete', 'Delete comment' ), - onClick: onDelete, + onClick: () => { + setActionState( 'delete' ); + setShowConfirmDialog( true ); + }, }, { title: _x( 'Reply', 'Reply on a comment' ), @@ -298,45 +248,110 @@ function CommentHeader( { const moreActions = actions.filter( ( item ) => item.onClick ); return ( - - - - { status !== 'approved' && ( - - { 0 === thread?.parent && onResolve && ( - + ) } - { showMoreReply && + { isFocused && thread.reply.map( ( reply ) => ( - + { 'approved' !== thread.status && ( + + ) } + { 'approved' === thread.status && ( + + ) } ) ) } ) } - { 'approved' !== thread.status && showReplyInput && ( + { 'approved' !== thread.status && isFocused && ( { onAddReply( inputComment, thread.id ); } } - onCancel={ () => setShowReplyInput( false ) } + onCancel={ ( event ) => { + event.stopPropagation(); // Prevent the parent onClick from being triggered + clearThreadFocus(); + } } submitButtonText={ _x( 'Reply', 'Add reply comment' @@ -197,14 +218,7 @@ function Thread( { ); } -const CommentBoard = ( { - thread, - onResolve, - onEdit, - onDelete, - onReply, - status, -} ) => { +const CommentBoard = ( { thread, onResolve, onEdit, onDelete, status } ) => { const [ actionState, setActionState ] = useState( false ); const [ showConfirmDialog, setShowConfirmDialog ] = useState( false ); @@ -226,26 +240,22 @@ const CommentBoard = ( { }; const actions = [ - { + onEdit && { title: _x( 'Edit', 'Edit comment' ), onClick: () => { setActionState( 'edit' ); }, }, - { + onDelete && { title: _x( 'Delete', 'Delete comment' ), onClick: () => { setActionState( 'delete' ); setShowConfirmDialog( true ); }, }, - { - title: _x( 'Reply', 'Reply on a comment' ), - onClick: onReply, - }, ]; - const moreActions = actions.filter( ( item ) => item.onClick ); + const moreActions = actions.filter( ( item ) => item?.onClick ); return ( <> @@ -277,15 +287,17 @@ const CommentBoard = ( { showTooltip /> ) } - + { 0 < moreActions.length && ( + + ) } ) } { status === 'approved' && ( From 01870de33b07501ab18370e0f747432f9aa00d48 Mon Sep 17 00:00:00 2001 From: akasunil Date: Wed, 4 Dec 2024 12:35:45 +0530 Subject: [PATCH 05/11] Remove board highlight on block selection change --- packages/editor/src/components/collab-sidebar/comments.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index b772245321aaf0..2a44589756bbc5 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -61,11 +61,9 @@ export function Comments( { // Set active thread when block is selected. useEffect( () => { - if ( blockCommentId ) { - setActiveThread( blockCommentId ); - setFocusThread( null ); - setShowCommentBoard( false ); - } + setActiveThread( blockCommentId ?? null ); + setFocusThread( null ); + setShowCommentBoard( false ); }, [ blockCommentId ] ); // Set thread focus when block is selected and comment icon is clicked. From 92c0e99cd3fdaacf5a5e45e119902cc39fe0c606 Mon Sep 17 00:00:00 2001 From: akasunil Date: Wed, 4 Dec 2024 12:53:59 +0530 Subject: [PATCH 06/11] Close popover on new comment option click --- .../collab-sidebar/comment-button.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comment-button.js b/packages/editor/src/components/collab-sidebar/comment-button.js index 373ee0becd92df..37300be147e1de 100644 --- a/packages/editor/src/components/collab-sidebar/comment-button.js +++ b/packages/editor/src/components/collab-sidebar/comment-button.js @@ -17,13 +17,18 @@ const { CommentIconSlotFill } = unlock( blockEditorPrivateApis ); const AddCommentButton = ( { onClick } ) => { return ( - - { _x( 'Comment', 'Add comment button' ) } - + { ( { onClose } ) => ( + { + onClick(); + onClose(); + } } + aria-haspopup="dialog" + > + { _x( 'Comment', 'Add comment button' ) } + + ) } ); }; From 29218bb92cd70ecf9bf14e40418480248de09571 Mon Sep 17 00:00:00 2001 From: akasunil Date: Wed, 4 Dec 2024 12:59:35 +0530 Subject: [PATCH 07/11] Fix styles for new comment board --- packages/editor/src/components/collab-sidebar/add-comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/collab-sidebar/add-comment.js b/packages/editor/src/components/collab-sidebar/add-comment.js index 2330017ac5db53..f94891ada07109 100644 --- a/packages/editor/src/components/collab-sidebar/add-comment.js +++ b/packages/editor/src/components/collab-sidebar/add-comment.js @@ -45,7 +45,7 @@ export function AddComment( { return ( From 989bb45135feffca2b42ee9f14121806e3de9e33 Mon Sep 17 00:00:00 2001 From: akasunil Date: Wed, 4 Dec 2024 14:17:50 +0530 Subject: [PATCH 08/11] Fix reply order issue --- packages/editor/src/components/collab-sidebar/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/index.js b/packages/editor/src/components/collab-sidebar/index.js index 4b3eec404683ac..7de9b363045928 100644 --- a/packages/editor/src/components/collab-sidebar/index.js +++ b/packages/editor/src/components/collab-sidebar/index.js @@ -290,12 +290,12 @@ export default function CollabSidebar() { } } ); - result.map( ( item ) => { - item.reply = item.reply.reverse(); - return item; - } ); + const updatedResult = result.map( ( item ) => ( { + ...item, + reply: [ ...item.reply ].reverse(), + } ) ); - return result; + return updatedResult; }, [ threads ] ); // Get the global styles to set the background color of the sidebar. From 038af2a1788ae464b86b15575157d7af3f28d443 Mon Sep 17 00:00:00 2001 From: akasunil Date: Wed, 4 Dec 2024 16:19:34 +0530 Subject: [PATCH 09/11] Remove unneccessory state --- packages/editor/src/components/collab-sidebar/comments.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index 2a44589756bbc5..4ae1143f857421 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -49,7 +49,6 @@ export function Comments( { setShowCommentBoard, } ) { const [ focusThread, setFocusThread ] = useState( null ); - const [ activeThread, setActiveThread ] = useState( null ); const blockCommentId = useSelect( ( select ) => { const clientID = select( blockEditorStore ).getSelectedBlockClientId(); @@ -61,7 +60,6 @@ export function Comments( { // Set active thread when block is selected. useEffect( () => { - setActiveThread( blockCommentId ?? null ); setFocusThread( null ); setShowCommentBoard( false ); }, [ blockCommentId ] ); @@ -105,7 +103,8 @@ export function Comments( { 'editor-collab-sidebar-panel__thread', { 'editor-collab-sidebar-panel__active-thread': - activeThread && activeThread === thread.id, + blockCommentId && + blockCommentId === thread.id, 'editor-collab-sidebar-panel__focus-thread': focusThread && focusThread === thread.id, } From 9a32000133550c8316598ecec77734aaab3fe57a Mon Sep 17 00:00:00 2001 From: akasunil Date: Thu, 5 Dec 2024 13:53:46 +0530 Subject: [PATCH 10/11] Set initial value for focusThread state and remove use of useEffect --- .../src/components/collab-sidebar/comments.js | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index 4ae1143f857421..d492d233956cb7 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -6,7 +6,7 @@ import clsx from 'clsx'; /** * WordPress dependencies */ -import { useState, RawHTML, useEffect } from '@wordpress/element'; +import { useState, RawHTML } from '@wordpress/element'; import { __experimentalHStack as HStack, __experimentalVStack as VStack, @@ -48,28 +48,21 @@ export function Comments( { showCommentBoard, setShowCommentBoard, } ) { - const [ focusThread, setFocusThread ] = useState( null ); + const { blockCommentId } = useSelect( ( select ) => { + const { getBlockAttributes, getSelectedBlockClientId } = + select( blockEditorStore ); + const _clientId = getSelectedBlockClientId(); - const blockCommentId = useSelect( ( select ) => { - const clientID = select( blockEditorStore ).getSelectedBlockClientId(); - return ( - select( blockEditorStore ).getBlock( clientID )?.attributes - ?.blockCommentId ?? false - ); + return { + blockCommentId: _clientId + ? getBlockAttributes( _clientId )?.blockCommentId + : null, + }; }, [] ); - // Set active thread when block is selected. - useEffect( () => { - setFocusThread( null ); - setShowCommentBoard( false ); - }, [ blockCommentId ] ); - - // Set thread focus when block is selected and comment icon is clicked. - useEffect( () => { - if ( blockCommentId && showCommentBoard ) { - setFocusThread( blockCommentId ); - } - }, [ showCommentBoard ] ); + const [ focusThread, setFocusThread ] = useState( + showCommentBoard && blockCommentId ? blockCommentId : null + ); const clearThreadFocus = () => { setFocusThread( null ); From b925cba09f607907d60395880c645a9453e32882 Mon Sep 17 00:00:00 2001 From: akasunil Date: Thu, 5 Dec 2024 16:20:20 +0530 Subject: [PATCH 11/11] Fix component remount issue --- packages/editor/src/components/collab-sidebar/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/editor/src/components/collab-sidebar/index.js b/packages/editor/src/components/collab-sidebar/index.js index 0dece8ed7657e5..c53ee9e7e919c6 100644 --- a/packages/editor/src/components/collab-sidebar/index.js +++ b/packages/editor/src/components/collab-sidebar/index.js @@ -203,6 +203,7 @@ function CollabSidebarContent( { setShowCommentBoard={ setShowCommentBoard } />