From 673275015a79063fb2cb01d91657499397de8a72 Mon Sep 17 00:00:00 2001 From: Jacopo Tomasone Date: Tue, 18 Feb 2020 16:21:11 +0000 Subject: [PATCH] Add the WPCOM Block Editor NUX (#38511) * Add a new WPCOM NUX plugin * Simplify the API handling * Improve code readability * REST fixes * Improve the state persistence and use modern PHP array notation * added welcomeGuide check * added disable for welcomeGuide * commented out nux loader Co-authored-by: Addison Stavlo --- .../full-site-editing-plugin.php | 9 ++ ...com-block-editor-nux-status-controller.php | 94 +++++++++++++++++++ .../class-wpcom-block-editor-nux.php | 65 +++++++++++++ .../wpcom-block-editor-nux/index.js | 6 ++ .../src/disable-core-nux.js | 27 ++++++ .../wpcom-block-editor-nux/src/store.js | 36 +++++++ .../wpcom-block-editor-nux/src/wpcom-nux.js | 86 +++++++++++++++++ apps/full-site-editing/package.json | 3 + 8 files changed, 326 insertions(+) create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wp-rest-wpcom-block-editor-nux-status-controller.php create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wpcom-block-editor-nux.php create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/index.js create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/disable-core-nux.js create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/store.js create mode 100644 apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/wpcom-nux.js diff --git a/apps/full-site-editing/full-site-editing-plugin/full-site-editing-plugin.php b/apps/full-site-editing/full-site-editing-plugin/full-site-editing-plugin.php index fb15ac9ea05d8..954fc51808ddb 100644 --- a/apps/full-site-editing/full-site-editing-plugin/full-site-editing-plugin.php +++ b/apps/full-site-editing/full-site-editing-plugin/full-site-editing-plugin.php @@ -215,3 +215,12 @@ function load_blog_posts_block() { require_once __DIR__ . '/blog-posts-block/index.php'; } add_action( 'plugins_loaded', __NAMESPACE__ . '\load_blog_posts_block' ); + +// @TODO - Uncomment once ready to deploy wpcom NUX. +/** + * Load WPCOM Block Editor NUX + */ +// function load_wpcom_block_editor_nux() { +// require_once __DIR__ . '/wpcom-block-editor-nux/class-wpcom-block-editor-nux.php'; +// } +// add_action( 'plugins_loaded', __NAMESPACE__ . '\load_wpcom_block_editor_nux' ); diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wp-rest-wpcom-block-editor-nux-status-controller.php b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wp-rest-wpcom-block-editor-nux-status-controller.php new file mode 100644 index 0000000000000..9d6d85c1899ab --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wp-rest-wpcom-block-editor-nux-status-controller.php @@ -0,0 +1,94 @@ +namespace = 'wpcom/v2'; + $this->rest_base = 'block-editor/nux'; + } + + /** + * Register available routes. + */ + public function register_rest_route() { + register_rest_route( + $this->namespace, + $this->rest_base, + array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_nux_status' ), + 'permission_callback' => array( $this, 'permission_callback' ), + ), + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_nux_status' ), + 'permission_callback' => array( $this, 'permission_callback' ), + ), + ) + ); + } + + /** + * Callback to determine whether the request can proceed. + * + * @return boolean + */ + public function permission_callback() { + return is_user_logged_in(); + } + + /** + * Check if NUX is enabled. + * + * @param mixed $nux_status Can be "enabled", "dismissed", or undefined. + * @return boolean + */ + public function is_nux_enabled( $nux_status ) { + return 'enabled' === $nux_status; + } + + /** + * Return the WPCOM NUX status + * + * @return WP_REST_Response + */ + public function get_nux_status() { + if ( has_filter( 'wpcom_block_editor_nux_get_status' ) ) { + $nux_status = apply_filters( 'wpcom_block_editor_nux_get_status', false ); + } elseif ( ! metadata_exists( 'user', get_current_user_id(), 'wpcom_block_editor_nux_status' ) ) { + $nux_status = 'enabled'; + } else { + $nux_status = get_user_meta( get_current_user_id(), 'wpcom_block_editor_nux_status', true ); + } + return rest_ensure_response( array( 'is_nux_enabled' => $this->is_nux_enabled( $nux_status ) ) ); + } + + /** + * Update the WPCOM NUX status + * + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function update_nux_status( $request ) { + $params = $request->get_json_params(); + $nux_status = $params['isNuxEnabled'] ? 'enabled' : 'dismissed'; + if ( has_action( 'wpcom_block_editor_nux_update_status' ) ) { + do_action( 'wpcom_block_editor_nux_update_status', $nux_status ); + } + update_user_meta( get_current_user_id(), 'wpcom_block_editor_nux_status', $nux_status ); + return rest_ensure_response( array( 'is_nux_enabled' => $this->is_nux_enabled( $nux_status ) ) ); + } +} diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wpcom-block-editor-nux.php b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wpcom-block-editor-nux.php new file mode 100644 index 0000000000000..3b8e2f3cf39a0 --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/class-wpcom-block-editor-nux.php @@ -0,0 +1,65 @@ +register_rest_route(); + } +} +add_action( 'init', array( __NAMESPACE__ . '\WPCOM_Block_Editor_NUX', 'init' ) ); diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/index.js b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/index.js new file mode 100644 index 0000000000000..5188282e23d73 --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/index.js @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import './src/store'; +import './src/disable-core-nux'; +import './src/wpcom-nux'; diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/disable-core-nux.js b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/disable-core-nux.js new file mode 100644 index 0000000000000..531cc0e4cb8d3 --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/disable-core-nux.js @@ -0,0 +1,27 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/** + * External dependencies + */ +import { select, dispatch, subscribe } from '@wordpress/data'; +import '@wordpress/nux'; //ensure nux store loads + +// Disable nux and welcome guide features from core. +const unsubscribe = subscribe( () => { + dispatch( 'core/nux' ).disableTips(); + if ( select( 'core/edit-post' ).isFeatureActive( 'welcomeGuide' ) ) { + dispatch( 'core/edit-post' ).toggleFeature( 'welcomeGuide' ); + } + unsubscribe(); +} ); + +// Listen for these features being triggered to call dotcom nux instead. +subscribe( () => { + if ( select( 'core/nux' ).areTipsEnabled() ) { + dispatch( 'core/nux' ).disableTips(); + dispatch( 'automattic/nux' ).setWpcomNuxStatus( { isNuxEnabled: true } ); + } + if ( select( 'core/edit-post' ).isFeatureActive( 'welcomeGuide' ) ) { + dispatch( 'core/edit-post' ).toggleFeature( 'welcomeGuide' ); + dispatch( 'automattic/nux' ).setWpcomNuxStatus( { isNuxEnabled: true } ); + } +} ); diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/store.js b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/store.js new file mode 100644 index 0000000000000..c8bbbfc8a80dc --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/store.js @@ -0,0 +1,36 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { registerStore } from '@wordpress/data'; + +const reducer = ( state = {}, { type, isNuxEnabled } ) => + 'WPCOM_BLOCK_EDITOR_NUX_SET_STATUS' === type ? { ...state, isNuxEnabled } : state; + +const actions = { + setWpcomNuxStatus: ( { isNuxEnabled, bypassApi } ) => { + if ( ! bypassApi ) { + apiFetch( { + path: '/wpcom/v2/block-editor/nux', + method: 'POST', + data: { isNuxEnabled }, + } ); + } + return { + type: 'WPCOM_BLOCK_EDITOR_NUX_SET_STATUS', + isNuxEnabled, + }; + }, +}; + +const selectors = { + isWpcomNuxEnabled: state => state.isNuxEnabled, +}; + +registerStore( 'automattic/nux', { + reducer, + actions, + selectors, + persist: true, +} ); diff --git a/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/wpcom-nux.js b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/wpcom-nux.js new file mode 100644 index 0000000000000..1ad4b35351d11 --- /dev/null +++ b/apps/full-site-editing/full-site-editing-plugin/wpcom-block-editor-nux/src/wpcom-nux.js @@ -0,0 +1,86 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable wpcalypso/jsx-classname-namespace */ +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { Guide, GuidePage } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { useEffect, __experimentalCreateInterpolateElement } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { registerPlugin } from '@wordpress/plugins'; + +function WpcomNux() { + const isWpcomNuxEnabled = useSelect( select => select( 'automattic/nux' ).isWpcomNuxEnabled() ); + const { setWpcomNuxStatus } = useDispatch( 'automattic/nux' ); + + // On mount check if the WPCOM NUX status exists in state, otherwise fetch it from the API. + useEffect( () => { + if ( typeof isWpcomNuxEnabled !== 'undefined' ) { + return; + } + const fetchWpcomNuxStatus = async () => { + const response = await apiFetch( { path: '/wpcom/v2/block-editor/nux' } ); + setWpcomNuxStatus( { isNuxEnabled: response.is_nux_enabled, bypassApi: true } ); + }; + fetchWpcomNuxStatus(); + }, [ isWpcomNuxEnabled, setWpcomNuxStatus ] ); + + if ( ! isWpcomNuxEnabled ) { + return null; + } + + const dismissWpcomNux = () => setWpcomNuxStatus( { isNuxEnabled: false } ); + + return ( + + +

+ { __( 'Welcome to the Block Editor' ) } +

+

+ { __( + 'In the WordPress editor, each paragraph, image, or video is presented as a distinct “block” of content.' + ) } +

+
+ +

{ __( 'Make each block your own' ) }

+

+ { __( + 'Each block comes with its own set of controls for changing things like color, width, and alignment. These will show and hide automatically when you have a block selected.' + ) } +

+
+ +

+ { __( 'Get to know the Block Library' ) } +

+

+ { __experimentalCreateInterpolateElement( + __( + 'All of the blocks available to you live in the Block Library. You’ll find it wherever you see the icon.' + ), + { + InserterIconImage: ( + { + ), + } + ) } +

+
+
+ ); +} + +registerPlugin( 'wpcom-block-editor-nux', { + render: () => , +} ); diff --git a/apps/full-site-editing/package.json b/apps/full-site-editing/package.json index 3f1e48c8a1044..594623f904a77 100644 --- a/apps/full-site-editing/package.json +++ b/apps/full-site-editing/package.json @@ -33,6 +33,9 @@ "global-styles": "calypso-build --source='global-styles'", "build:global-styles": "NODE_ENV=production npm run global-styles", "dev:global-styles": "npm run global-styles", + "wpcom-block-editor-nux": "calypso-build --source='wpcom-block-editor-nux'", + "dev:wpcom-block-editor-nux": "npm run wpcom-block-editor-nux", + "build:wpcom-block-editor-nux": "NODE_ENV=production npm run wpcom-block-editor-nux", "dev": "node bin/npm-run-build.js --dev", "build": "node bin/npm-run-build.js --build", "test:js": "npx wp-scripts test-unit-js --config='bin/js-unit-config.js'",