Skip to content

feat: custom byline interface#3746

Merged
leogermani merged 53 commits into
trunkfrom
feat/byline-interface
Mar 28, 2025
Merged

feat: custom byline interface#3746
leogermani merged 53 commits into
trunkfrom
feat/byline-interface

Conversation

@allysonsouza

@allysonsouza allysonsouza commented Feb 12, 2025

Copy link
Copy Markdown
Contributor

All Submissions:

Changes proposed in this Pull Request:

This Pull Request implements the feature to allow the selection of author tokens from authors selected on Co-Authors Plus to compound a custom byline with them.

How to test the changes in this Pull Request:

  1. Go to a post edit page and assign authors to the post on co-authors plus panel
  2. Below it, you will see the Newspack Custom Byline panel. Set the toggle to active to enable custom byline.
  3. You will see the custom byline field, which is a div with contenteditable. Below it you should see the authors assigned to the post as buttons that will insert the tokens on the content when clicked.
  4. Click on buttons to add the token to the content
  5. Click on buttons inside the byline content to remove token
  6. Also, the tokens should be removed when editions are made to then with delete/backspace for example
  7. Save the post, reload the page and see if the custom byline saved is what is expected
  8. Check if the custom byline is editable as expected too after saving it

Things to check:

  • The authors set on Co-Authors Plus are being displayed as tokens to be used on Custom Byline?
  • When I click on token "+", the author token is inserted at the end of the byline?
  • Does the token get removed after a change on it's content is made (by using delete, backspace or by adding additional characters)?
  • Does the token get removed when I click on "x" on it after inserted into the byline?
  • Does additional space after the token is inserted to allow more text to be typed after it?
  • Does the byline get save properly?
  • After saving, does the available tokens (the ones that aren't in use) are correctly displayed below the byline field?

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@allysonsouza allysonsouza self-assigned this Feb 12, 2025
@allysonsouza allysonsouza changed the title Feat: custom byline interfce feat: custom byline interfce Feb 12, 2025
@allysonsouza allysonsouza added the [Status] Needs Review The issue or pull request needs to be reviewed label Feb 13, 2025
@allysonsouza allysonsouza marked this pull request as ready for review February 13, 2025 18:44
@allysonsouza allysonsouza requested a review from a team as a code owner February 13, 2025 18:44

@claudiulodro claudiulodro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall I think this is coming together! The UX of it feels good. I noticed a few quirks in my testing:

  1. In general it's kind of hard to read once there are a few authors in there:
Screenshot 2025-02-13 at 1 29 49 PM

Not sure if we should reduce the size of the author boxes or how best to handle that. What do you think, @thomasguillot?

  1. Using the arrow keys, you can go into one of the boxes and then type to modify the content. I think it should not be editable.
Screenshot 2025-02-13 at 1 31 01 PM
  1. If you select a portion of the text that includes a box and delete, the box doesn't go back into the available authors section:
Screenshot 2025-02-13 at 1 33 24 PM Screenshot 2025-02-13 at 1 33 34 PM
  1. Authors are always inserted at the end of the text box. I think the best experience would be for them to be inserted at the cursor position, otherwise it's tricky to edit existing bylines to add/change authors around.

@leogermani

Copy link
Copy Markdown
Contributor

This is starting to look pretty good!

Here are two things I noticed:

  • This feature should also work without CoAuthors Plus. In that case, it would list only the normal post author
  • The input should be pre-filled with the default by byline
  • The value stored in the post meta field should follow what's described here

The idea of storing the ID and the name is to have a fallback in case the user is deleted. When we render the byline, we'll always read the ID and get the Display name from the database, but if the ID is gone, we'll use the name that is stored there.

@leogermani

Copy link
Copy Markdown
Contributor

Ah, and before you get crazy and go deep in a rabbit role, we DON'T NEED TO SUPPORT Guest Authors

@claudiulodro claudiulodro added [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator and removed [Status] Needs Review The issue or pull request needs to be reviewed labels Feb 13, 2025
@thomasguillot

Copy link
Copy Markdown
Contributor

Overall I think this is coming together! The UX of it feels good. I noticed a few quirks in my testing:

  1. In general it's kind of hard to read once there are a few authors in there:
Screenshot 2025-02-13 at 1 29 49 PM Not sure if we should reduce the size of the author boxes or how best to handle that. What do you think, @thomasguillot?

You're right, this doesn't look good. Let me think about a different approach here.

@thomasguillot

Copy link
Copy Markdown
Contributor

Note: The panel should simply be named "Byline", not "Newspack Custom Byline"

@thomasguillot

Copy link
Copy Markdown
Contributor

Can we please make sure the style matches Core's FormTokenField

Also we can use @wordpress/base-styles/colors rather than hardcoding the values.

@miguelpeixe

Copy link
Copy Markdown
Member

I've just tested on a fresh post and I still have issues with the backspace interaction:

custom-byline.mov

Another problem I faced while drafting the new post was that the additional authors only became available after I saved and refreshed the post. Ideally, the component would be aware of the edited changes and update the component's available tokens.

@allysonsouza

Copy link
Copy Markdown
Contributor Author

The latest commit fixes the backspace interaction, @miguelpeixe. About authors, it was expected that for the first version that would be acceptable (to have to refresh the page to make them available to use on byline), can you confirm that, @claudiulodro?

@allysonsouza allysonsouza changed the title feat: custom byline interfce feat: custom byline interface Feb 25, 2025
@miguelpeixe

Copy link
Copy Markdown
Member

Thanks for the revisions @allysonsouza!

Backspace interaction is working well for deleting the token when the cursor is at the end of it. I'm facing a couple of issues still:

  • The cursor repositions to the beginning after deleting a token
  • Removing (via delete or backspace) multiple selected text doesn't restore the token
bylines.mov

Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/index.js
Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/index.js Outdated
Comment thread src/bylines/style.scss Outdated
Comment thread src/bylines/index.js
@allysonsouza

Copy link
Copy Markdown
Contributor Author

After struggling to handle the state of the content, which was not being managed by React state, @goldenapples started working on a simplification to use onInput instead of MutationObserver, which lead to a simpler and shorter code.

He's proposing it on this PR on our fork, I've been testing it and it seems like we need to deal with the removal of the tokens itself when there's a change to the token content (like adding characters or removing them with backspace or delete).

That seems possible to be handled by onInput too, by adding an onInput on each token to remove itself when changes happen and to keep the onInput on the wrapper contenteditable div.

@goldenapples goldenapples force-pushed the feat/byline-interface branch from b49dbc5 to 0867dfa Compare March 25, 2025 12:22
@leogermani

Copy link
Copy Markdown
Contributor

Heads up that I've implemented the data structure changes that this PR does in trunk to allow us to move on with some tests. This might create conflicts that should be easily resolved - just ignore the changes on trunk

#3863

@joeleenk joeleenk added [Status] Needs Review The issue or pull request needs to be reviewed and removed [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator labels Mar 28, 2025

@miguelpeixe miguelpeixe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for all the revisions, the code is well organized and very readable!

I ran into a couple of issues, but I'm not considering them blockers because we can address them separately:

  1. When backspacing a token, my cursor gets reset to position zero
  2. Making changes to the post authors does not update the available tokens. This is also the case after saving the changes. Only after a page refresh I'm able to use the new authors. This only happens when using Co-Authors Plus.

Other than that, I'm able to make changes to the byline and save with different token/text variations without issues.

@leogermani leogermani dismissed claudiulodro’s stale review March 28, 2025 21:00

changes addressed

@leogermani leogermani merged commit 289f55e into trunk Mar 28, 2025
@leogermani leogermani deleted the feat/byline-interface branch March 28, 2025 21:01
@github-actions

Copy link
Copy Markdown

Hey @allysonsouza, good job getting this PR merged! 🎉

Now, the needs-changelog label has been added to it.

Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label.

If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label.

Thank you! ❤️

@matticbot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 6.3.0-hotfix-just-to-test-ci-changes.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

miguelpeixe added a commit that referenced this pull request Apr 4, 2025
* fix: path to autoload (#3808)

* fix(ia): render all emails on reset (#3867)

This fixes an issue where resetting an email template in Newspack > Settings > Emails would only render Woo templates on success.

* refactor(corrections): remove feature flag (#3866)

* feat: custom byline interface (#3746)

* feat: modify textarea to RichText and add TagInlineBlock with dummy authors

* feat: fetch authors from co-authors plus and set tokens on BylinesSettingsPanel

* chore: improve inline documentation

* feat: [WIP] add author tokens on click

* feat: append users to the end of the byline

* feat: add author tokens to custom byline

* feat: handling tokens with vanilla JS (WIP)

* feat: useRef to manage tokens in use

* chore: improve inline docs

* feat: check custom byline after DOM ready

* chore: addEventListener trough ref instead of DOM directly

Also adds the return of a function on useEffect to allow React cleanup on unmount

* feat: display icons on tokens (plus to insert and close to remove)

* feat: add mutation observer to remove tokens on erasing with backspace/delete

* chore: enhance inline documentation

* fix: stylize tokens according to FormTokenField

* fix: remove token when characterData changes

* fix: improved mutation observer callback logic to update data correctly

* fix: initilize only on DOM ready and main byline element ready

* fix: properly add the mutation observer after child component is ready

* fix: implement setTokensInUse function to better reuse code

* fix: split byline "textarea" and tokens to avoid unwanted re-rendering

* feat: parse meta with <Author> before rendering byline

* feat: store byline meta according to the expected format

* chore: refacot bylineParser function

* feat: make custom bylines to work without co-author plus activated

* feat: make custom byline field to be displayed on a modal

* fix: mystype newspackByline.is_co_authors_plus_active

* fix: adding space after token insertion at the end of byline

* fix: improve byline innerHTML assignment

* fix: typo isTokensdReady

* docs: update docs

* fix: remove non used authors query

* fix: cubic-bezier transition typo

* fix: remove updateBylineMeta from click on x/removal callback event

* fix: remove unnecessary "backwards" compatibility since it's new feature

* refactor: replace MutationObserver with event listeners

Replaced the MutationObserver with an event listener, replaced some of
the DOM interaction with a useRef element, and tried to refactor some of
the data getters and setters.

* fix: update effect registration so it only runs on mounting

* refactor: remove unneded "remove token" handler

* fix: look up the byline meta on mount, not just on initial render

* fix: set contenteditable="false" on token spans

Prevents editing the content in these spans, and makes it so that
deleting (with backspace) will remove the whole span at once rather than
editing within the span.

* chore: add some missing docblocks and fix some lint issues

* fix: set default insert location to end of editable field

Updates the "cursorPos" variable logic to use the end of the line if
there's no cursor position set yet, and to add a non-breaking space at
the end of the text if necessary. Also updates the white-space styling
of the editable area, to ensure that users can select any point in the
text they may need to.

* fix: remove margin from last token to prevent confusion with whitespace

* feat: add preview to sidebar interface

* fix: rename panel to Byline

* fix: make modal width fixed

* feat: add function to parse meta for preview

* feat: default custom byline on first toggle

* feat: set default custom byline meta on toggle

* feat: update styles to match new designs

* feat: update styles to match designs

* chore: cleanup, comments, organization

---------

Co-authored-by: Leo Germani <leogermani@automattic.com>
Co-authored-by: goldenapples <goldenapplesdesign@gmail.com>
Co-authored-by: Joeleen Kennedy <joeleen@humanmade.com>

* feat: frontend display of bylines (#3856)

* feat: modify textarea to RichText and add TagInlineBlock with dummy authors

* feat: fetch authors from co-authors plus and set tokens on BylinesSettingsPanel

* chore: improve inline documentation

* feat: [WIP] add author tokens on click

* feat: append users to the end of the byline

* feat: add author tokens to custom byline

* feat: handling tokens with vanilla JS (WIP)

* feat: useRef to manage tokens in use

* chore: improve inline docs

* feat: check custom byline after DOM ready

* chore: addEventListener trough ref instead of DOM directly

Also adds the return of a function on useEffect to allow React cleanup on unmount

* feat: display icons on tokens (plus to insert and close to remove)

* feat: add mutation observer to remove tokens on erasing with backspace/delete

* chore: enhance inline documentation

* fix: stylize tokens according to FormTokenField

* fix: remove token when characterData changes

* fix: improved mutation observer callback logic to update data correctly

* fix: initilize only on DOM ready and main byline element ready

* fix: properly add the mutation observer after child component is ready

* fix: implement setTokensInUse function to better reuse code

* fix: split byline "textarea" and tokens to avoid unwanted re-rendering

* feat: parse meta with <Author> before rendering byline

* feat: store byline meta according to the expected format

* chore: refacot bylineParser function

* feat: make custom bylines to work without co-author plus activated

* feat: make custom byline field to be displayed on a modal

* fix: mystype newspackByline.is_co_authors_plus_active

* fix: adding space after token insertion at the end of byline

* fix: improve byline innerHTML assignment

* docs: update docs

* fix: typo isTokensdReady

* fix: remove non used authors query

* fix: cubic-bezier transition typo

* fix: remove updateBylineMeta from click on x/removal callback event

* fix: remove unnecessary "backwards" compatibility since it's new feature

* feat: add byline output to pre_newspack_posted_by hook

* Tried to simplify some things

Replaced the MutationObserver with an event listener, replaced some of
the DOM interaction with a useRef element, and tried to refactor some of
the data getters and setters.

* Update effects on mounting

* Remove unneded remove handler.

* Look up the byline on mount, not just on initial render.

* feat: modify textarea to RichText and add TagInlineBlock with dummy authors

* feat: fetch authors from co-authors plus and set tokens on BylinesSettingsPanel

* chore: improve inline documentation

* feat: [WIP] add author tokens on click

* feat: append users to the end of the byline

* feat: add author tokens to custom byline

* feat: handling tokens with vanilla JS (WIP)

* feat: useRef to manage tokens in use

* chore: improve inline docs

* feat: check custom byline after DOM ready

* chore: addEventListener trough ref instead of DOM directly

Also adds the return of a function on useEffect to allow React cleanup on unmount

* feat: display icons on tokens (plus to insert and close to remove)

* feat: add mutation observer to remove tokens on erasing with backspace/delete

* chore: enhance inline documentation

* fix: stylize tokens according to FormTokenField

* fix: remove token when characterData changes

* fix: improved mutation observer callback logic to update data correctly

* fix: initilize only on DOM ready and main byline element ready

* fix: properly add the mutation observer after child component is ready

* fix: implement setTokensInUse function to better reuse code

* fix: split byline "textarea" and tokens to avoid unwanted re-rendering

* feat: parse meta with <Author> before rendering byline

* feat: store byline meta according to the expected format

* chore: refacot bylineParser function

* feat: make custom bylines to work without co-author plus activated

* feat: make custom byline field to be displayed on a modal

* fix: mystype newspackByline.is_co_authors_plus_active

* fix: adding space after token insertion at the end of byline

* fix: improve byline innerHTML assignment

* fix: typo isTokensdReady

* docs: update docs

* fix: remove non used authors query

* fix: cubic-bezier transition typo

* fix: remove updateBylineMeta from click on x/removal callback event

* fix: remove unnecessary "backwards" compatibility since it's new feature

* refactor: replace MutationObserver with event listeners

Replaced the MutationObserver with an event listener, replaced some of
the DOM interaction with a useRef element, and tried to refactor some of
the data getters and setters.

* fix: update effect registration so it only runs on mounting

* refactor: remove unneded "remove token" handler

* fix: look up the byline meta on mount, not just on initial render

* fix: set contenteditable="false" on token spans

Prevents editing the content in these spans, and makes it so that
deleting (with backspace) will remove the whole span at once rather than
editing within the span.

* chore: add some missing docblocks and fix some lint issues

* fix: set default insert location to end of editable field

Updates the "cursorPos" variable logic to use the end of the line if
there's no cursor position set yet, and to add a non-breaking space at
the end of the text if necessary. Also updates the white-space styling
of the editable area, to ensure that users can select any point in the
text they may need to.

* fix: remove margin from last token to prevent confusion with whitespace

* feat: add preview to sidebar interface

* fix: rename panel to Byline

* fix: make modal width fixed

* feat: add function to parse meta for preview

* feat: default custom byline on first toggle

* feat: set default custom byline meta on toggle

* feat: replace author shortcodes on output

* feat: update styles to match new designs

* feat: update styles to match designs

* chore: cleanup, comments, organization

* feat: return an array of coauthors plus authors object, for authors in use in the byline

* chore: few tweaks and linting

---------

Co-authored-by: Leo Germani <leogermani@automattic.com>
Co-authored-by: goldenapples <goldenapplesdesign@gmail.com>
Co-authored-by: Joeleen Kennedy <joeleen@humanmade.com>

* fix: handle missing Mailchimp API key in auth status (#3873)

* fix: remove Mailchimp for WooCommerce from wizard (#3876)

* fix(notices): fix PHP notice (#3872)

* chore: remove unused `react-daterange-picker` package (#3879)

* chore: prevent PHP notice with is_singular (#3874)

* fix(guest-contributors): return them in authors query

* fix: remove the Design link from the Appearance menu (#3878)

* feat(esp-sync): add constant contact support (#3832)

* fix: add constant contact list id setting

* fix: add constant contact to Sync settings

* fix: add constant contact to reader activation settings

* chore: refactor esp settings component

* fix: regressions

---------

Co-authored-by: dkoo <derrick.koo@automattic.com>

* ci: build distributable after release

---------

Co-authored-by: Ron Chambers <116242607+ronchambers@users.noreply.github.com>
Co-authored-by: Rasmy Nguyen <raz@automattic.com>
Co-authored-by: Takshil Kunadia <71006004+Takshil-Kunadia@users.noreply.github.com>
Co-authored-by: Allyson <2000638+allysonsouza@users.noreply.github.com>
Co-authored-by: Leo Germani <leogermani@automattic.com>
Co-authored-by: goldenapples <goldenapplesdesign@gmail.com>
Co-authored-by: Joeleen Kennedy <joeleen@humanmade.com>
Co-authored-by: Camilla Krag Jensen <naxoc@users.noreply.github.com>
Co-authored-by: matticbot <sysops+ghmatticbot@automattic.com>
Co-authored-by: Adam Cassis <adam@adamcassis.com>
Co-authored-by: Adam Cassis <adam.cassis@automattic.com>
Co-authored-by: Laurel <laurel.fulford@automattic.com>
Co-authored-by: dkoo <derrick.koo@automattic.com>
matticbot pushed a commit that referenced this pull request Apr 4, 2025
# [6.3.0-alpha.1](v6.2.2...v6.3.0-alpha.1) (2025-04-04)

### Bug Fixes

* **guest-contributors:** return them in authors query ([3703559](3703559))
* handle missing Mailchimp API key in auth status ([#3873](#3873)) ([6df6fda](6df6fda))
* **ia:** render all emails on reset ([#3867](#3867)) ([c6a71c0](c6a71c0))
* **notices:** fix PHP notice ([#3872](#3872)) ([cc928b2](cc928b2))
* path to autoload ([#3808](#3808)) ([97fa24a](97fa24a))
* remove Mailchimp for WooCommerce from wizard ([#3876](#3876)) ([f6b2484](f6b2484))
* remove the Design link from the Appearance menu ([#3878](#3878)) ([e24f147](e24f147))

### Features

* custom byline interface ([#3746](#3746)) ([289f55e](289f55e))
* **esp-sync:** add constant contact support ([#3832](#3832)) ([8198956](8198956))
* frontend display of bylines ([#3856](#3856)) ([9feeba8](9feeba8))
@matticbot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 6.3.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

matticbot pushed a commit that referenced this pull request Apr 9, 2025
# [6.4.0-alpha.1](v6.3.0...v6.4.0-alpha.1) (2025-04-09)

### Bug Fixes

* **guest-contributors:** return them in authors query ([3703559](3703559))
* handle missing Mailchimp API key in auth status ([#3873](#3873)) ([6df6fda](6df6fda))
* **ia:** render all emails on reset ([#3867](#3867)) ([c6a71c0](c6a71c0))
* **notices:** fix PHP notice ([#3872](#3872)) ([cc928b2](cc928b2))
* path to autoload ([#3808](#3808)) ([97fa24a](97fa24a))
* remove Mailchimp for WooCommerce from wizard ([#3876](#3876)) ([f6b2484](f6b2484))
* remove the Design link from the Appearance menu ([#3878](#3878)) ([e24f147](e24f147))

### Features

* custom byline interface ([#3746](#3746)) ([289f55e](289f55e))
* **esp-sync:** add constant contact support ([#3832](#3832)) ([8198956](8198956))
* frontend display of bylines ([#3856](#3856)) ([9feeba8](9feeba8))
@matticbot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 6.4.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

matticbot pushed a commit that referenced this pull request Apr 14, 2025
# [6.4.0](v6.3.1...v6.4.0) (2025-04-14)

### Bug Fixes

* **guest-contributors:** return them in authors query ([3703559](3703559))
* handle missing Mailchimp API key in auth status ([#3873](#3873)) ([6df6fda](6df6fda))
* **ia:** render all emails on reset ([#3867](#3867)) ([c6a71c0](c6a71c0))
* **notices:** fix PHP notice ([#3872](#3872)) ([cc928b2](cc928b2))
* path to autoload ([#3808](#3808)) ([97fa24a](97fa24a))
* remove Mailchimp for WooCommerce from wizard ([#3876](#3876)) ([f6b2484](f6b2484))
* remove the Design link from the Appearance menu ([#3878](#3878)) ([e24f147](e24f147))

### Features

* custom byline interface ([#3746](#3746)) ([289f55e](289f55e))
* **esp-sync:** add constant contact support ([#3832](#3832)) ([8198956](8198956))
* frontend display of bylines ([#3856](#3856)) ([9feeba8](9feeba8))
@matticbot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 6.4.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants