-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Gutenlypso: Disable the Publish button if the email is unverified #29594
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
7373a55
Gutenlypso: Disable the Publish button if the email is unverified
mmtr 2441771
Fix warning caused by an invalid href value
mmtr d5d6164
Restore original withSelect and new component method for getting the …
mmtr 8edfc00
Use localize Higher-Order Component
mmtr 3865b41
Remove withState in favor of this.state
mmtr 7939fe6
Add JSDoc and rename togglePostSaving to toggleLockPostSaving
mmtr 492ab33
Prevent clicks on Publish button when disabled
mmtr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
217 changes: 217 additions & 0 deletions
217
client/gutenberg/editor/components/post-publish-button-or-toggle/index.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
/** @format */ | ||
/** | ||
* External Dependencies | ||
*/ | ||
import React, { Component, Fragment } from 'react'; | ||
import { get } from 'lodash'; | ||
import { localize } from 'i18n-calypso'; | ||
import { connect } from 'react-redux'; | ||
|
||
/** | ||
* WordPress dependencies. | ||
*/ | ||
import { compose } from '@wordpress/compose'; | ||
import { withDispatch, withSelect } from '@wordpress/data'; | ||
import { PostPublishButton } from '@wordpress/editor'; | ||
import { withViewportMatch } from '@wordpress/viewport'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import VerifyEmailDialog from 'components/email-verification/email-verification-dialog'; | ||
import { getSelectedSiteId } from 'state/ui/selectors'; | ||
import { isCurrentUserEmailVerified } from 'state/current-user/selectors'; | ||
import isUnlaunchedSite from 'state/selectors/is-unlaunched-site'; | ||
import isVipSite from 'state/selectors/is-vip-site'; | ||
|
||
export class PostPublishButtonOrToggle extends Component { | ||
state = { | ||
showEmailVerificationDialog: false, | ||
}; | ||
|
||
componentDidMount() { | ||
this.toggleLockPostSaving(); | ||
} | ||
|
||
componentDidUpdate( prevProps ) { | ||
const { userNeedsVerification, isPublished, isBeingScheduled } = this.props; | ||
if ( | ||
userNeedsVerification !== prevProps.userNeedsVerification || | ||
isPublished !== prevProps.isPublished || | ||
isBeingScheduled !== prevProps.isBeingScheduled | ||
) { | ||
this.toggleLockPostSaving(); | ||
} | ||
} | ||
|
||
/** | ||
* Locks the post saving if the user needs to verify their email, or unlocks it otherwise. | ||
*/ | ||
toggleLockPostSaving() { | ||
const { | ||
userNeedsVerification, | ||
lockPostSaving, | ||
unlockPostSaving, | ||
createWarningNotice, | ||
translate, | ||
} = this.props; | ||
|
||
const lockName = 'blockEditorPostSavingLock'; | ||
|
||
if ( userNeedsVerification ) { | ||
lockPostSaving( lockName ); | ||
|
||
createWarningNotice( this.getVerificationNoticeLabel(), { | ||
id: 'verify-email-notice', | ||
isDismissible: false, | ||
actions: [ | ||
{ | ||
label: translate( 'Learn More' ), | ||
url: '#', | ||
onClick: e => { | ||
e.preventDefault(); | ||
this.setState( { showEmailVerificationDialog: true } ); | ||
}, | ||
}, | ||
], | ||
} ); | ||
} else { | ||
unlockPostSaving( lockName ); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the label to be used in the verification notice which depends on the post status | ||
* @returns {string} The verification notice label | ||
*/ | ||
getVerificationNoticeLabel() { | ||
const { isPublished, isBeingScheduled, translate } = this.props; | ||
if ( isPublished ) { | ||
return translate( 'To update, check your email and confirm your address.' ); | ||
} else if ( isBeingScheduled ) { | ||
return translate( 'To schedule, check your email and confirm your address.' ); | ||
} | ||
return translate( 'To publish, check your email and confirm your address.' ); | ||
} | ||
|
||
/** | ||
* Closes the dialog explaining why we need to verify the email | ||
*/ | ||
closeVerifyEmailDialog = () => { | ||
this.setState( { showEmailVerificationDialog: false } ); | ||
}; | ||
|
||
render() { | ||
const { | ||
forceIsDirty, | ||
forceIsSaving, | ||
hasPublishAction, | ||
isBeingScheduled, | ||
isLessThanMediumViewport, | ||
isPending, | ||
isPublished, | ||
isPublishSidebarEnabled, | ||
isPublishSidebarOpened, | ||
isScheduled, | ||
togglePublishSidebar, | ||
} = this.props; | ||
|
||
const { showEmailVerificationDialog } = this.state; | ||
|
||
const IS_TOGGLE = 'toggle'; | ||
const IS_BUTTON = 'button'; | ||
let component; | ||
|
||
/** | ||
* Conditions to show a BUTTON (publish directly) or a TOGGLE (open publish sidebar): | ||
* | ||
* 1) We want to show a BUTTON when the post status is at the _final stage_ | ||
* for a particular role (see https://codex.wordpress.org/Post_Status): | ||
* | ||
* - is published | ||
* - is scheduled to be published | ||
* - is pending and can't be published (but only for viewports >= medium). | ||
* Originally, we considered showing a button for pending posts that couldn't be published | ||
* (for example, for an author with the contributor role). Some languages can have | ||
* long translations for "Submit for review", so given the lack of UI real estate available | ||
* we decided to take into account the viewport in that case. | ||
* See: https://github.com/WordPress/gutenberg/issues/10475 | ||
* | ||
* 2) Then, in small viewports, we'll show a TOGGLE. | ||
* | ||
* 3) Finally, we'll use the publish sidebar status to decide: | ||
* | ||
* - if it is enabled, we show a TOGGLE | ||
* - if it is disabled, we show a BUTTON | ||
*/ | ||
if ( | ||
isPublished || | ||
( isScheduled && isBeingScheduled ) || | ||
( isPending && ! hasPublishAction && ! isLessThanMediumViewport ) | ||
) { | ||
component = IS_BUTTON; | ||
} else if ( isLessThanMediumViewport ) { | ||
component = IS_TOGGLE; | ||
} else if ( isPublishSidebarEnabled ) { | ||
component = IS_TOGGLE; | ||
} else { | ||
component = IS_BUTTON; | ||
} | ||
|
||
return ( | ||
<Fragment> | ||
<PostPublishButton | ||
forceIsDirty={ forceIsDirty } | ||
forceIsSaving={ forceIsSaving } | ||
isOpen={ isPublishSidebarOpened } | ||
isToggle={ component === IS_TOGGLE } | ||
onToggle={ togglePublishSidebar } | ||
/> | ||
{ showEmailVerificationDialog && ( | ||
<VerifyEmailDialog onClose={ this.closeVerifyEmailDialog } /> | ||
) } | ||
</Fragment> | ||
); | ||
} | ||
} | ||
|
||
export default compose( | ||
withSelect( select => ( { | ||
hasPublishAction: get( | ||
select( 'core/editor' ).getCurrentPost(), | ||
[ '_links', 'wp:action-publish' ], | ||
false | ||
), | ||
isBeingScheduled: select( 'core/editor' ).isEditedPostBeingScheduled(), | ||
isPending: select( 'core/editor' ).isCurrentPostPending(), | ||
isPublished: select( 'core/editor' ).isCurrentPostPublished(), | ||
isPublishSidebarEnabled: select( 'core/editor' ).isPublishSidebarEnabled(), | ||
isPublishSidebarOpened: select( 'core/edit-post' ).isPublishSidebarOpened(), | ||
isScheduled: select( 'core/editor' ).isCurrentPostScheduled(), | ||
} ) ), | ||
withDispatch( dispatch => { | ||
const { togglePublishSidebar } = dispatch( 'core/edit-post' ); | ||
const { createWarningNotice } = dispatch( 'core/notices' ); | ||
const { lockPostSaving, unlockPostSaving } = dispatch( 'core/editor' ); | ||
return { | ||
togglePublishSidebar, | ||
createWarningNotice, | ||
lockPostSaving, | ||
unlockPostSaving, | ||
}; | ||
} ), | ||
withViewportMatch( { isLessThanMediumViewport: '< medium' } ), | ||
connect( state => { | ||
const siteId = getSelectedSiteId( state ); | ||
|
||
// do not allow publish for unverified e-mails, but allow if the site is VIP, or if the site is unlaunched | ||
const userNeedsVerification = | ||
! isCurrentUserEmailVerified( state ) && | ||
! isVipSite( state, siteId ) && | ||
! isUnlaunchedSite( state, siteId ); | ||
|
||
return { | ||
userNeedsVerification, | ||
}; | ||
} ) | ||
)( localize( PostPublishButtonOrToggle ) ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 0 additions & 101 deletions
101
client/gutenberg/editor/edit-post/components/header/post-publish-button-or-toggle.js
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Testing the PR I've got into a funny case that somehow "breaks" these checks.
This is correct: we allow unverified users to publish, as long as their site is not yet public.
Though, to launch a site, the user first needs to verify their email.
So, I wonder: when can it happen that a user has both a verified email and an unlaunched site—or viceversa?
Those two cases would be the only two that would enable the whole
userNeedsVerification
flow, with the warning and the dialog, etc. (in both Gutenberg and Classic)cc @scruffian for adding
isUnlaunchedSite
to the equivalent of this inEditorGroundControl
in #27962.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.
It's possible for a user to have an unlaunched site and a verified email address. Since the process to launch a site would be to first verify the email address and then launch the site, any users who are part way through that process will be in that state.
The reverse state should be impossible - we should never allow users with unverified email addresses to launch a site.
Does that answer your question?
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.
Absolutely yes, thank you very much @scruffian!
I didn't proceed with the test
because I'm that lazyto keep the user email unverified, and somehow just assumed verifying the email would also automatically launch (which would definitely be odd).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.
(Sorry for the delay from my previous answer, I just now got to test it)
So, what happens then is that:
In other words, this would never be true:
In other words, we don't need the unverified email notice and the logic that prevents publishing a post, for both Guten and Classic.
Am I wrong on this?
Like, it's almost EOD and I've got the flu, I might very well have missed something. 😄
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.
I think this is not true. According to #27962, only private sites are unlaunched, so an unverified user can have a launched site if it is public.