From d81f1b9ba217c3858fd7f05b6ca03b108c675abb Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Sun, 23 Jun 2019 14:50:01 +0200 Subject: [PATCH 01/37] Simple Payments: Report Minimum Plan Required in Availability Endpoint --- modules/simple-payments/simple-payments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index e1b7f8d77d456..578d7d51a7281 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -64,7 +64,7 @@ function register_gutenberg_block() { if ( $this->is_enabled_jetpack_simple_payments() ) { jetpack_register_block( 'jetpack/simple-payments' ); } else { - Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/simple-payments', 'missing_plan' ); + Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/simple-payments', 'premium_plan_required' ); } } From 99976e916e453369cc1c07d68b3a7b9196cd470a Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Sun, 23 Jun 2019 14:50:38 +0200 Subject: [PATCH 02/37] Blocks: Show Blocks if they're missing a plan This way, the user will be able to insert the block, and will be prompted to upgrade to a plan that enables it. --- extensions/shared/register-jetpack-block.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index 9c53e8f21ea99..dfac26a983867 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -1,6 +1,7 @@ /** * External dependencies */ +import { endsWith } from 'lodash'; import { registerBlockType } from '@wordpress/blocks'; /** @@ -11,6 +12,13 @@ import getJetpackExtensionAvailability from './get-jetpack-extension-availabilit const betaExtensions = extensionList.beta || []; +function requiresPlan( unavailableReason ) { + if ( endsWith( unavailableReason, '_plan_required' ) ) { + return unavailableReason.substring( 0, unavailableReason.length - '_plan_required'.length ); + } + return false; +} + /** * Registers a gutenberg block if the availability requirements are met. * @@ -22,7 +30,7 @@ const betaExtensions = extensionList.beta || []; export default function registerJetpackBlock( name, settings, childBlocks = [] ) { const { available, unavailableReason } = getJetpackExtensionAvailability( name ); - if ( ! available ) { + if ( ! available && ! requiresPlan( unavailableReason ) ) { if ( 'production' !== process.env.NODE_ENV ) { // eslint-disable-next-line no-console console.warn( From a5ed4236ef1098b82ed2c4673c33a218b7add2ec Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:06:08 +0200 Subject: [PATCH 03/37] Steal files from @Automattic/wp-calypso#33723 --- extensions/editor.js | 1 + extensions/shared/upgrade-nudge/index.jsx | 28 +++++++ extensions/shared/upgrade-nudge/style.scss | 85 ++++++++++++++++++++++ extensions/shared/wrap-premium-blocks.jsx | 39 ++++++++++ 4 files changed, 153 insertions(+) create mode 100644 extensions/shared/upgrade-nudge/index.jsx create mode 100644 extensions/shared/upgrade-nudge/style.scss create mode 100644 extensions/shared/wrap-premium-blocks.jsx diff --git a/extensions/editor.js b/extensions/editor.js index 34458e4cc57df..c7259c8e70efa 100644 --- a/extensions/editor.js +++ b/extensions/editor.js @@ -3,3 +3,4 @@ */ import './shared/public-path'; import './shared/block-category'; +import './shared/wrap-premium-blocks'; diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx new file mode 100644 index 0000000000000..6fd5a6ac8ed35 --- /dev/null +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -0,0 +1,28 @@ +/** + * External dependencies + */ +import React from 'react'; +import { localize } from 'i18n-calypso'; +import Gridicon from 'gridicons'; + +import './style.scss'; + +class UpgradeNudge extends React.Component { + render() { + const { translate } = this.props; + return ( +
+ +
+ { translate( 'Upgrade to Premium' ) } + + { translate( 'To gain access to this block.' ) } + +
+ +
+ ); + } +} + +export default localize( UpgradeNudge ); diff --git a/extensions/shared/upgrade-nudge/style.scss b/extensions/shared/upgrade-nudge/style.scss new file mode 100644 index 0000000000000..8cb986e65eeae --- /dev/null +++ b/extensions/shared/upgrade-nudge/style.scss @@ -0,0 +1,85 @@ +@media ( max-width: 600px ) { + // stylelint-disable-next-line selector-max-id + .is-iframed #wpbody { + padding-top: 0; + } +} + +@media ( min-width: 600px ) { + body.is-iframed.is-fullscreen-mode .edit-post-header { + top: 0; + } +} + +@media ( min-width: 782px ) { + .edit-post-layout__content { + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 88px; + min-height: calc( 100% - 88px ); + height: auto; + margin-left: 160px; + } + + body.is-fullscreen-mode .edit-post-layout__content { + top: 56px; + position: fixed; + } +} + +@media ( min-width: 782px ) and ( max-width: 1079px ) { + .is-fullscreen-mode .edit-post-layout.has-fixed-toolbar .components-notice { + top: 37px; + } +} + +.components-notice-list { + z-index: 29; // Ensure notices are placed behind the editor header (z-index: 30). +} + +.premium-blocks__wrapper { + border: 1px solid var( --color-border-subtle ); +} + +.premium-blocks__disabled { + opacity: 0.5; + padding: 10px; +} + +.upgrade-nudge { + border-left: 3px solid var( --color-plan-premium ); + box-shadow: 0 0 0 1px var( --color-border-subtle ); + display: flex; + margin: 0 -1px 1em 0; + padding: 12px 16px; + text-align: left; + width: 100%; +} + +.upgrade-nudge__icon { + background: var( --color-plan-premium ); + border-radius: 50%; + box-sizing: content-box; + margin-right: 16px; + color: var( --color-white ); + padding: 6px; + align-self: center; + flex: 0 0 auto; + fill: var( --color-white ); +} + +.upgrade-nudge__title { + font-size: 14px; +} + +.upgrade-nudge__message { + color: var( --color-text-subtle ); + font-size: 12px; + display: block; +} + +.upgrade-nudge__button { + margin-left: auto; +} diff --git a/extensions/shared/wrap-premium-blocks.jsx b/extensions/shared/wrap-premium-blocks.jsx new file mode 100644 index 0000000000000..afad3b327b4b1 --- /dev/null +++ b/extensions/shared/wrap-premium-blocks.jsx @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import React from 'react'; +import { addFilter } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import UpgradeNudge from './upgrade-nudge'; + +const wrapPremiumBlocks = WrappedComponent => { + return class extends React.Component { + render() { + // Wraps the input component in a container, without mutating it. Good! + return ( +
+ +
+ +
+
+ ); + } + }; +}; + +const premiumBlocks = ( settings, name ) => { + if ( name === 'jetpack/simple-payments' ) { + return { + ...settings, + edit: wrapPremiumBlocks( settings.edit ), + }; + } + + return settings; +}; + +addFilter( 'blocks.registerBlockType', 'jetpack', premiumBlocks ); From cf5587d816fc3780cb8e2fe8a2eda12622c6db85 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:15:19 +0200 Subject: [PATCH 04/37] So functional, much wow --- extensions/shared/wrap-premium-blocks.jsx | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/extensions/shared/wrap-premium-blocks.jsx b/extensions/shared/wrap-premium-blocks.jsx index afad3b327b4b1..fdd01f0a2bcef 100644 --- a/extensions/shared/wrap-premium-blocks.jsx +++ b/extensions/shared/wrap-premium-blocks.jsx @@ -9,21 +9,15 @@ import { addFilter } from '@wordpress/hooks'; */ import UpgradeNudge from './upgrade-nudge'; -const wrapPremiumBlocks = WrappedComponent => { - return class extends React.Component { - render() { - // Wraps the input component in a container, without mutating it. Good! - return ( -
- -
- -
-
- ); - } - }; -}; +const wrapPremiumBlocks = WrappedComponent => props => ( + // Wraps the input component in a container, without mutating it. Good! +
+ +
+ +
+
+); const premiumBlocks = ( settings, name ) => { if ( name === 'jetpack/simple-payments' ) { From ae97d6135bfbce50a702777ff89a79f1ad4f3885 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:19:49 +0200 Subject: [PATCH 05/37] Remove React import --- extensions/shared/wrap-premium-blocks.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/shared/wrap-premium-blocks.jsx b/extensions/shared/wrap-premium-blocks.jsx index fdd01f0a2bcef..41fb8e62eb21a 100644 --- a/extensions/shared/wrap-premium-blocks.jsx +++ b/extensions/shared/wrap-premium-blocks.jsx @@ -1,7 +1,6 @@ /** * External dependencies */ -import React from 'react'; import { addFilter } from '@wordpress/hooks'; /** From 24a131c1d2e91ef2b9056ba20f3bc38a47799357 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:29:44 +0200 Subject: [PATCH 06/37] Only wrap block if plan isn't sufficient --- extensions/shared/register-jetpack-block.js | 12 ++++++------ extensions/shared/wrap-premium-blocks.jsx | 20 +------------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index dfac26a983867..25bfa3b1af25c 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -9,6 +9,7 @@ import { registerBlockType } from '@wordpress/blocks'; */ import extensionList from '../index.json'; import getJetpackExtensionAvailability from './get-jetpack-extension-availability'; +import wrapPremiumBlocks from './wrap-premium-blocks'; const betaExtensions = extensionList.beta || []; @@ -40,12 +41,11 @@ export default function registerJetpackBlock( name, settings, childBlocks = [] ) return false; } - const result = registerBlockType( - `jetpack/${ name }`, - betaExtensions.includes( name ) - ? { ...settings, title: `${ settings.title } (beta)` } - : settings - ); + const result = registerBlockType( `jetpack/${ name }`, { + ...settings, + title: betaExtensions.includes( name ) ? `${ settings.title } (beta)` : settings.title, + edit: requiresPlan( unavailableReason ) ? wrapPremiumBlocks( settings.edit ) : settings.edit, + } ); // Register child blocks. Using `registerBlockType()` directly avoids availability checks -- if // their parent is available, we register them all, without checking for their individual availability. diff --git a/extensions/shared/wrap-premium-blocks.jsx b/extensions/shared/wrap-premium-blocks.jsx index 41fb8e62eb21a..cdad28f9e862a 100644 --- a/extensions/shared/wrap-premium-blocks.jsx +++ b/extensions/shared/wrap-premium-blocks.jsx @@ -1,14 +1,9 @@ -/** - * External dependencies - */ -import { addFilter } from '@wordpress/hooks'; - /** * Internal dependencies */ import UpgradeNudge from './upgrade-nudge'; -const wrapPremiumBlocks = WrappedComponent => props => ( +export default WrappedComponent => props => ( // Wraps the input component in a container, without mutating it. Good!
@@ -17,16 +12,3 @@ const wrapPremiumBlocks = WrappedComponent => props => (
); - -const premiumBlocks = ( settings, name ) => { - if ( name === 'jetpack/simple-payments' ) { - return { - ...settings, - edit: wrapPremiumBlocks( settings.edit ), - }; - } - - return settings; -}; - -addFilter( 'blocks.registerBlockType', 'jetpack', premiumBlocks ); From ea064496ff08ea76dc673a4838d1f6204a6978ea Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:35:07 +0200 Subject: [PATCH 07/37] Rename to wrap-paid-block --- extensions/shared/register-jetpack-block.js | 4 ++-- extensions/shared/upgrade-nudge/style.scss | 4 ++-- .../shared/{wrap-premium-blocks.jsx => wrap-paid-block.jsx} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename extensions/shared/{wrap-premium-blocks.jsx => wrap-paid-block.jsx} (75%) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index 25bfa3b1af25c..80df117edb30e 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -9,7 +9,7 @@ import { registerBlockType } from '@wordpress/blocks'; */ import extensionList from '../index.json'; import getJetpackExtensionAvailability from './get-jetpack-extension-availability'; -import wrapPremiumBlocks from './wrap-premium-blocks'; +import wrapPaidBlock from './wrap-paid-block'; const betaExtensions = extensionList.beta || []; @@ -44,7 +44,7 @@ export default function registerJetpackBlock( name, settings, childBlocks = [] ) const result = registerBlockType( `jetpack/${ name }`, { ...settings, title: betaExtensions.includes( name ) ? `${ settings.title } (beta)` : settings.title, - edit: requiresPlan( unavailableReason ) ? wrapPremiumBlocks( settings.edit ) : settings.edit, + edit: requiresPlan( unavailableReason ) ? wrapPaidBlock( settings.edit ) : settings.edit, } ); // Register child blocks. Using `registerBlockType()` directly avoids availability checks -- if diff --git a/extensions/shared/upgrade-nudge/style.scss b/extensions/shared/upgrade-nudge/style.scss index 8cb986e65eeae..96a19fbdf1448 100644 --- a/extensions/shared/upgrade-nudge/style.scss +++ b/extensions/shared/upgrade-nudge/style.scss @@ -39,11 +39,11 @@ z-index: 29; // Ensure notices are placed behind the editor header (z-index: 30). } -.premium-blocks__wrapper { +.paid-block__wrapper { border: 1px solid var( --color-border-subtle ); } -.premium-blocks__disabled { +.paid-block__disabled { opacity: 0.5; padding: 10px; } diff --git a/extensions/shared/wrap-premium-blocks.jsx b/extensions/shared/wrap-paid-block.jsx similarity index 75% rename from extensions/shared/wrap-premium-blocks.jsx rename to extensions/shared/wrap-paid-block.jsx index cdad28f9e862a..dafac48ee5fce 100644 --- a/extensions/shared/wrap-premium-blocks.jsx +++ b/extensions/shared/wrap-paid-block.jsx @@ -5,9 +5,9 @@ import UpgradeNudge from './upgrade-nudge'; export default WrappedComponent => props => ( // Wraps the input component in a container, without mutating it. Good! -
+
-
+
From 21ec9faf1c5eb3aa7ce0017b938731a751d53255 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:36:34 +0200 Subject: [PATCH 08/37] Moar functional --- extensions/shared/upgrade-nudge/index.jsx | 30 +++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 6fd5a6ac8ed35..5df79247fbed3 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -1,28 +1,22 @@ /** * External dependencies */ -import React from 'react'; import { localize } from 'i18n-calypso'; import Gridicon from 'gridicons'; import './style.scss'; -class UpgradeNudge extends React.Component { - render() { - const { translate } = this.props; - return ( -
- -
- { translate( 'Upgrade to Premium' ) } - - { translate( 'To gain access to this block.' ) } - -
- -
- ); - } -} +const UpgradeNudge = ( { translate } ) => ( +
+ +
+ { translate( 'Upgrade to Premium' ) } + + { translate( 'To gain access to this block.' ) } + +
+ +
+); export default localize( UpgradeNudge ); From 3ab69018ca9a9735f2498b3945581f3cc5b99672 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:37:47 +0200 Subject: [PATCH 09/37] Use @wp/i18n --- extensions/shared/upgrade-nudge/index.jsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 5df79247fbed3..07af883b5a673 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -1,22 +1,18 @@ /** * External dependencies */ -import { localize } from 'i18n-calypso'; +import { __ } from '@wordpress/i18n'; import Gridicon from 'gridicons'; import './style.scss'; -const UpgradeNudge = ( { translate } ) => ( +export default () => (
- { translate( 'Upgrade to Premium' ) } - - { translate( 'To gain access to this block.' ) } - + { __( 'Upgrade to Premium' ) } + { __( 'To gain access to this block.' ) }
- +
); - -export default localize( UpgradeNudge ); From 03bb5e5406ddfc0c404ec712f8101727701acdec Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:41:35 +0200 Subject: [PATCH 10/37] Missed when renaming to wrap-paid-block --- extensions/editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/editor.js b/extensions/editor.js index c7259c8e70efa..bd8f31824de2c 100644 --- a/extensions/editor.js +++ b/extensions/editor.js @@ -3,4 +3,4 @@ */ import './shared/public-path'; import './shared/block-category'; -import './shared/wrap-premium-blocks'; +import './shared/wrap-paid-block'; From f721591f4a92e53f97d78bfa03f38514706a1cb4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:43:00 +0200 Subject: [PATCH 11/37] Use Button component --- extensions/shared/upgrade-nudge/index.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 07af883b5a673..2dee762dc9312 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -2,6 +2,7 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; import Gridicon from 'gridicons'; import './style.scss'; @@ -13,6 +14,6 @@ export default () => ( { __( 'Upgrade to Premium' ) } { __( 'To gain access to this block.' ) }
- +
); From 993bc53b6d405181eb33907b827abfa24aa713c8 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 13:58:09 +0200 Subject: [PATCH 12/37] Parametrize for requiredPlan --- extensions/shared/register-jetpack-block.js | 6 ++++-- extensions/shared/upgrade-nudge/index.jsx | 10 +++++++--- extensions/shared/wrap-paid-block.jsx | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index 80df117edb30e..662e56b94b2db 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -31,7 +31,9 @@ function requiresPlan( unavailableReason ) { export default function registerJetpackBlock( name, settings, childBlocks = [] ) { const { available, unavailableReason } = getJetpackExtensionAvailability( name ); - if ( ! available && ! requiresPlan( unavailableReason ) ) { + const requiredPlan = requiresPlan( unavailableReason ); + + if ( ! available && ! requiredPlan ) { if ( 'production' !== process.env.NODE_ENV ) { // eslint-disable-next-line no-console console.warn( @@ -44,7 +46,7 @@ export default function registerJetpackBlock( name, settings, childBlocks = [] ) const result = registerBlockType( `jetpack/${ name }`, { ...settings, title: betaExtensions.includes( name ) ? `${ settings.title } (beta)` : settings.title, - edit: requiresPlan( unavailableReason ) ? wrapPaidBlock( settings.edit ) : settings.edit, + edit: requiredPlan ? wrapPaidBlock( settings.edit, requiredPlan ) : settings.edit, } ); // Register child blocks. Using `registerBlockType()` directly avoids availability checks -- if diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 2dee762dc9312..439c57b6002fc 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -1,17 +1,21 @@ /** * External dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; import Gridicon from 'gridicons'; import './style.scss'; -export default () => ( +export default ( { requiredPlan } ) => (
- { __( 'Upgrade to Premium' ) } + + { sprintf( __( 'You need at least the following plan: %(requiredPlan)s', 'jetpack' ), { + requiredPlan, + } ) } + { __( 'To gain access to this block.' ) }
diff --git a/extensions/shared/wrap-paid-block.jsx b/extensions/shared/wrap-paid-block.jsx index dafac48ee5fce..970e61aad50ab 100644 --- a/extensions/shared/wrap-paid-block.jsx +++ b/extensions/shared/wrap-paid-block.jsx @@ -3,10 +3,10 @@ */ import UpgradeNudge from './upgrade-nudge'; -export default WrappedComponent => props => ( +export default ( WrappedComponent, requiredPlan ) => props => ( // Wraps the input component in a container, without mutating it. Good!
- +
From 9894bd653d6f16a5ccd61e7b29126f0bdf672eaa Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 23:34:05 +0200 Subject: [PATCH 13/37] Point button to plans page --- extensions/shared/register-jetpack-block.js | 8 +++++++- extensions/shared/upgrade-nudge/index.jsx | 18 +++++++++++++++--- extensions/shared/wrap-paid-block.jsx | 4 ++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index 662e56b94b2db..07a801ebc4b47 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -20,6 +20,10 @@ function requiresPlan( unavailableReason ) { return false; } +const blockFeatureMap = { + 'simple-payments': 'simple-payments', +}; + /** * Registers a gutenberg block if the availability requirements are met. * @@ -46,7 +50,9 @@ export default function registerJetpackBlock( name, settings, childBlocks = [] ) const result = registerBlockType( `jetpack/${ name }`, { ...settings, title: betaExtensions.includes( name ) ? `${ settings.title } (beta)` : settings.title, - edit: requiredPlan ? wrapPaidBlock( settings.edit, requiredPlan ) : settings.edit, + edit: requiredPlan + ? wrapPaidBlock( settings.edit, { feature: blockFeatureMap[ name ], requiredPlan } ) + : settings.edit, } ); // Register child blocks. Using `registerBlockType()` directly avoids availability checks -- if diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 439c57b6002fc..a9fcadd9a031d 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -2,13 +2,19 @@ * External dependencies */ import { __, sprintf } from '@wordpress/i18n'; +import { addQueryArgs } from '@wordpress/url'; import { Button } from '@wordpress/components'; import Gridicon from 'gridicons'; +/** + * Internal dependencies + */ +import getSiteFragment from '../get-site-fragment'; + import './style.scss'; -export default ( { requiredPlan } ) => ( -
+export default ( { requiredPlan, feature } ) => ( +
@@ -18,6 +24,12 @@ export default ( { requiredPlan } ) => ( { __( 'To gain access to this block.' ) }
- +
); diff --git a/extensions/shared/wrap-paid-block.jsx b/extensions/shared/wrap-paid-block.jsx index 970e61aad50ab..4ddeaacd0b15b 100644 --- a/extensions/shared/wrap-paid-block.jsx +++ b/extensions/shared/wrap-paid-block.jsx @@ -3,10 +3,10 @@ */ import UpgradeNudge from './upgrade-nudge'; -export default ( WrappedComponent, requiredPlan ) => props => ( +export default ( WrappedComponent, { feature, requiredPlan } ) => props => ( // Wraps the input component in a container, without mutating it. Good!
- +
From cde52f8328a5b1539108bffa64f4582de82b50a9 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 23:44:16 +0200 Subject: [PATCH 14/37] Change prop name to plan --- extensions/shared/upgrade-nudge/index.jsx | 6 ++---- extensions/shared/wrap-paid-block.jsx | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index a9fcadd9a031d..bb17ec14d601f 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -13,14 +13,12 @@ import getSiteFragment from '../get-site-fragment'; import './style.scss'; -export default ( { requiredPlan, feature } ) => ( +export default ( { feature, plan } ) => (
- { sprintf( __( 'You need at least the following plan: %(requiredPlan)s', 'jetpack' ), { - requiredPlan, - } ) } + { sprintf( __( 'You need at least the following plan: %(plan)s', 'jetpack' ), { plan } ) } { __( 'To gain access to this block.' ) }
diff --git a/extensions/shared/wrap-paid-block.jsx b/extensions/shared/wrap-paid-block.jsx index 4ddeaacd0b15b..a5c19c811ce2b 100644 --- a/extensions/shared/wrap-paid-block.jsx +++ b/extensions/shared/wrap-paid-block.jsx @@ -6,7 +6,7 @@ import UpgradeNudge from './upgrade-nudge'; export default ( WrappedComponent, { feature, requiredPlan } ) => props => ( // Wraps the input component in a container, without mutating it. Good!
- +
From b0ce0be7ecffa8178ef5cecfbeb289873761c26e Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 24 Jun 2019 23:51:49 +0200 Subject: [PATCH 15/37] Pass plan qarg --- extensions/shared/upgrade-nudge/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index bb17ec14d601f..101017a62c985 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -24,7 +24,7 @@ export default ( { feature, plan } ) => (
); +export default withSelect( ( select, { plan } ) => { + const plans = select( 'wordpress-com/plans' ).getPlan(); + console.log( plan, plans ); + return { plans }; +} )( UpgradeNudge ); diff --git a/extensions/shared/upgrade-nudge/store.js b/extensions/shared/upgrade-nudge/store.js new file mode 100644 index 0000000000000..e0905505c25a2 --- /dev/null +++ b/extensions/shared/upgrade-nudge/store.js @@ -0,0 +1,54 @@ +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { registerStore } from '@wordpress/data'; + +const actions = { + setPlans( plans ) { + return { + type: 'SET_PLANS', + plans, + }; + }, + + fetchFromAPI( url ) { + return { + type: 'FETCH_FROM_API', + url, + }; + }, +}; + +registerStore( 'wordpress-com/plans', { + reducer( state = {}, action ) { + switch ( action.type ) { + case 'SET_PLANS': + return action.plans; + } + + return state; + }, + + actions, + + selectors: { + getPlan( state ) { + return state; // TODO: Find and return plan by planSlug + }, + }, + + controls: { + FETCH_FROM_API( { url } ) { + return apiFetch( { url } ); + }, + }, + + resolvers: { + *getPlan() { + const url = 'https://public-api.wordpress.com/rest/v1.5/plans'; + const plans = yield actions.fetchFromAPI( url ); + return actions.setPlans( plans ); + }, + }, +} ); From 4ec054f7fb7e55a097d6c099ed9a13e59838c70a Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Fri, 28 Jun 2019 13:32:13 +0200 Subject: [PATCH 23/37] Fix CORS issue --- extensions/shared/upgrade-nudge/store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/shared/upgrade-nudge/store.js b/extensions/shared/upgrade-nudge/store.js index e0905505c25a2..84e306ae54373 100644 --- a/extensions/shared/upgrade-nudge/store.js +++ b/extensions/shared/upgrade-nudge/store.js @@ -40,7 +40,7 @@ registerStore( 'wordpress-com/plans', { controls: { FETCH_FROM_API( { url } ) { - return apiFetch( { url } ); + return apiFetch( { url, credentials: 'omit', mode: 'no-cors' } ); }, }, From c8029269a4ee6bc126fd072d1e00043f7871d6cd Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 11:22:15 +0600 Subject: [PATCH 24/37] _Finally_ fix that CORS issue --- extensions/shared/upgrade-nudge/store.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/shared/upgrade-nudge/store.js b/extensions/shared/upgrade-nudge/store.js index 84e306ae54373..e1de50c17b9da 100644 --- a/extensions/shared/upgrade-nudge/store.js +++ b/extensions/shared/upgrade-nudge/store.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import apiFetch from '@wordpress/api-fetch'; import { registerStore } from '@wordpress/data'; const actions = { @@ -40,7 +39,11 @@ registerStore( 'wordpress-com/plans', { controls: { FETCH_FROM_API( { url } ) { - return apiFetch( { url, credentials: 'omit', mode: 'no-cors' } ); + // We cannot use `@wordpress/api-fetch` here since it unconditionally sends + // the `X-WP-Nonce` header, which is disallowed by WordPress.com + return fetch( url, { credentials: 'same-origin', mode: 'cors' } ).then( response => + response.json() + ); }, }, From 10d28ca02d6d02e65e5e01b6ef5ab3de45bb44b1 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 11:42:19 +0600 Subject: [PATCH 25/37] Return plan object --- extensions/shared/upgrade-nudge/index.jsx | 14 ++++++++------ extensions/shared/upgrade-nudge/store.js | 6 +++--- modules/simple-payments/simple-payments.php | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index 73f6c06626ce9..d7b2b96809d06 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -1,6 +1,7 @@ /** * External dependencies */ +import { get } from 'lodash'; import { __, sprintf } from '@wordpress/i18n'; import { addQueryArgs } from '@wordpress/url'; import { Button } from '@wordpress/components'; @@ -15,12 +16,14 @@ import './store'; import './style.scss'; -const UpgradeNudge = ( { feature, plan } ) => ( +const UpgradeNudge = ( { feature, plan, planName } ) => (
- { sprintf( __( 'You need at least the following plan: %(plan)s', 'jetpack' ), { plan } ) } + { sprintf( __( 'You need at least the following plan: %(planName)s', 'jetpack' ), { + planName, + } ) } { __( 'To gain access to this block.' ) }
@@ -36,8 +39,7 @@ const UpgradeNudge = ( { feature, plan } ) => (
); -export default withSelect( ( select, { plan } ) => { - const plans = select( 'wordpress-com/plans' ).getPlan(); - console.log( plan, plans ); - return { plans }; +export default withSelect( ( select, { plan: planSlug } ) => { + const plan = select( 'wordpress-com/plans' ).getPlan( planSlug ); + return { planName: get( plan, [ 'product_name_short' ] ) }; } )( UpgradeNudge ); diff --git a/extensions/shared/upgrade-nudge/store.js b/extensions/shared/upgrade-nudge/store.js index e1de50c17b9da..80ce09f4fa667 100644 --- a/extensions/shared/upgrade-nudge/store.js +++ b/extensions/shared/upgrade-nudge/store.js @@ -20,7 +20,7 @@ const actions = { }; registerStore( 'wordpress-com/plans', { - reducer( state = {}, action ) { + reducer( state = [], action ) { switch ( action.type ) { case 'SET_PLANS': return action.plans; @@ -32,8 +32,8 @@ registerStore( 'wordpress-com/plans', { actions, selectors: { - getPlan( state ) { - return state; // TODO: Find and return plan by planSlug + getPlan( state, planSlug ) { + return state.find( plan => plan.product_slug === planSlug ); }, }, diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index bed99e5403227..a32c3b63342ff 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -68,7 +68,7 @@ function register_gutenberg_block() { 'jetpack/simple-payments', 'missing_plan', array( - 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'premium' : 'jetpack_premium' + 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' ) ); } From b0c395f74f2998c015101bba0533ec3df5c84473 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 13:57:53 +0600 Subject: [PATCH 26/37] Have endpoint communicate required_feature --- extensions/shared/register-jetpack-block.js | 6 +----- modules/simple-payments/simple-payments.php | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/extensions/shared/register-jetpack-block.js b/extensions/shared/register-jetpack-block.js index 083dbb6bfb8a7..06bbd9263163a 100644 --- a/extensions/shared/register-jetpack-block.js +++ b/extensions/shared/register-jetpack-block.js @@ -19,10 +19,6 @@ function requiresPlan( unavailableReason, details ) { return false; } -const blockFeatureMap = { - 'simple-payments': 'simple-payments', -}; - /** * Registers a gutenberg block if the availability requirements are met. * @@ -50,7 +46,7 @@ export default function registerJetpackBlock( name, settings, childBlocks = [] ) ...settings, title: betaExtensions.includes( name ) ? `${ settings.title } (beta)` : settings.title, edit: requiredPlan - ? wrapPaidBlock( { feature: blockFeatureMap[ name ], requiredPlan } )( settings.edit ) + ? wrapPaidBlock( { feature: details.required_feature, requiredPlan } )( settings.edit ) : settings.edit, } ); diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index a32c3b63342ff..becc6a2a1712e 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -68,8 +68,8 @@ function register_gutenberg_block() { 'jetpack/simple-payments', 'missing_plan', array( - 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' - ) + 'required_feature' => 'simple-payments', + 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' ) ); } } From c64d6d5f02fb018f847afff295e83dfc20669206 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 14:05:57 +0600 Subject: [PATCH 27/37] Drop unnecessary defaults --- extensions/shared/upgrade-nudge/store.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/extensions/shared/upgrade-nudge/store.js b/extensions/shared/upgrade-nudge/store.js index 80ce09f4fa667..a7cf15bf2b174 100644 --- a/extensions/shared/upgrade-nudge/store.js +++ b/extensions/shared/upgrade-nudge/store.js @@ -40,10 +40,11 @@ registerStore( 'wordpress-com/plans', { controls: { FETCH_FROM_API( { url } ) { // We cannot use `@wordpress/api-fetch` here since it unconditionally sends - // the `X-WP-Nonce` header, which is disallowed by WordPress.com - return fetch( url, { credentials: 'same-origin', mode: 'cors' } ).then( response => - response.json() - ); + // the `X-WP-Nonce` header, which is disallowed by WordPress.com. + // (To reproduce, note that you need to call `apiFetch` with ` + // `{ credentials: 'same-origin', mode: 'cors' }`, since its defaults are + // different from `fetch`'s.) + return fetch( url ).then( response => response.json() ); }, }, From 9ed7fe9cea8eb73b3bceee153b5e879cfa16919c Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 16:42:38 +0600 Subject: [PATCH 28/37] Whitespace :facepalm: --- modules/simple-payments/simple-payments.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index becc6a2a1712e..da9a73e7d6c6a 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -69,7 +69,8 @@ function register_gutenberg_block() { 'missing_plan', array( 'required_feature' => 'simple-payments', - 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' ) + 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' + ) ); } } From c871c9923ae2e7be3dbb90359307931a2cc8e80b Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 16:46:09 +0600 Subject: [PATCH 29/37] Feature-flag --- modules/simple-payments/simple-payments.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/simple-payments/simple-payments.php b/modules/simple-payments/simple-payments.php index da9a73e7d6c6a..2f4110ab07400 100644 --- a/modules/simple-payments/simple-payments.php +++ b/modules/simple-payments/simple-payments.php @@ -64,12 +64,13 @@ function register_gutenberg_block() { if ( $this->is_enabled_jetpack_simple_payments() ) { jetpack_register_block( 'jetpack/simple-payments' ); } else { + $required_plan = ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium'; Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/simple-payments', 'missing_plan', array( 'required_feature' => 'simple-payments', - 'required_plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium' + 'required_plan' => ( defined( 'SHOW_BLOCK_UPGRADE_NUDGE' ) && SHOW_BLOCK_UPGRADE_NUDGE ) ? $required_plan : false ) ); } From 9669ec3cfcdd81e7035d37995cd9c35f2f285ae8 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Mon, 1 Jul 2019 17:16:05 +0600 Subject: [PATCH 30/37] Copy --- extensions/shared/upgrade-nudge/index.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index d7b2b96809d06..65defb64dc6d5 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -21,11 +21,13 @@ const UpgradeNudge = ( { feature, plan, planName } ) => (
- { sprintf( __( 'You need at least the following plan: %(planName)s', 'jetpack' ), { + { sprintf( __( 'Upgrade to %(planName)s', 'jetpack' ), { planName, } ) } - { __( 'To gain access to this block.' ) } + + { __( 'To make this block visible on your site' ) } +
); From 1157ae64ffcde14b7866e0778be00534874663cb Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 2 Jul 2019 16:52:25 +0600 Subject: [PATCH 33/37] Dedicated stylesheet and directory for wrap-paid-block --- extensions/shared/upgrade-nudge/style.scss | 9 --------- .../{wrap-paid-block.jsx => wrap-paid-block/index.jsx} | 4 +++- extensions/shared/wrap-paid-block/style.scss | 8 ++++++++ 3 files changed, 11 insertions(+), 10 deletions(-) rename extensions/shared/{wrap-paid-block.jsx => wrap-paid-block/index.jsx} (88%) create mode 100644 extensions/shared/wrap-paid-block/style.scss diff --git a/extensions/shared/upgrade-nudge/style.scss b/extensions/shared/upgrade-nudge/style.scss index ce92fccc45ce4..2a1ea43199fd2 100644 --- a/extensions/shared/upgrade-nudge/style.scss +++ b/extensions/shared/upgrade-nudge/style.scss @@ -1,12 +1,3 @@ -.paid-block__wrapper { - border: 1px solid var( --color-border-subtle ); -} - -.paid-block__disabled { - opacity: 0.5; - padding: 10px; -} - .upgrade-nudge { border-left: 3px solid var( --color-plan-premium ); box-shadow: 0 0 0 1px var( --color-border-subtle ); diff --git a/extensions/shared/wrap-paid-block.jsx b/extensions/shared/wrap-paid-block/index.jsx similarity index 88% rename from extensions/shared/wrap-paid-block.jsx rename to extensions/shared/wrap-paid-block/index.jsx index b0781659edec8..d0d0d518facec 100644 --- a/extensions/shared/wrap-paid-block.jsx +++ b/extensions/shared/wrap-paid-block/index.jsx @@ -7,7 +7,9 @@ import { createHigherOrderComponent } from '@wordpress/compose'; /** * Internal dependencies */ -import UpgradeNudge from './upgrade-nudge'; +import UpgradeNudge from '../upgrade-nudge'; + +import './style.scss'; export default ( { feature, requiredPlan } ) => createHigherOrderComponent( diff --git a/extensions/shared/wrap-paid-block/style.scss b/extensions/shared/wrap-paid-block/style.scss new file mode 100644 index 0000000000000..a91a65a636b45 --- /dev/null +++ b/extensions/shared/wrap-paid-block/style.scss @@ -0,0 +1,8 @@ +.paid-block__wrapper { + border: 1px solid var( --color-border-subtle ); +} + +.paid-block__disabled { + opacity: 0.5; + padding: 10px; +} From 4d6617bfd48682f884a8eaee16424be9c443ed96 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 2 Jul 2019 17:19:29 +0600 Subject: [PATCH 34/37] Prefix with jetpack- --- extensions/shared/upgrade-nudge/index.jsx | 12 ++++++------ extensions/shared/upgrade-nudge/style.scss | 10 +++++----- extensions/shared/wrap-paid-block/index.jsx | 4 ++-- extensions/shared/wrap-paid-block/style.scss | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/extensions/shared/upgrade-nudge/index.jsx b/extensions/shared/upgrade-nudge/index.jsx index b713f9370f862..b88b97cdc7b5f 100644 --- a/extensions/shared/upgrade-nudge/index.jsx +++ b/extensions/shared/upgrade-nudge/index.jsx @@ -17,20 +17,20 @@ import './store'; import './style.scss'; const UpgradeNudge = ( { feature, plan, planName } ) => ( -
- -
- +
+ +
+ { sprintf( __( 'Upgrade to %(planName)s', 'jetpack' ), { planName, } ) } - + { __( 'To make this block visible on your site', 'jetpack' ) }