Skip to content
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

Handle the site_icon_maskable setting within a full-site-editing context #919

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
},
"scripts": {
"build": "grunt build; grunt create-build-zip",
"blocks:build": "wp-scripts build",
"blocks:start": "wp-scripts start",
"check-engines": "wp-scripts check-engines",
"check-licenses": "wp-scripts check-licenses --production",
"deploy": "grunt deploy",
Expand Down
3 changes: 3 additions & 0 deletions pwa.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ function _pwa_check_disabled_navigation_preload() {
/** Hooks to add for when accessing admin. */
require_once PWA_PLUGIN_DIR . '/wp-admin/admin.php';

/** Function to register maskable icon setting as 'core/site-logo'-block filter */
require_once PWA_PLUGIN_DIR . '/site-icon-maskable/site-icon-maskable-block-editor.php';

/**
* Plugin activation hook.
*/
Expand Down
45 changes: 45 additions & 0 deletions site-icon-maskable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* The 'icon maskable' control allows to set the 'site_icon_maskable' option.
*
* It also provides a small preview of the image used as Site-Logo,
* using a cropping-preview to illustrate the safe space an logo needs
* to be an adaptive image.
*/
import MaskableControls from './maskable-icon-controls';

/**
* The compose package is a collection
* of handy Hooks and Higher Order Components (HOCs)
* you can use to wrap your WordPress components
* and provide some basic features like: state, instance id, pure…
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-compose/
*/
import { createHigherOrderComponent } from '@wordpress/compose';

const withMaskableControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.name !== 'core/site-logo') {
return <BlockEdit {...props} />;
}

return (
<>
<BlockEdit {...props} />
<MaskableControls />
</>
);
};
}, 'withMaskableControls');

/**
* To modify the behavior of existing blocks,
* WordPress exposes several APIs.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/
*/
wp.hooks.addFilter(
'editor.BlockEdit',
'pwa/with-maskable-icon-controls',
withMaskableControls
);
116 changes: 116 additions & 0 deletions site-icon-maskable/maskable-icon-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/packages/packages-i18n/
*/
import { __ } from '@wordpress/i18n';

/**
* This module allows you to create and use standalone block editors. ;)
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/
*/
import { InspectorControls } from '@wordpress/block-editor';

/**
* This package includes a library of generic WordPress components
* to be used for creating common UI elements shared between screens
* and features of the WordPress dashboard.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-components/
*/
import {
// __experimentalHStack as HStack,
Flex,
FlexBlock,
FlexItem,
PanelBody,
ToggleControl,
} from '@wordpress/components';

/**
* Core Data is a data module intended to
* simplify access to and manipulation
* of core WordPress entities.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-core-data/
*/
import { store as coreStore, useEntityProp } from '@wordpress/core-data';

/**
* WordPress’ data module serves as a hub
* to manage application state
* for both plugins and WordPress itself.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-data/
*/
import { useSelect } from '@wordpress/data';

export default function MaskableControls() {
const [siteIconMaskable, setSiteIconMaskable] = useEntityProp(
'root',
'site',
'site_icon_maskable'
);

// mainly borrowed from ...
const { isRequestingSiteIcon, siteIconUrl } = useSelect((select) => {
const { getEntityRecord, isResolving } = select(coreStore);
const siteData =
getEntityRecord('root', '__unstableBase', undefined) || {};

return {
isRequestingSiteIcon: isResolving('getEntityRecord', [
'root',
'__unstableBase',
undefined,
]),
siteIconUrl: siteData.site_icon_url,
};
}, []);

if (isRequestingSiteIcon) {
return null;
}

const siteIconStyle = {
clipPath: siteIconMaskable ? 'inset(10% round 50%)' : '',
width: '64px',
};

let siteIcon = <div style={siteIconStyle} />;

if (siteIconUrl) {
siteIcon = (
<img
alt={__('Site Icon')}
className="components-site-icon"
src={siteIconUrl}
width={64}
height={64}
style={siteIconStyle}
/>
);
}

return (
<InspectorControls>
<PanelBody>
<Flex align="start">
<FlexBlock>
<ToggleControl
label={__('Maskable icon', 'pwa')}
help={__(
'Maskable icons let your Progressive Web App use adaptive icons. If you supply a maskable icon, your icon can fill up the entire shape as an app- or homescreen-icon and will look great on all devices.',
'pwa'
)}
onChange={setSiteIconMaskable}
checked={siteIconMaskable}
/>
</FlexBlock>
<FlexItem>{siteIcon}</FlexItem>
</Flex>
</PanelBody>
</InspectorControls>
);
}
66 changes: 66 additions & 0 deletions site-icon-maskable/site-icon-maskable-block-editor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* Handles the 'site_icon_maskable' setting within a full-site-editing context
*
* @package PWA
*/

namespace PWA_WP;

use Error;

use function add_action;
use function plugins_url;
use function register_setting;
use function wp_enqueue_script;
use function wp_set_script_translations;

/**
* [pwa__enqueue_block_editor_assets description]
*
* @package PWA
* @since 0.8.0-alpha
* @throws Error Fatals out when the block-filter files weren't built.
*
* @see https://developer.wordpress.org/reference/hooks/enqueue_block_editor_assets/
*/
function enqueue_block_editor_assets__site_icon_maskable() {
carstingaxion marked this conversation as resolved.
Show resolved Hide resolved
$dir = __DIR__;

$script_asset_path = "$dir/../build/site-icon-maskable.asset.php";
if ( ! file_exists( $script_asset_path ) ) {
throw new Error(
'You need to run `npm run blocks:start` or `npm run blocks:build` first, for the "core/site-logo"-block filter to work.'
);
carstingaxion marked this conversation as resolved.
Show resolved Hide resolved
}
$index_js = '../build/site-icon-maskable.js';
$script_asset = require $script_asset_path;

wp_enqueue_script(
'pwa-site-icon-maskable-block-editor',
plugins_url( $index_js, __FILE__ ),
$script_asset['dependencies'],
$script_asset['version'],
true
);
wp_set_script_translations( 'pwa-site-icon-maskable-block-editor', 'pwa' );

}
add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\enqueue_block_editor_assets__site_icon_maskable' );

/**
* Register 'Site Icon maskable' setting.
*/
function register_setting__site_icon_maskable() {
register_setting(
'general',
'site_icon_maskable',
array(
'type' => 'boolean',
'show_in_rest' => true,
'sanitize_callback' => 'rest_sanitize_boolean',
)
);
}
add_action( 'rest_api_init', __NAMESPACE__ . '\\register_setting__site_icon_maskable' );
add_action( 'admin_init', __NAMESPACE__ . '\\register_setting__site_icon_maskable' );
7 changes: 7 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const defaultConfig = require('@wordpress/scripts/config/webpack.config');
module.exports = {
...defaultConfig,
entry: {
'site-icon-maskable': './site-icon-maskable',
},
};