-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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: Added new sidebar as extension of the canvas #67347
Changes from 5 commits
35c9f23
f1d7e1c
b1f0488
c60972c
06c49ba
d096211
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export const collabHistorySidebarName = 'edit-post/collab-history-sidebar'; | ||
export const collabSidebarName = 'edit-post/collab-sidebar'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,12 @@ | |
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { useSelect, useDispatch, resolveSelect } from '@wordpress/data'; | ||
import { | ||
useSelect, | ||
useDispatch, | ||
resolveSelect, | ||
subscribe, | ||
} from '@wordpress/data'; | ||
import { useState, useMemo } from '@wordpress/element'; | ||
import { comment as commentIcon } from '@wordpress/icons'; | ||
import { addFilter } from '@wordpress/hooks'; | ||
|
@@ -15,12 +20,14 @@ import { store as interfaceStore } from '@wordpress/interface'; | |
* Internal dependencies | ||
*/ | ||
import PluginSidebar from '../plugin-sidebar'; | ||
import { collabSidebarName } from './constants'; | ||
import { collabHistorySidebarName, collabSidebarName } from './constants'; | ||
import { Comments } from './comments'; | ||
import { AddComment } from './add-comment'; | ||
import { store as editorStore } from '../../store'; | ||
import AddCommentButton from './comment-button'; | ||
import AddCommentToolbarButton from './comment-button-toolbar'; | ||
import { getEditorCanvasBackgroundColor } from './utils'; | ||
import { useGlobalStylesContext } from '../global-styles-provider'; | ||
|
||
const isBlockCommentExperimentEnabled = | ||
window?.__experimentalEnableBlockComment; | ||
|
@@ -44,61 +51,28 @@ addFilter( | |
modifyBlockCommentAttributes | ||
); | ||
|
||
function CollabSidebarContent( { showCommentBoard, setShowCommentBoard } ) { | ||
function CollabSidebarContent( { | ||
showCommentBoard, | ||
setShowCommentBoard, | ||
styles, | ||
comments, | ||
} ) { | ||
const { createNotice } = useDispatch( noticesStore ); | ||
const { saveEntityRecord, deleteEntityRecord } = useDispatch( coreStore ); | ||
const { getEntityRecord } = resolveSelect( coreStore ); | ||
|
||
const { postId, threads } = useSelect( ( select ) => { | ||
const { postId } = useSelect( ( select ) => { | ||
const { getCurrentPostId } = select( editorStore ); | ||
const _postId = getCurrentPostId(); | ||
const data = !! _postId | ||
? select( coreStore ).getEntityRecords( 'root', 'comment', { | ||
post: _postId, | ||
type: 'block_comment', | ||
status: 'any', | ||
per_page: 100, | ||
} ) | ||
: null; | ||
|
||
return { | ||
postId: _postId, | ||
threads: data, | ||
}; | ||
}, [] ); | ||
|
||
const { getSelectedBlockClientId } = useSelect( blockEditorStore ); | ||
const { updateBlockAttributes } = useDispatch( blockEditorStore ); | ||
|
||
// Process comments to build the tree structure | ||
const resultComments = useMemo( () => { | ||
// Create a compare to store the references to all objects by id | ||
const compare = {}; | ||
const result = []; | ||
|
||
const filteredComments = ( threads ?? [] ).filter( | ||
( comment ) => comment.status !== 'trash' | ||
); | ||
|
||
// Initialize each object with an empty `reply` array | ||
filteredComments.forEach( ( item ) => { | ||
compare[ item.id ] = { ...item, reply: [] }; | ||
} ); | ||
|
||
// Iterate over the data to build the tree structure | ||
filteredComments.forEach( ( item ) => { | ||
if ( item.parent === 0 ) { | ||
// If parent is 0, it's a root item, push it to the result array | ||
result.push( compare[ item.id ] ); | ||
} else if ( compare[ item.parent ] ) { | ||
// Otherwise, find its parent and push it to the parent's `reply` array | ||
compare[ item.parent ].reply.push( compare[ item.id ] ); | ||
} | ||
} ); | ||
|
||
return result; | ||
}, [ threads ] ); | ||
|
||
// Function to save the comment. | ||
const addNewComment = async ( comment, parentCommentId ) => { | ||
const args = { | ||
|
@@ -222,14 +196,14 @@ function CollabSidebarContent( { showCommentBoard, setShowCommentBoard } ) { | |
}; | ||
|
||
return ( | ||
<div className="editor-collab-sidebar-panel"> | ||
<div className="editor-collab-sidebar-panel" style={ styles }> | ||
<AddComment | ||
onSubmit={ addNewComment } | ||
showCommentBoard={ showCommentBoard } | ||
setShowCommentBoard={ setShowCommentBoard } | ||
/> | ||
<Comments | ||
threads={ resultComments } | ||
threads={ comments } | ||
onEditComment={ onEditComment } | ||
onAddReply={ addNewComment } | ||
onCommentDelete={ onCommentDelete } | ||
|
@@ -245,6 +219,7 @@ function CollabSidebarContent( { showCommentBoard, setShowCommentBoard } ) { | |
export default function CollabSidebar() { | ||
const [ showCommentBoard, setShowCommentBoard ] = useState( false ); | ||
const { enableComplementaryArea } = useDispatch( interfaceStore ); | ||
const { getActiveComplementaryArea } = useSelect( interfaceStore ); | ||
|
||
const { postStatus } = useSelect( ( select ) => { | ||
return { | ||
|
@@ -270,6 +245,68 @@ export default function CollabSidebar() { | |
enableComplementaryArea( 'core', 'edit-post/collab-sidebar' ); | ||
}; | ||
|
||
const { threads } = useSelect( ( select ) => { | ||
const { getCurrentPostId } = select( editorStore ); | ||
const _postId = getCurrentPostId(); | ||
const data = !! _postId | ||
? select( coreStore ).getEntityRecords( 'root', 'comment', { | ||
post: _postId, | ||
type: 'block_comment', | ||
status: 'any', | ||
per_page: 100, | ||
} ) | ||
: null; | ||
|
||
return { | ||
postId: _postId, | ||
threads: data, | ||
}; | ||
}, [] ); | ||
|
||
// Process comments to build the tree structure | ||
const resultComments = useMemo( () => { | ||
// Create a compare to store the references to all objects by id | ||
const compare = {}; | ||
const result = []; | ||
|
||
const filteredComments = ( threads ?? [] ).filter( | ||
( comment ) => comment.status !== 'trash' | ||
); | ||
|
||
// Initialize each object with an empty `reply` array | ||
filteredComments.forEach( ( item ) => { | ||
compare[ item.id ] = { ...item, reply: [] }; | ||
} ); | ||
|
||
// Iterate over the data to build the tree structure | ||
filteredComments.forEach( ( item ) => { | ||
if ( item.parent === 0 ) { | ||
// If parent is 0, it's a root item, push it to the result array | ||
result.push( compare[ item.id ] ); | ||
} else if ( compare[ item.parent ] ) { | ||
// Otherwise, find its parent and push it to the parent's `reply` array | ||
compare[ item.parent ].reply.push( compare[ item.id ] ); | ||
} | ||
} ); | ||
|
||
return result; | ||
}, [ threads ] ); | ||
|
||
// Get the global styles to set the background color of the sidebar. | ||
const { merged: GlobalStyles } = useGlobalStylesContext(); | ||
const backgroundColor = GlobalStyles?.styles?.color?.background; | ||
|
||
if ( 0 < resultComments.length ) { | ||
const unsubscribe = subscribe( () => { | ||
const activeSidebar = getActiveComplementaryArea( 'core' ); | ||
|
||
if ( ! activeSidebar ) { | ||
enableComplementaryArea( 'core', 'edit-post/collab-sidebar' ); | ||
unsubscribe(); | ||
} | ||
} ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could probably create an option for |
||
} | ||
|
||
// Check if the experimental flag is enabled. | ||
if ( ! isBlockCommentExperimentEnabled || postStatus === 'publish' ) { | ||
return null; // or maybe return some message indicating no threads are available. | ||
|
@@ -283,14 +320,32 @@ export default function CollabSidebar() { | |
<> | ||
<AddCommentComponent onClick={ openCollabBoard } /> | ||
<PluginSidebar | ||
identifier={ collabSidebarName } | ||
identifier={ collabHistorySidebarName } | ||
// translators: Comments sidebar title | ||
title={ __( 'Comments' ) } | ||
icon={ commentIcon } | ||
> | ||
<CollabSidebarContent | ||
comments={ resultComments } | ||
showCommentBoard={ showCommentBoard } | ||
setShowCommentBoard={ setShowCommentBoard } | ||
/> | ||
</PluginSidebar> | ||
<PluginSidebar | ||
isPinnable={ false } | ||
header={ false } | ||
identifier={ collabSidebarName } | ||
className="editor-collab-sidebar" | ||
headerClassName="editor-collab-sidebar__header" | ||
> | ||
<CollabSidebarContent | ||
comments={ resultComments } | ||
showCommentBoard={ showCommentBoard } | ||
setShowCommentBoard={ setShowCommentBoard } | ||
styles={ { | ||
backgroundColor: | ||
backgroundColor ?? getEditorCanvasBackgroundColor(), | ||
} } | ||
/> | ||
</PluginSidebar> | ||
</> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,21 @@ | |
export function sanitizeCommentString( str ) { | ||
return str.trim(); | ||
} | ||
|
||
/** | ||
* Gets the background color of the editor canvas. | ||
* | ||
* @return { string } Background color of the editor canvas. | ||
*/ | ||
export function getEditorCanvasBackgroundColor() { | ||
const iframe = document.querySelector( 'iframe[name="editor-canvas"]' ); | ||
const iframeDocument = | ||
iframe?.contentDocument || iframe?.contentWindow.document; | ||
const iframeBody = iframeDocument?.body; | ||
if ( iframeBody ) { | ||
const style = window.getComputedStyle( iframeBody ); | ||
return style?.backgroundColor; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if we can just get the colour from global styles, but I guess this is fine for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve updated the implementation to pull the color directly from the global styles., and also kept this function for fallback background color. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove it for now, and reduce complexity. There's also cases where the editor doesn't have an iframe, so this code is too fragile atm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, I'll remove the fallback function for now. However, we might still encounter cases where global styles aren't supported, should we consider that later? |
||
} | ||
|
||
return ''; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to an effect? We shouldn't subscribe on render.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useEffect
won't work in this case, as the component doesn't re-render when another sidebar is toggled from outside the editor.