diff --git a/packages/edit-site/src/components/global-styles/screen-revisions/revisions-buttons.js b/packages/edit-site/src/components/global-styles/screen-revisions/revisions-buttons.js
index feec0f25ac8823..2786bf6d791212 100644
--- a/packages/edit-site/src/components/global-styles/screen-revisions/revisions-buttons.js
+++ b/packages/edit-site/src/components/global-styles/screen-revisions/revisions-buttons.js
@@ -12,20 +12,28 @@ import { dateI18n, getDate, humanTimeDiff, getSettings } from '@wordpress/date';
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
+const DAY_IN_MILLISECONDS = 60 * 60 * 1000 * 24;
+
/**
* 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 {string} formattedModifiedDate Revision modified date formatted.
* @return {string} Translated label.
*/
-function getRevisionLabel( revision ) {
- const authorDisplayName = revision?.author?.name || __( 'User' );
-
- if ( 'parent' === revision?.id ) {
+function getRevisionLabel(
+ id,
+ isLatest,
+ authorDisplayName,
+ formattedModifiedDate
+) {
+ 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' ),
@@ -33,23 +41,18 @@ function getRevisionLabel( revision ) {
);
}
- const formattedDate = dateI18n(
- getSettings().formats.datetimeAbbreviated,
- getDate( revision?.modified )
- );
-
- 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)' ),
authorDisplayName,
- formattedDate
+ formattedModifiedDate
)
: sprintf(
/* translators: %1$s author display name, %2$s: revision creation date */
__( 'Changes saved by %1$s on %2$s' ),
authorDisplayName,
- formattedDate
+ formattedModifiedDate
);
}
@@ -65,10 +68,18 @@ 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();
+ const { date: dateFormat, datetimeAbbreviated } = getSettings().formats;
+
return (
{ 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 )
+ : humanTimeDiff( modified );
+ const revisionLabel = getRevisionLabel(
+ id,
+ isLatest,
+ authorDisplayName,
+ dateI18n( datetimeAbbreviated, modifiedDate )
+ );
return (
- {
onChange( revision );
} }
- label={ getRevisionLabel( revision ) }
+ label={ revisionLabel }
>
{ isReset ? (
{ __( 'Default styles' ) }
- { currentTheme?.name?.rendered ||
- currentTheme?.stylesheet }
+ { currentThemeName }
) : (
-
+ { isUnsaved ? (
+
+ { __( '(Unsaved)' ) }
+
+ ) : (
+
+ ) }
- { isUnsaved
- ? sprintf(
- /* translators: %s author display name */
- __(
- 'Unsaved changes by %s'
- ),
- authorDisplayName
- )
- : sprintf(
- /* translators: %s author display name */
- __( 'Changes saved by %s' ),
- authorDisplayName
- ) }
-
+ { authorDisplayName }
) }
diff --git a/packages/edit-site/src/components/global-styles/screen-revisions/style.scss b/packages/edit-site/src/components/global-styles/screen-revisions/style.scss
index 238f3f7d116e19..6598fcb5ce1c74 100644
--- a/packages/edit-site/src/components/global-styles/screen-revisions/style.scss
+++ b/packages/edit-site/src/components/global-styles/screen-revisions/style.scss
@@ -8,62 +8,80 @@
margin: 0;
li {
margin-bottom: 0;
- border-left: 1px solid $gray-300;
}
}
.edit-site-global-styles-screen-revisions__revision-item {
position: relative;
- padding: $grid-unit-10 0 $grid-unit-10 $grid-unit-15;
+ padding-left: $grid-unit-20;
+ overflow: hidden;
+ cursor: pointer;
- &:first-child {
- padding-top: 0;
+ &:hover {
+ background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
+ .edit-site-global-styles-screen-revisions__date {
+ color: var(--wp-admin-theme-color);
+ }
}
- &:last-child {
- padding-bottom: 0;
+ &::before,
+ &::after {
+ position: absolute;
+ content: "\a";
+ display: block;
}
&::before {
background: $gray-300;
border-radius: 50%;
- content: "\a";
- display: inline-block;
height: $grid-unit-10;
width: $grid-unit-10;
- position: absolute;
- top: 50%;
- left: 0;
+ top: $grid-unit-20 + 2;
+ left: $grid-unit-20 + 1; // So the circle is centered on the line.
transform: translate(-50%, -50%);
+ z-index: 1;
}
&.is-selected::before {
background: var(--wp-components-color-accent, var(--wp-admin-theme-color, #007cba));
}
-}
-.edit-site-global-styles-screen-revisions__revision-button {
- width: 100%;
- height: auto;
- display: block;
- padding: $grid-unit-10 $grid-unit-15;
+ &::after {
+ height: 100%;
+ left: $grid-unit-20;
+ top: 0;
+ width: 0;
+ border: 0.5px solid $gray-300;
+ }
- &:hover {
- background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
+ &:first-child::after {
+ top: $grid-unit-20 + 2;
+ }
- .edit-site-global-styles-screen-revisions__date {
- color: var(--wp-admin-theme-color);
+ &:last-child::after {
+ height: $grid-unit-20 + 2;
+ }
+
+ // Nested to override specificity of .components-button.
+ .edit-site-global-styles-screen-revisions__revision-button {
+ width: 100%;
+ height: auto;
+ display: block;
+ padding: $grid-unit-15 $grid-unit-15 $grid-unit-15 $grid-unit-30;
+ &:focus,
+ &:active {
+ outline: 0;
+ box-shadow: none;
}
}
}
.is-selected {
+ color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #007cba));
+ background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
.edit-site-global-styles-screen-revisions__revision-button {
- color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #007cba));
opacity: 1;
- background: rgba(var(--wp-admin-theme-color--rgb), 0.04);
}
-
- .edit-site-global-styles-screen-revisions__meta {
+ .edit-site-global-styles-screen-revisions__date {
color: var(--wp-admin-theme-color);
}
}
@@ -78,20 +96,26 @@
flex-direction: column;
align-items: flex-start;
gap: $grid-unit-10;
+ .edit-site-global-styles-screen-revisions__date {
+ text-transform: uppercase;
+ font-weight: 600;
+ font-size: 12px;
+ }
}
.edit-site-global-styles-screen-revisions__meta {
- color: $gray-700;
+ color: $gray-600;
display: flex;
- justify-content: space-between;
+ justify-content: start;
width: 100%;
align-items: center;
- text-align: left;
+ font-size: 12px;
img {
width: $grid-unit-20;
height: $grid-unit-20;
border-radius: 100%;
+ margin-right: $grid-unit-10;
}
}