From 912ec5ad0534a6a6cec9baa76a7f9f13484889a8 Mon Sep 17 00:00:00 2001 From: karthick-murugan Date: Fri, 8 Nov 2024 19:44:56 +0530 Subject: [PATCH 01/18] Scroll editor blocks based on comments --- .../src/components/collab-sidebar/comments.js | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index c0b4bd3d4dc38a..89054abe68bca4 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -52,6 +52,8 @@ export function Comments( { } ) { const [ actionState, setActionState ] = useState( false ); const [ isConfirmDialogOpen, setIsConfirmDialogOpen ] = useState( false ); + const [ activeClientId, setActiveClientId ] = useState( null ); + const [ blocksList, setBlocksList ] = useState( null ); const handleConfirmDelete = () => { onCommentDelete( actionState.id ); @@ -70,14 +72,54 @@ export function Comments( { setIsConfirmDialogOpen( false ); }; - const blockCommentId = useSelect( ( select ) => { + useSelect( ( select ) => { const clientID = select( blockEditorStore ).getSelectedBlockClientId(); - return ( + const clientBlocks = select( blockEditorStore ).getBlocks(); + setBlocksList( clientBlocks ); + + const getBlockCommentId = select( blockEditorStore ).getBlock( clientID )?.attributes - ?.blockCommentId ?? false - ); + ?.blockCommentId ?? false; + + if ( getBlockCommentId ) { + setActiveClientId( getBlockCommentId ); + } }, [] ); + const findBlockByCommentId = ( blocks, commentId ) => { + for ( const block of blocks ) { + if ( block.attributes.blockCommentId === commentId ) { + return block; + } + if ( block.innerBlocks && block.innerBlocks.length > 0 ) { + const foundBlock = findBlockByCommentId( + block.innerBlocks, + commentId + ); + if ( foundBlock ) { + return foundBlock; + } + } + } + return null; + }; + + const handleThreadClick = ( thread ) => { + const block = findBlockByCommentId( blocksList, thread.id ); + + if ( block ) { + const bclientId = block.clientId; + const blockElement = document.getElementById( + 'block-' + bclientId + ); + + if ( blockElement ) { + blockElement.scrollIntoView( { behavior: 'smooth' } ); + setActiveClientId( thread.id ); + } + } + }; + const CommentBoard = ( { thread, parentThread } ) => { return ( <> @@ -201,12 +243,13 @@ export function Comments( { 'editor-collab-sidebar-panel__thread', { 'editor-collab-sidebar-panel__active-thread': - blockCommentId && - blockCommentId === thread.id, + activeClientId && + activeClientId === thread.id, } ) } id={ thread.id } spacing="3" + onClick={ () => handleThreadClick( thread ) } > { 'reply' === actionState?.action && From 154c2734b5c951ea940cfa36b6e9c364070594ec Mon Sep 17 00:00:00 2001 From: karthick-murugan Date: Fri, 8 Nov 2024 20:02:50 +0530 Subject: [PATCH 02/18] Update blockClientId --- packages/editor/src/components/collab-sidebar/comments.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index 89054abe68bca4..a163a6ef308920 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -108,9 +108,9 @@ export function Comments( { const block = findBlockByCommentId( blocksList, thread.id ); if ( block ) { - const bclientId = block.clientId; + const blockClientId = block.clientId; const blockElement = document.getElementById( - 'block-' + bclientId + 'block-' + blockClientId ); if ( blockElement ) { From 52341d1779f5393924491c71ee6c8d81fe8f7638 Mon Sep 17 00:00:00 2001 From: karthick-murugan Date: Mon, 11 Nov 2024 11:57:46 +0530 Subject: [PATCH 03/18] Update Iframe --- packages/editor/src/components/collab-sidebar/comments.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index a163a6ef308920..88aa7f03a8c520 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -109,7 +109,12 @@ export function Comments( { if ( block ) { const blockClientId = block.clientId; - const blockElement = document.getElementById( + const iframe = document.querySelector( + 'iframe[name="editor-canvas"]' + ); + const iframeDocument = + iframe.contentDocument || iframe.contentWindow.document; + const blockElement = iframeDocument.getElementById( 'block-' + blockClientId ); From aef8840633de4d127cf91e34c010f29338b7bdd2 Mon Sep 17 00:00:00 2001 From: karthick-murugan Date: Tue, 26 Nov 2024 20:14:44 +0530 Subject: [PATCH 04/18] Feedback Changes --- .../src/components/collab-sidebar/comments.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index 88aa7f03a8c520..cef50991a371ed 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -23,7 +23,7 @@ import { } from '@wordpress/date'; import { Icon, check, published, moreVertical } from '@wordpress/icons'; import { __, _x } from '@wordpress/i18n'; -import { useSelect } from '@wordpress/data'; +import { useSelect, dispatch } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data'; import { store as blockEditorStore } from '@wordpress/block-editor'; @@ -106,22 +106,10 @@ export function Comments( { const handleThreadClick = ( thread ) => { const block = findBlockByCommentId( blocksList, thread.id ); - if ( block ) { const blockClientId = block.clientId; - const iframe = document.querySelector( - 'iframe[name="editor-canvas"]' - ); - const iframeDocument = - iframe.contentDocument || iframe.contentWindow.document; - const blockElement = iframeDocument.getElementById( - 'block-' + blockClientId - ); - - if ( blockElement ) { - blockElement.scrollIntoView( { behavior: 'smooth' } ); - setActiveClientId( thread.id ); - } + // Select the block in the editor + dispatch( blockEditorStore ).selectBlock( blockClientId ); } }; From dad8215c8cafc9890ce213fabd17868707f08715 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 27 Nov 2024 12:24:10 +0100 Subject: [PATCH 05/18] Site Editor: Unify layout with posts dataviews (#67162) Co-authored-by: youknowriad Co-authored-by: ntsekouras --- .../edit-site/src/components/app/index.js | 19 ++++--------------- .../edit-site/src/components/layout/index.js | 17 +++++++++++++++-- .../src/components/posts-app/index.js | 14 +++----------- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/packages/edit-site/src/components/app/index.js b/packages/edit-site/src/components/app/index.js index 3588565fcb3c17..7e4c50d7d00f09 100644 --- a/packages/edit-site/src/components/app/index.js +++ b/packages/edit-site/src/components/app/index.js @@ -1,11 +1,6 @@ /** * WordPress dependencies */ -import { SlotFillProvider } from '@wordpress/components'; -import { - UnsavedChangesWarning, - privateApis as editorPrivateApis, -} from '@wordpress/editor'; import { store as noticesStore } from '@wordpress/notices'; import { useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; @@ -23,7 +18,6 @@ import useSetCommandContext from '../../hooks/commands/use-set-command-context'; import { useRegisterSiteEditorRoutes } from '../site-editor-routes'; const { RouterProvider } = unlock( routerPrivateApis ); -const { GlobalStylesProvider } = unlock( editorPrivateApis ); function AppLayout() { useCommonCommands(); @@ -50,14 +44,9 @@ export default function App() { } return ( - - - - - - - - - + + + + ); } diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index cbc0a4661bf3e7..47ff65aa2ac678 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -10,6 +10,7 @@ import { __unstableMotion as motion, __unstableAnimatePresence as AnimatePresence, __unstableUseNavigateRegions as useNavigateRegions, + SlotFillProvider, } from '@wordpress/components'; import { useReducedMotion, @@ -23,6 +24,7 @@ import { CommandMenu } from '@wordpress/commands'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; import { EditorSnackbars, + UnsavedChangesWarning, privateApis as editorPrivateApis, } from '@wordpress/editor'; import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands'; @@ -44,12 +46,12 @@ import SavePanel from '../save-panel'; const { useCommands } = unlock( coreCommandsPrivateApis ); const { useGlobalStyle } = unlock( blockEditorPrivateApis ); -const { NavigableRegion } = unlock( editorPrivateApis ); +const { NavigableRegion, GlobalStylesProvider } = unlock( editorPrivateApis ); const { useLocation } = unlock( routerPrivateApis ); const ANIMATION_DURATION = 0.3; -export default function Layout( { route } ) { +function Layout( { route } ) { const { params } = useLocation(); const { canvas = 'view' } = params; useCommands(); @@ -78,6 +80,7 @@ export default function Layout( { route } ) { return ( <> + { canvas === 'view' && }
); } + +export default function LayoutWithGlobalStylesProvider( props ) { + return ( + + + + + + ); +} diff --git a/packages/edit-site/src/components/posts-app/index.js b/packages/edit-site/src/components/posts-app/index.js index 72e5b1eb997498..e6eb90c1680019 100644 --- a/packages/edit-site/src/components/posts-app/index.js +++ b/packages/edit-site/src/components/posts-app/index.js @@ -1,10 +1,6 @@ /** * WordPress dependencies */ -import { - UnsavedChangesWarning, - privateApis as editorPrivateApis, -} from '@wordpress/editor'; import { privateApis as routerPrivateApis } from '@wordpress/router'; /** @@ -16,7 +12,6 @@ import { unlock } from '../../lock-unlock'; import useActiveRoute from '../layout/router'; const { RouterProvider } = unlock( routerPrivateApis ); -const { GlobalStylesProvider } = unlock( editorPrivateApis ); function PostsLayout() { useRegisterPostsAppRoutes(); @@ -26,11 +21,8 @@ function PostsLayout() { export default function PostsApp() { return ( - - - - - - + + + ); } From cd730bb3c231ef9d256648f1c9f8714b4eba7868 Mon Sep 17 00:00:00 2001 From: karthick-murugan Date: Fri, 8 Nov 2024 19:44:56 +0530 Subject: [PATCH 06/18] Scroll editor blocks based on comments --- .../src/components/collab-sidebar/comments.js | 180 ++++++++++++------ 1 file changed, 126 insertions(+), 54 deletions(-) diff --git a/packages/editor/src/components/collab-sidebar/comments.js b/packages/editor/src/components/collab-sidebar/comments.js index eb972a9b9d8ad8..7232f4878c8048 100644 --- a/packages/editor/src/components/collab-sidebar/comments.js +++ b/packages/editor/src/components/collab-sidebar/comments.js @@ -6,26 +6,31 @@ 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, __experimentalConfirmDialog as ConfirmDialog, Button, DropdownMenu, + TextareaControl, Tooltip, } from '@wordpress/components'; +import { + dateI18n, + format, + getSettings as getDateSettings, +} from '@wordpress/date'; import { Icon, check, published, moreVertical } from '@wordpress/icons'; import { __, _x } from '@wordpress/i18n'; -import { useSelect, dispatch } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; import { useEntityProp } from '@wordpress/core-data'; import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies */ -import CommentAuthorInfo from './comment-author-info'; -import CommentForm from './comment-form'; +import { sanitizeCommentString } from './utils'; /** * Renders the Comments component. @@ -36,7 +41,7 @@ import CommentForm from './comment-form'; * @param {Function} props.onAddReply - The function to add a reply to a comment. * @param {Function} props.onCommentDelete - The function to delete a comment. * @param {Function} props.onCommentResolve - The function to mark a comment as resolved. - * @return {React.ReactNode} The rendered Comments component. + * @return {JSX.Element} The rendered Comments component. */ export function Comments( { threads, @@ -67,19 +72,31 @@ export function Comments( { setIsConfirmDialogOpen( false ); }; - useSelect( ( select ) => { - const clientID = select( blockEditorStore ).getSelectedBlockClientId(); - const clientBlocks = select( blockEditorStore ).getBlocks(); - setBlocksList( clientBlocks ); + const { selectedClientBlocks, selectedActiveClientId } = useSelect( + ( select ) => { + const clientID = + select( blockEditorStore ).getSelectedBlockClientId(); + const selClientBlocks = select( blockEditorStore ).getBlocks(); + + const getBlockCommentId = + select( blockEditorStore ).getBlock( clientID )?.attributes + ?.blockCommentId ?? false; + + return { + selectedClientBlocks: selClientBlocks, + selectedActiveClientId: getBlockCommentId || null, + }; + }, + [] + ); - const getBlockCommentId = - select( blockEditorStore ).getBlock( clientID )?.attributes - ?.blockCommentId ?? false; + useEffect( () => { + setBlocksList( selectedClientBlocks ); - if ( getBlockCommentId ) { - setActiveClientId( getBlockCommentId ); + if ( selectedActiveClientId ) { + setActiveClientId( selectedActiveClientId ); } - }, [] ); + }, [ selectedClientBlocks, selectedActiveClientId ] ); const findBlockByCommentId = ( blocks, commentId ) => { for ( const block of blocks ) { @@ -99,12 +116,11 @@ export function Comments( { return null; }; + const { selectBlock } = useDispatch( blockEditorStore ); const handleThreadClick = ( thread ) => { const block = findBlockByCommentId( blocksList, thread.id ); if ( block ) { - const blockClientId = block.clientId; - // Select the block in the editor - dispatch( blockEditorStore ).selectBlock( blockClientId ); + selectBlock( block.clientId ); // Use the action to select the block } }; @@ -157,7 +173,6 @@ export function Comments( { } } onCancel={ () => setActionState( false ) } thread={ thread } - submitButtonText={ _x( 'Update', 'verb' ) } /> ) } { ( ! actionState || @@ -241,33 +256,14 @@ export function Comments( { onClick={ () => handleThreadClick( thread ) } > - { 0 < thread?.reply?.length && - thread.reply.map( ( reply ) => ( - - - - ) ) } { 'reply' === actionState?.action && thread.id === actionState?.id && ( - - - - setActionState( false ) } - submitButtonText={ _x( - 'Reply', - 'Add reply comment' - ) } /> - + ) } + { 0 < thread?.reply?.length && + thread.reply.map( ( reply ) => ( + + + + ) ) } ) ) } ); } +/** + * EditComment component. + * + * @param {Object} props - The component props. + * @param {Function} props.onSubmit - The function to call when updating the comment. + * @param {Function} props.onCancel - The function to call when canceling the comment update. + * @param {Object} props.thread - The comment thread object. + * @return {JSX.Element} The CommentForm component. + */ +function CommentForm( { onSubmit, onCancel, thread } ) { + const [ inputComment, setInputComment ] = useState( + thread?.content?.raw ?? '' + ); + + return ( + <> + + + + + + + + + ); +} + /** * Renders the header of a comment in the collaboration sidebar. * @@ -307,7 +358,7 @@ export function Comments( { * @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. + * @return {JSX.Element} The rendered comment header. */ function CommentHeader( { thread, @@ -317,6 +368,13 @@ function CommentHeader( { onReply, status, } ) { + const dateSettings = getDateSettings(); + const [ dateTimeFormat = dateSettings.formats.time ] = useEntityProp( + 'root', + 'site', + 'time_format' + ); + const actions = [ { title: _x( 'Edit', 'Edit comment' ), @@ -336,15 +394,29 @@ function CommentHeader( { return ( - + + + { thread.author_name } + + + { status !== 'approved' && ( - { 0 === thread?.parent && onResolve && ( + { 0 === thread.parent && onResolve && ( - - - - - ); -} - /** * Renders the header of a comment in the collaboration sidebar. * @@ -368,13 +280,6 @@ function CommentHeader( { onReply, status, } ) { - const dateSettings = getDateSettings(); - const [ dateTimeFormat = dateSettings.formats.time ] = useEntityProp( - 'root', - 'site', - 'time_format' - ); - const actions = [ { title: _x( 'Edit', 'Edit comment' ), @@ -394,29 +299,15 @@ function CommentHeader( { return ( - - - - { thread.author_name } - - - { status !== 'approved' && ( - { 0 === thread.parent && onResolve && ( + { 0 === thread?.parent && onResolve && (