Skip to content

Commit 9097eea

Browse files
johnwatkins0westonruter
authored andcommitted
Settings screen: allow showing success notice multiple times (#5265)
1 parent 60ebaeb commit 9097eea

File tree

4 files changed

+62
-31
lines changed

4 files changed

+62
-31
lines changed

assets/src/components/amp-notice/index.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,19 @@ function getNoticeIcon( type ) {
7575
* @param {string} props.size The notice size.
7676
* @param {string} props.type The notice type.
7777
*/
78-
export function AMPNotice( { children, className, size = NOTICE_SIZE_LARGE, type = NOTICE_TYPE_INFO } ) {
78+
export function AMPNotice( { children, className, size = NOTICE_SIZE_LARGE, type = NOTICE_TYPE_INFO, ...props } ) {
7979
const noticeIcon = getNoticeIcon( type );
8080

8181
return (
82-
<div className={
83-
classnames(
84-
className,
85-
'amp-notice',
86-
`amp-notice--${ type }`,
87-
`amp-notice--${ size }`,
88-
) }
82+
<div
83+
className={
84+
classnames(
85+
className,
86+
'amp-notice',
87+
`amp-notice--${ type }`,
88+
`amp-notice--${ size }`,
89+
) }
90+
{ ...props }
8991
>
9092
<div className="amp-notice__icon">
9193
{ noticeIcon }

assets/src/components/options-context-provider/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export function OptionsContextProvider( { children, optionsRestPath, populateDef
162162
return;
163163
}
164164

165+
setUpdates( {} );
165166
setDidSaveOptions( true );
166167
setSavingOptions( false );
167168
}, [ delaySave, hasErrorBoundary, optionsRestPath, setAsyncError, originalOptions, setError, updates ] );

assets/src/settings-page/index.js

+34-16
Original file line numberDiff line numberDiff line change
@@ -122,29 +122,45 @@ function scrollFocusedSectionIntoView( focusedSectionId ) {
122122
function Root() {
123123
const [ focusedSection, setFocusedSection ] = useState( global.location.hash.replace( /^#/, '' ) );
124124

125-
const { didSaveOptions, fetchingOptions, saveOptions } = useContext( Options );
125+
const { didSaveOptions, fetchingOptions, hasOptionsChanges, saveOptions } = useContext( Options );
126126
const { error } = useContext( ErrorContext );
127127
const { downloadingTheme } = useContext( ReaderThemes );
128-
const [ saved, setSaved ] = useState( false );
128+
const [ savedNoticeClass, setSavedNoticeClass ] = useState( '' );
129129

130130
/**
131-
* Shows a saved notice on success.
131+
* Show the success notice after options have saved.
132132
*/
133133
useEffect( () => {
134-
if ( true === didSaveOptions && ! downloadingTheme ) {
135-
setSaved( true );
134+
if ( didSaveOptions && ! downloadingTheme ) {
135+
setSavedNoticeClass( 'visible' );
136+
}
137+
}, [ didSaveOptions, downloadingTheme ] );
138+
139+
/**
140+
* If the success notice is showing and updates have been made, hide the notice.
141+
*/
142+
useEffect( () => {
143+
if ( 'visible' === savedNoticeClass && hasOptionsChanges ) {
144+
setSavedNoticeClass( 'dismissed' );
145+
}
146+
}, [ savedNoticeClass, hasOptionsChanges ] );
136147

137-
const timeout = setTimeout( () => [
138-
setSaved( false ),
139-
], 9000 );
148+
/**
149+
* Hide the success notice after several seconds.
150+
*/
151+
useEffect( () => {
152+
if ( 'visible' === savedNoticeClass ) {
153+
const timeout = setTimeout( () => {
154+
setSavedNoticeClass( 'dismissed' );
155+
}, 9000 );
140156

141157
return () => {
142158
clearTimeout( timeout );
143159
};
144160
}
145161

146162
return () => undefined;
147-
}, [ didSaveOptions, downloadingTheme ] );
163+
}, [ savedNoticeClass ] );
148164

149165
/**
150166
* Scroll to the focused element on load or when it changes.
@@ -237,13 +253,15 @@ function Root() {
237253
</form>
238254
<UnsavedChangesWarning excludeUserContext={ true } />
239255
{ error && <ErrorNotice errorMessage={ error.message || __( 'An error occurred. You might be offline or logged out.', 'amp' ) } /> }
240-
{ saved && (
241-
<AMPNotice className={ `amp-save-success-notice` } type={ NOTICE_TYPE_SUCCESS }>
242-
<p>
243-
{ __( 'Settings saved', 'amp' ) }
244-
</p>
245-
</AMPNotice>
246-
) }
256+
<AMPNotice
257+
className={ `amp-save-success-notice ${ savedNoticeClass }` }
258+
type={ NOTICE_TYPE_SUCCESS }
259+
aria-hidden={ 'visible' !== savedNoticeClass }
260+
>
261+
<p>
262+
{ __( 'Settings saved', 'amp' ) }
263+
</p>
264+
</AMPNotice>
247265
</>
248266
);
249267
}

assets/src/settings-page/style.css

+17-7
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,32 @@ li.error-kept {
308308
}
309309
}
310310

311-
@keyframes fadeOut {
311+
@keyframes slideOut {
312312

313313
from {
314-
opacity: 1;
314+
transform: translate3d(0, 0, 0);
315315
}
316316

317317
to {
318-
opacity: 0;
318+
transform: translate3d(300px, 0, 0);
319319
}
320320
}
321321

322+
.amp .amp-save-success-notice.amp-notice:not(.dismissed):not(.visible) {
323+
transform: translate3d(300px, 0, 0);
324+
}
322325

323-
.amp .amp-save-success-notice.amp-notice {
324-
animation: slideIn, fadeOut;
325-
animation-delay: 0s, 8s;
326-
animation-duration: 0.5s, 0.5s;
326+
.amp .amp-save-success-notice.amp-notice.visible {
327+
animation: slideIn;
328+
animation-delay: 0s;
329+
animation-duration: 0.5s;
330+
animation-fill-mode: both;
331+
}
332+
333+
.amp .amp-save-success-notice.amp-notice.dismissed {
334+
animation: slideOut;
335+
animation-delay: 0s;
336+
animation-duration: 0.5s;
327337
animation-fill-mode: both;
328338
}
329339

0 commit comments

Comments
 (0)