-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Global style revisions: redesign style revision items #55913
Changes from 5 commits
53a0c14
1137710
a5bd0ed
064c6dc
857ee07
77ccfcf
e21cc6b
1b72bc2
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 |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
const translationMap = { | ||
blocks: __( 'Block styles' ), | ||
border: __( 'Border' ), | ||
color: __( 'Colors' ), | ||
elements: __( 'Elements' ), | ||
link: __( 'Links' ), | ||
layout: __( 'Layout' ), | ||
spacing: __( 'Spacing' ), | ||
typography: __( 'Typography' ), | ||
}; | ||
|
||
/** | ||
* Returns an array of translated strings describing high level global styles and settings. | ||
* | ||
* @param {Object} revision | ||
* @param {Object} revision.settings Global styles settings. | ||
* @param {Object} revision.styles Global styles. | ||
* @return {string[] | []} An array of translated labels. | ||
*/ | ||
export default function getGlobalStylesChanges( { | ||
settings = {}, | ||
styles = {}, | ||
} ) { | ||
const changes = []; | ||
if ( Object.keys( settings ).length > 0 ) { | ||
changes.push( __( 'Global settings' ) ); | ||
} | ||
Object.keys( styles ).forEach( ( key ) => { | ||
if ( translationMap[ key ] ) { | ||
changes.push( translationMap[ key ] ); | ||
} | ||
} ); | ||
|
||
return changes; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,33 +12,40 @@ import { dateI18n, getDate, humanTimeDiff, getSettings } from '@wordpress/date'; | |
import { store as coreStore } from '@wordpress/core-data'; | ||
import { useSelect } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import getGlobalStylesChanges from './get-revision-changes'; | ||
|
||
const DAY_IN_MILLISECONDS = 60 * 60 * 1000 * 24; | ||
const dateFormat = getSettings().formats.date; | ||
const datetimeAbbreviatedFormat = getSettings().formats.datetimeAbbreviated; | ||
|
||
ramonjd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Returns a button label for the revision. | ||
* | ||
* @param {Object} revision A revision object. | ||
* @param {string|number} id A revision object. | ||
* @param {boolean} isLatest Whether the revision is the most current. | ||
* @param {string} authorDisplayName Author name. | ||
* @param {Date} modifiedDate Revision modified date object. | ||
* @return {string} Translated label. | ||
*/ | ||
function getRevisionLabel( revision ) { | ||
const authorDisplayName = revision?.author?.name || __( 'User' ); | ||
|
||
if ( 'parent' === revision?.id ) { | ||
function getRevisionLabel( id, isLatest, authorDisplayName, modifiedDate ) { | ||
ramonjd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if ( 'parent' === id ) { | ||
return __( 'Reset the styles to the theme defaults' ); | ||
} | ||
|
||
if ( 'unsaved' === revision?.id ) { | ||
if ( 'unsaved' === id ) { | ||
return sprintf( | ||
/* translators: %s author display name */ | ||
__( 'Unsaved changes by %s' ), | ||
authorDisplayName | ||
); | ||
} | ||
|
||
const formattedDate = dateI18n( | ||
getSettings().formats.datetimeAbbreviated, | ||
getDate( revision?.modified ) | ||
); | ||
const formattedDate = dateI18n( datetimeAbbreviatedFormat, modifiedDate ); | ||
|
||
return revision?.isLatest | ||
return isLatest | ||
? sprintf( | ||
/* translators: %1$s author display name, %2$s: revision creation date */ | ||
__( 'Changes saved by %1$s on %2$s (current)' ), | ||
|
@@ -65,25 +72,40 @@ function getRevisionLabel( revision ) { | |
* @return {JSX.Element} The modal component. | ||
*/ | ||
function RevisionsButtons( { userRevisions, selectedRevisionId, onChange } ) { | ||
const currentTheme = useSelect( | ||
( select ) => select( coreStore ).getCurrentTheme(), | ||
[] | ||
); | ||
const { currentThemeName, currentUser } = useSelect( ( select ) => { | ||
const { getCurrentTheme, getCurrentUser } = select( coreStore ); | ||
const currentTheme = getCurrentTheme(); | ||
return { | ||
currentThemeName: | ||
currentTheme?.name?.rendered || currentTheme?.stylesheet, | ||
currentUser: getCurrentUser(), | ||
}; | ||
}, [] ); | ||
const dateNowInMs = getDate().getTime(); | ||
|
||
return ( | ||
<ol | ||
className="edit-site-global-styles-screen-revisions__revisions-list" | ||
aria-label={ __( 'Global styles revisions' ) } | ||
role="group" | ||
> | ||
{ userRevisions.map( ( revision, index ) => { | ||
const { id, author, modified } = revision; | ||
const authorDisplayName = author?.name || __( 'User' ); | ||
const authorAvatar = author?.avatar_urls?.[ '48' ]; | ||
const isUnsaved = 'unsaved' === revision?.id; | ||
const { id, isLatest, author, modified } = revision; | ||
const isUnsaved = 'unsaved' === id; | ||
// Unsaved changes are created by the current user. | ||
const revisionAuthor = isUnsaved ? currentUser : author; | ||
const authorDisplayName = revisionAuthor?.name || __( 'User' ); | ||
const authorAvatar = revisionAuthor?.avatar_urls?.[ '48' ]; | ||
const isSelected = selectedRevisionId | ||
? selectedRevisionId === revision?.id | ||
? selectedRevisionId === id | ||
: index === 0; | ||
const isReset = 'parent' === revision?.id; | ||
const isReset = 'parent' === id; | ||
const modifiedDate = getDate( modified ); | ||
const displayDate = | ||
modified && | ||
dateNowInMs - modifiedDate.getTime() > DAY_IN_MILLISECONDS | ||
? dateI18n( dateFormat, modifiedDate ) | ||
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. The date is formatted as OCTOBER 20 2023 This doesn't match the designs, which specify an abbreviated month — OCT 20 2023 — however I think it's important to introduce new formats using the date library and into Core so that themes can override them. So TL;DR I can open a new PR and corresponding core patch to introduce the abbreviated month format if folks think it's worth it. |
||
: humanTimeDiff( modified ); | ||
|
||
return ( | ||
<li | ||
|
@@ -102,40 +124,39 @@ function RevisionsButtons( { userRevisions, selectedRevisionId, onChange } ) { | |
onClick={ () => { | ||
onChange( revision ); | ||
} } | ||
label={ getRevisionLabel( revision ) } | ||
label={ getRevisionLabel( | ||
id, | ||
isLatest, | ||
authorDisplayName, | ||
modifiedDate | ||
) } | ||
> | ||
{ isReset ? ( | ||
<span className="edit-site-global-styles-screen-revisions__description"> | ||
{ __( 'Default styles' ) } | ||
<span className="edit-site-global-styles-screen-revisions__meta"> | ||
{ currentTheme?.name?.rendered || | ||
currentTheme?.stylesheet } | ||
{ currentThemeName } | ||
</span> | ||
</span> | ||
) : ( | ||
<span className="edit-site-global-styles-screen-revisions__description"> | ||
<time dateTime={ modified }> | ||
{ humanTimeDiff( modified ) } | ||
<time | ||
className="edit-site-global-styles-screen-revisions__date" | ||
dateTime={ modified } | ||
> | ||
{ displayDate } | ||
</time> | ||
<span className="edit-site-global-styles-screen-revisions__changes"> | ||
{ getGlobalStylesChanges( | ||
revision | ||
).join( ', ' ) } | ||
</span> | ||
<span className="edit-site-global-styles-screen-revisions__meta"> | ||
{ isUnsaved | ||
? sprintf( | ||
/* translators: %s author display name */ | ||
__( | ||
'Unsaved changes by %s' | ||
), | ||
authorDisplayName | ||
) | ||
: sprintf( | ||
/* translators: %s author display name */ | ||
__( 'Changes saved by %s' ), | ||
authorDisplayName | ||
) } | ||
|
||
<img | ||
alt={ author?.name } | ||
alt={ authorDisplayName } | ||
src={ authorAvatar } | ||
/> | ||
{ authorDisplayName } | ||
</span> | ||
</span> | ||
) } | ||
|
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 we break out block names in a follow up? For example show "Paragraph block typography" etc instead of a generic "Block styles". I think block styles are going to change a bunch and a lot of "Block styles" being listed is not super useful.
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.
For blocks it makes sense. I think we have to put a limit on it at some point as it needs to be calculated for every revision item on render.
I'll see how memoizing/caching each one might work too.
@c4rl0sbr4v0 explored comparing the style/settings tree deeply: #52829 (comment)