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

Phase 3: Explore inline block commenting #59445

Open
annezazu opened this issue Feb 28, 2024 · 15 comments
Open

Phase 3: Explore inline block commenting #59445

annezazu opened this issue Feb 28, 2024 · 15 comments
Labels
Collaborative Workflows Phase 3 of the Gutenberg roadmap around all-things related to collaborative workflows [Type] Enhancement A suggestion for improvement. [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues

Comments

@annezazu
Copy link
Contributor

annezazu commented Feb 28, 2024

While a discussion broke out years ago around a commenting API, this issue seeks to be a gathering place on what in line commenting could look like today as phase 3 has previously been more firmly announced and early explorations begin. In particular, this area of work is listed as a task for real time collaboration and this issue can act as a gathering place for coordinating what's needed. To pull from this workflows post:

Introduce inline comments on blocks within the editor experience. Explore using comment types to store them. Allow marking comments as resolved. Status of comments also need to fold within individual revisions, so that it’s easy to see what specific edit state a comment refers to. Possible connection with “pending review” functionality.

collaboration-comments

Mockups

Some initial work is underway in #60622, where the following mockups were pulled from.

Adding comments:

Comments i2, adding

"Add comment" is present in the block toolbar's "More" menu, in the first group.

Separately, this menu can itself benefit from migrating to DropdownMenuV2 so it can have flyouts, that might offer a better hierarchy.

Indicators:

Comments i2, indicators, with overlays

In this example, comments have been added to a post. That makes the sidebar button appear. Implicitly that means, the comments button only appears if a post has comments.

Shown also, one of the blocks selected, with indication in the block toolbar: a stack of avatars of who interacted with this particular block. This particular design is similar to past concept art for collaborative editing, which imagines a similar stack of avatars with colored rings, in the top toolbar.

The block-highlight is block-level, to start, and shows the full block except for text blocks, where the full text is highlighted even if in inline style. An alternative is a block-level highlight treatment for all blocks:

Comments i2, sidebar, alternate overlay style

This might get too close to block level multi-select, though, so the particular visual for highlighting blocks we can refine, it can also be borders and/or underlines.

Sidebar:

Comments i2, sidebar

The sidebar has a partially-inline visual style, but it's mainly a matter of applying the site background-color as background to the sidebar panel.

Figma.


Issue updated Aug 29.

@annezazu annezazu added [Type] Enhancement A suggestion for improvement. [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration labels Feb 28, 2024
@poojabhimani12
Copy link
Contributor

poojabhimani12 commented Mar 7, 2024

Hey Annezazu,

We're excited to share that we've developed this feature and equally thrilled to contribute it to the WordPress core. You can check out the codebase on our GitHub repository here.

Key Features:

  • Seamless integration with all Gutenberg core blocks.
  • Comment on entire blocks or select specific text within a block.
  • Manage comment status: publish, delete, and resolve for each thread.
  • An activity panel provides a comprehensive view of all comments and their activities.
  • Custom meta handling for comment threads is stored in the Post Meta table.
  • Revision support: All comments are stored in post content via custom attributes for accurate restoration.
  • You can check compatibility for all blocks here.

Feel free to explore the GitHub repository for a closer look at the functionalities, and don't hesitate to reach out if you have any questions or feedback.

Let's make WordPress collaboration better than ever! 🌐✨

@annezazu
Copy link
Contributor Author

This is very exciting to see! Big thank you to your crew for being open to contributing your work to Core. It's part of what I hope to see more of with Phase 3.

To move forward, are you all able to split your work into chunks to merge items in a multi-step process? Reviewing the whole repo in one go will be a huge task and smaller items makes it easier to get a sense of the whole. Since you all are experts in your own code and how it's architectured, it would help to have you all lead splitting and integrating it. In terms of general next steps, I had a quick chat with @youknowriad who suggested the following:

  1. Introduce the experimental flag for this feature. Here's an example of a recent PR that does this for a different feature: Add Grid interactivity #59052
  2. Introduce the low level database structure/whatever custom post types needed. We can then ping some Core PHP folks to review.
  3. Introduce the REST endpoint. We can again ensure reviews here.
  4. Update the block editor package to support comments.

In some cases, for similar work, folks will create a big POC (proof of concept) PR that's initially opened to serve as an overall guide to the smaller steps. Here's an example: #53455 (comment) You're welcome to do that too to orient the work.

Let me know what questions or guidance is needed so we can collaborate well <3

@poojabhimani12
Copy link
Contributor

Here is the Introduction to database structure.

Comments and related activities are stored within the wp_postmeta, whereas all plugin settings and miscellaneous data reside in the wp_options. Our plugin does not utilize any custom tables.

Comment Meta Data Structure:
When someone comments on a post, we've implemented a sophisticated system for storing comment data using post meta.

  • When a user comments on a post, metadata is added with a serialized value.
  • Meta Key: _el1710843345082 (prefixed with _el followed by timestamp)
  • Meta Value: Serialized array containing comment data, including user data (ID), comment thread content, an assigned user (if any), comment status, commented-on text (block or content), and timestamps.
  • If a comment is resolved, additional data is stored, including the resolved status, resolved timestamp, and the user ID of the person who resolved the comment.
  • Any edits, deletions, or comments resolved trigger post metadata updates.

Autodraft Comments:

Comments left blank or as autosaves are stored in _autodraft_ids on the post meta.

We add our custom meta key to the WordPress "wp_postmeta" table.

Also I am adding here visual presentation
Db structure

Introduce the REST endpoint
We've enhanced our REST API endpoints to retrieve data directly from the Post Meta Table.
/cf-get-comments: Retrieves comments via REST API.[check here]
/cf-get-comments-key: Retrieves comment keys via REST API.[check here]
/cf-activities: Retrieves all comments thread [check here]

@annezazu annezazu changed the title [Phase 3] Explore inline block commenting Phase 3: Explore inline block commenting Mar 22, 2024
@jasmussen jasmussen moved this to Later in Design priorities Apr 12, 2024
@jasmussen
Copy link
Contributor

Hello @poojabhimani12, thank you for contributing 🙏

I took a quick review at the various pieces to see how we can best proceed. Keep in mind I'm mainly a design/user experience contributor to the project, and the following should be seen as a first impression.

Experimental flag PR

The PR, as noted, adds an experimental flag for the feature, and adds a button to the block toolbar.

commenting

I later reviewed the plugin using the demo that's graciously provided. Quick GIF showing adding inline, block level comments, interacting with existing comments, editing comments, and more:

multicollab-commenting

There are quite a lot of impressive features. Enough that it can also be a bit overwhelming to take in at first, the demo site is no doubt created to show the breadth of features rather than necessarily a typical example of what you might see. But for that reason, I'll rewind a bit, and start with the basics, simply adding a comment.

Adding comments

There are a few ways to do it. Medium has an on-select inline toolbar to surface comment buttons:

medium

Google Docs, perhaps best known for collaboration features, shows an on-select toolbar on the right:

docs

MultiCollab supports both models:

  • You can add comments on the block level. Select a block, click the button in the block toolbar. This is denoted by a colored rectangle around the block.
  • You can add inline comments. Select any bit of text, press the same block toolbar button.
  • There's an additional Google Docs-like toolbar that appears on select, allowing inline comments.

It's also very feature complete:

  • Theres' a sidebar inspector panel for resolving/commenting.
  • You can also resolve/comment on the bubbles that sit on the right, inside the canvas.
  • There's a share button to collaborate.
  • There's suggesting, deleting, commenting, marking resolved, adding attachments, editing comments, deleting comments, etc.

It's certainly an impressive featureset, replicating most of what people appreciate about Google Docs.

This also means that there's quite a big surface area for UI that would need to be added and reviewed. As part of that, some details would likely need addressing in order to be compatible with existing UI, meet accessibility criteria, such as using WordPress core components, WordPress icons, leveraging the design system and theme colors, border radii, shadows, borders, etc.

Absorbing the featureset wholesale is likely not going to be feasible, given how much overlap the plugin has with phase 3 features.

gutenberg-phase-3

The overlap almost certainly comes with a great deal of experience from building everything from multi user editing to share buttons. Because of that, each of those pieces are probably best added separately.

To aid that, the best path forward may be to extract the smallest possible feature-set, polish that to core standards for componentry, design, and accessibility, then ship that. And if it works well, outline a road map of subsquent features and how they might fit in with existing phase 3 collaboration issues.

One outline for how to start could be:

  • Start with just comments.
    No comment threads, no suggesting, no accepting changes, perhaps just the ability to dismiss a comment.
  • Start with allowing comments only at the block level.
    No inline selection quite yet.
  • Start with the "Add comment" action as an item in the block options dropdown, not a button in the block toolbar. It can still have the same shortcut.

We'd most likely want on-select commenting options, and simpler ways to comment. But by starting simple, the structure of the logistics of bringing this to the block editor could be hashed out, what needs rewriting vs. what can be reused would become clearer, and there would be fewer details to get right in order to ship each PR.

Let me know if this makes sense, and thank you again for contributing!

@priethor priethor mentioned this issue Apr 26, 2024
11 tasks
@smithjw1
Copy link

I'm excited to work with @ingeniumed and @alecgeatches on moving this work forward. We all work at WordPress VIP.

Broadly, there are two different areas to consider: UI and data.

@jasmussen offered tons of helpful UI feedback and some clear actions. There are big data questions, but I wonder if we could move the UI forward today. Could there be an experiment where comments aren't persisted in the database? Would that help integrate the UI and refine it to match WordPress standards?

I think it may be helpful to explore this option.

Turning toward data, I think the biggest question this raises is how we associate the comment with the block. The plugin does this currently, but there has been some conversation about a unique block ID. That would be a significant structural change with implications beyond just this issue.

There is also room for conversation about storing the comments as WordPress comments vs. post meta. Or even inline as part of block attributes.

The best next step is to gather further details on the "why" behind the current data structure. Did you experiment with it? Where have you seen issues? What implications would every WordPress blog worldwide have if it implemented this? If you could return to the beginning, would you do it another way?

Once we have a strong case for the current (or a modified) structure, we can ask the community for feedback.

If we can move forward on both paths, I think we can deliver the finished feature more quickly.

@ellatrix
Copy link
Member

I'm mostly curious how the comments will link to the content.

  • For block-level comments, do you assign an ID to the block as an attribute? Maybe we should persist block client IDs?
  • For inline comments, will you store spans (with a generated ID) in the content? If so, how can we make sure we don't reveal too much information in case it leaks? (No comments would be leaked, but location might leak.)

@poojabhimani12
Copy link
Contributor

As an experimental approach for block-level comments, we are currently implementing a method where comments are saved by incorporating a new attribute called blockComments to the blocks. This allows us to manage the comments using the blocks' clientId, ensuring that each comment is associated with its respective block via the clientId.

Regarding inline comments, we are storing the generated ID within spans. When we store this information...

While this approach is still experimental, I am inclined towards saving comments in the post meta table to prevent information leaks, as you mentioned. With block comments already stored in the post meta, extending functionality to support inline comments becomes more straightforward.

@ellatrix
Copy link
Member

Sure, it's just that information about what is commented on can still be leaked, which is a tradeoff we may be ok with, I just wanted to highlight it. I don't really see any other robust way to achieve it tbh.

This allows us to manage the comments using the blocks' clientId, ensuring that each comment is associated with its respective block via the clientId.

I'm not sure I understand this part. Are you "generating" a new ID by storing the client ID at the time of commenting?

@poojabhimani12
Copy link
Contributor

No, we are not. In the context of the WordPress block editor, each block has a unique clientId, which can be used to identify and manage block-specific data.

In this PR, we are using the clientId to save and fetch comments from the block's attributes. However, with the post meta approach (storing comments as post meta), we might not use the clientId and instead generate our own unique IDs to store comments.

@priethor priethor added Collaborative Workflows Phase 3 of the Gutenberg roadmap around all-things related to collaborative workflows and removed [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration labels May 28, 2024
@mtias
Copy link
Member

mtias commented Jun 7, 2024

Cool to see the work here!

Expanding on what @smithjw1 mentions, I'd be very curious to see an exploration that introduces these as a new private comment_type instead of using post meta and what the tradeoffs might be. Also my inclination would be to not force blocks to have an ID, which is really cumbersome to track, but to reference the comment ID as a block attribute instead.

@gziolo
Copy link
Member

gziolo commented Jun 13, 2024

Also my inclination would be to not force blocks to have an ID, which is really cumbersome to track, but to reference the comment ID as a block attribute instead.

That concept of blocks was explored also for Pattern Overrides with the existing metadata attribute. metadata.id existed in the development version for some time and was created only when needed. It eventually was replaced by metadata.name better suited for that use case. I read it as the comment id that starts the thread would get stored as metadata which seems like a very reasonable design decision as it makes it trivial to load the related comments, or remove comments when deleting the block.

@poojabhimani12
Copy link
Contributor

The PR has been updated with the proposed data model and is now ready for review and merging as an experiment.

@poojabhimani12
Copy link
Contributor

Cool to see the work here!

Expanding on what @smithjw1 mentions, I'd be very curious to see an exploration that introduces these as a new private comment_type instead of using post meta and what the tradeoffs might be. Also my inclination would be to not force blocks to have an ID, which is really cumbersome to track, but to reference the comment ID as a block attribute instead.

While working on adding comments through a custom comment type, we have encountered a few queries and would appreciate your insights:

Adding Custom Comment Type:

  • While utilizing the Comments REST API, we did not find any arguments that allow the insertion of custom data into the comment_type column.
  • To address this, we have used the Comments REST API. Here is a screenshot of the code snippet: Code Snippet Screenshot.
  • Alternatively, we considered using the PHP wp_insert_comment function, which does provide an argument to pass a custom comment_type.

Adding Comments on Draft Pages:
We found that comments can only be added if the post is published; otherwise, the Comments REST API returns an error. Here is the error message: Error Message Screenshot.

Our Suggestions:

  • For the custom comment type issue, we suggest extending the REST API endpoints by creating a custom endpoint that allows specifying the comment_type. This could involve developing a custom REST route in PHP that accepts additional parameters and processes them accordingly.
  • For adding comments to draft pages, one approach could be to save comments as a custom post type or post meta until the post is published. Once the post is published, these comments can be transferred to the standard comments table. This would ensure that the comments are not lost and can be associated with the draft until it is published.

@jasmussen
Copy link
Contributor

I've updated this issue with mockups.

@annezazu annezazu added the [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues label Oct 24, 2024
@spacedmonkey
Copy link
Member

As this new comment type, this will require lots of query to the comment database with that queried by the comment type. However, querying but comment type has some performance issues, as this type does not have an index.

There is a core ticket #59488, if this feature is to make it into core, then I believe this index is required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Collaborative Workflows Phase 3 of the Gutenberg roadmap around all-things related to collaborative workflows [Type] Enhancement A suggestion for improvement. [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues
Projects
Status: Later
Development

No branches or pull requests

9 participants