Skip to content

Commit a53e5c8

Browse files
authored
Merge pull request #307 from material-components/fse/opt-in
Add FSE opt-in in customizer
2 parents 9f9d51b + 16d33c4 commit a53e5c8

File tree

23 files changed

+722
-143
lines changed

23 files changed

+722
-143
lines changed

plugin/assets/src/admin/get-config.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@
2323
* @return {string|Object|undefined} Value of config.
2424
*/
2525
const getConfig = name => {
26-
const configData = window.materialDesignWizard;
26+
const configData = window?.materialDesignWizard;
27+
28+
if ( undefined === configData ) {
29+
return undefined;
30+
}
31+
32+
return configData[ name ];
33+
};
34+
35+
export const getConfigTheme = name => {
36+
const configData = window?.materialDesignWizardTheme;
2737

2838
if ( undefined === configData ) {
2939
return undefined;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
*
3+
* Copyright 2022 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* External dependencies
20+
*/
21+
import _uniqueId from 'lodash/uniqueId';
22+
23+
/**
24+
* WordPress dependencies
25+
*/
26+
import { __ } from '@wordpress/i18n';
27+
import { useState, useContext } from '@wordpress/element';
28+
29+
/**
30+
* Internal dependencies
31+
*/
32+
import { ACTIONS } from '../../constants';
33+
import SettingsContext from '../../context';
34+
import Switch from './switch';
35+
import { toggleFseOptIn } from '../../utils';
36+
37+
/**
38+
* @return {JSX.Element} JSX.
39+
*/
40+
const FseOptIn = () => {
41+
const [ id ] = useState( _uniqueId( 'updater-' ) );
42+
const { dispatch } = useContext( SettingsContext );
43+
const type = 'OPT_IN';
44+
const { state } = useContext( SettingsContext );
45+
46+
const checked = state.updaters.OPT_IN.autoUpdates;
47+
48+
const handleAutoUpdateToggle = async () => {
49+
dispatch( { type: ACTIONS.TOGGLE_UPDATES, payload: { type } } );
50+
51+
await toggleFseOptIn( ! checked );
52+
window.location.reload();
53+
};
54+
55+
return (
56+
<div className={ 'material-settings__updater no__last-update' }>
57+
<div className="mdc-layout-grid">
58+
<div className="mdc-layout-grid__inner">
59+
<div className="mdc-layout-grid__cell mdc-layout-grid__cell--span-10 mdc-layout-grid__cell--align-middle">
60+
<h3 className="mdc-typography--headline6">
61+
{ __(
62+
'Full Site Editing Opt In',
63+
'material-design'
64+
) }{ ' ' }
65+
</h3>
66+
67+
<p className="mdc-typography--body1">
68+
{ __(
69+
'This setting won’t be available when Full Site Editing is out of Beta and fully supported by WordPress.',
70+
'material-design'
71+
) }
72+
</p>
73+
</div>
74+
<div className="mdc-layout-grid__cell mdc-layout-grid__cell--span-2 mdc-layout-grid__cell--align-middle material-settings__cell--justify-end">
75+
<Switch
76+
checked={ checked }
77+
onChange={ handleAutoUpdateToggle }
78+
id={ id }
79+
showLabel={ false }
80+
/>
81+
</div>
82+
</div>
83+
</div>
84+
</div>
85+
);
86+
};
87+
88+
export default FseOptIn;

plugin/assets/src/settings/components/integrations/index.js

Lines changed: 83 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -29,89 +29,105 @@ import { useContext } from '@wordpress/element';
2929
* Internal dependencies
3030
*/
3131
import SettingsContext from '../../context';
32-
import { UPDATERS } from '../../constants';
32+
import { isPluginActive, UPDATERS, isThemeActive } from '../../constants';
3333
import Updater from './updater';
3434
import Api from './api';
35+
import FseOptIn from './fse-opt-in';
3536

3637
const Integrations = () => {
3738
const { state } = useContext( SettingsContext );
3839

3940
return (
4041
<div className="material-settings__integrations">
41-
<h2 className="mdc-typography--headline6">
42-
{ __( 'Integrations', 'material-design' ) }
43-
</h2>
42+
{ isPluginActive && (
43+
<>
44+
<h2 className="mdc-typography--headline6">
45+
{ __( 'Integrations', 'material-design' ) }
46+
</h2>
4447

45-
<p
46-
className="mdc-typography--body1"
47-
dangerouslySetInnerHTML={ {
48-
__html: sprintf(
49-
// translators: %1$s: google font anchor tag, %2$s material icon resources link.
50-
__(
51-
'Integrate %1$s and %1$s to get the most out of the Material Theme.',
52-
'material-design'
53-
),
54-
`<a href="https://fonts.google.com/" target="_blank" rel="noopener noreferrer">${ __(
55-
'Google Fonts',
56-
'material-design'
57-
) }</a>`,
58-
`<a href="https://material.io/resources/icons/?style=baseline" target="_blank" rel="noopener noreferrer">${ __(
59-
'Material icons',
60-
'material-design'
61-
) }</a>`
62-
),
63-
} }
64-
></p>
48+
<p
49+
className="mdc-typography--body1"
50+
dangerouslySetInnerHTML={ {
51+
__html: sprintf(
52+
// translators: %1$s: google font anchor tag, %2$s material icon resources link.
53+
__(
54+
'Integrate %1$s and %1$s to get the most out of the Material Theme.',
55+
'material-design'
56+
),
57+
`<a href="https://fonts.google.com/" target="_blank" rel="noopener noreferrer">${ __(
58+
'Google Fonts',
59+
'material-design'
60+
) }</a>`,
61+
`<a href="https://material.io/resources/icons/?style=baseline" target="_blank" rel="noopener noreferrer">${ __(
62+
'Material icons',
63+
'material-design'
64+
) }</a>`
65+
),
66+
} }
67+
/>
6568

66-
<p className="mdc-typography--body1">
67-
{ __(
68-
'Turn on auto-updater or update your resources manually.',
69-
'material-design'
70-
) }
71-
</p>
69+
<p className="mdc-typography--body1">
70+
{ __(
71+
'Turn on auto-updater or update your resources manually.',
72+
'material-design'
73+
) }
74+
</p>
75+
</>
76+
) }
7277

7378
<div className="material-settings__updates">
74-
{ Object.keys( UPDATERS ).map( key => (
75-
<Updater
76-
key={ uniqueId( 'updater-' ) }
77-
title={ UPDATERS[ key ].title }
78-
needsKey={ UPDATERS[ key ].needsKey }
79-
checked={ state.updaters[ key ].autoUpdates }
80-
lastUpdated={ state.updaters[ key ].lastUpdated }
81-
type={ UPDATERS[ key ].type }
82-
displayUpdatedOn={ UPDATERS[ key ].displayUpdatedOn }
83-
versionAvailable={ UPDATERS[ key ].versionAvailable }
84-
apiStatus={ state.apiStatus }
85-
updateAvailable={
86-
state.updaters[ UPDATERS[ key ].type ]
87-
.updateAvailable
88-
}
89-
/>
90-
) ) }
79+
{ Object.keys( UPDATERS ).map( key =>
80+
key === 'OPT_IN' ? null : (
81+
<Updater
82+
key={ uniqueId( 'updater-' ) }
83+
title={ UPDATERS[ key ].title }
84+
needsKey={ UPDATERS[ key ].needsKey }
85+
checked={ state.updaters[ key ].autoUpdates }
86+
lastUpdated={ state.updaters[ key ].lastUpdated }
87+
type={ UPDATERS[ key ].type }
88+
displayUpdatedOn={
89+
UPDATERS[ key ].displayUpdatedOn
90+
}
91+
versionAvailable={
92+
UPDATERS[ key ].versionAvailable
93+
}
94+
apiStatus={ state.apiStatus }
95+
updateAvailable={
96+
state.updaters[ UPDATERS[ key ].type ]
97+
.updateAvailable
98+
}
99+
/>
100+
)
101+
) }
102+
{ isThemeActive && <FseOptIn /> }
91103
</div>
92104

93-
<h2 className="mdc-typography--headline6">
94-
{ __( 'Google API Key', 'material-design' ) }
95-
</h2>
105+
{ isPluginActive && (
106+
<>
107+
<h2 className="mdc-typography--headline6">
108+
{ __( 'Google API Key', 'material-design' ) }
109+
</h2>
96110

97-
<p
98-
className="mdc-typography--body1"
99-
dangerouslySetInnerHTML={ {
100-
__html: sprintf(
101-
// translators: %s google api key anchor tag.
102-
__(
103-
'To use Google Fonts in Material Theme, please activate your %s and enable updates',
104-
'material-design'
105-
),
106-
`<a href="https://developers.google.com/fonts/docs/developer_api#APIKey" target="_blank" rel="noopener noreferrer">${ __(
107-
'Google API Key',
108-
'material-design'
109-
) }</a>`
110-
),
111-
} }
112-
></p>
111+
<p
112+
className="mdc-typography--body1"
113+
dangerouslySetInnerHTML={ {
114+
__html: sprintf(
115+
// translators: %s google api key anchor tag.
116+
__(
117+
'To use Google Fonts in Material Theme, please activate your %s and enable updates',
118+
'material-design'
119+
),
120+
`<a href="https://developers.google.com/fonts/docs/developer_api#APIKey" target="_blank" rel="noopener noreferrer">${ __(
121+
'Google API Key',
122+
'material-design'
123+
) }</a>`
124+
),
125+
} }
126+
/>
113127

114-
<Api apiStatus={ state.apiStatus } />
128+
<Api apiStatus={ state.apiStatus } />
129+
</>
130+
) }
115131
</div>
116132
);
117133
};

plugin/assets/src/settings/components/integrations/switch.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { MDCSwitch } from '@material/switch';
2626
import { __ } from '@wordpress/i18n';
2727
import { useEffect } from '@wordpress/element';
2828

29-
const Switch = ( { checked, id, onChange } ) => {
29+
const Switch = ( { checked, id, onChange, showLabel = true } ) => {
3030
useEffect( () => {
3131
const mdcSwitches = document.querySelectorAll( '.mdc-switch' );
3232

@@ -58,9 +58,11 @@ const Switch = ( { checked, id, onChange } ) => {
5858
/>
5959
</div>
6060
</div>
61-
<label id={ `label-${ id }` } htmlFor={ id }>
62-
{ __( 'Auto-updates enabled', 'material-design' ) }
63-
</label>
61+
{ showLabel && (
62+
<label id={ `label-${ id }` } htmlFor={ id }>
63+
{ __( 'Auto-updates enabled', 'material-design' ) }
64+
</label>
65+
) }
6466
</div>
6567
);
6668
};

plugin/assets/src/settings/components/integrations/updater.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ const Updater = ( {
134134
) }</a>`
135135
),
136136
} }
137-
></p>
137+
/>
138138
) }
139139

140140
{ ! isDisabled && false !== displayUpdatedOn && (

plugin/assets/src/settings/constants.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { __ } from '@wordpress/i18n';
2222
/**
2323
* Internal dependencies
2424
*/
25-
import getConfig from '../admin/get-config';
25+
import getConfig, { getConfigTheme } from '../admin/get-config';
2626

2727
export const ACTIONS = {
2828
ADD_ERROR: 'ADD_ERROR',
@@ -34,7 +34,7 @@ export const ACTIONS = {
3434
SET_UPDATED: 'SET_UPDATED',
3535
};
3636

37-
const ASSET_UPDATES = {
37+
export const ASSET_UPDATES = {
3838
FONTS: {
3939
title: __( 'Google Fonts', 'material-design' ),
4040
type: 'FONTS',
@@ -76,9 +76,22 @@ const CORE_UPDATES = {
7676
},
7777
};
7878

79+
const FSE = {
80+
OPT_IN: {
81+
title: __( 'Opt-in', 'material-design' ),
82+
type: 'OPT_IN',
83+
autoUpdates: parseInt( getConfigTheme( 'isOptIn' ) || 0, 10 ),
84+
},
85+
};
86+
export const isPluginActive = !! window?.materialDesignWizard;
87+
export const isThemeActive = !! window?.materialDesignWizardTheme;
88+
7989
export const UPDATERS = {
80-
...ASSET_UPDATES,
81-
...( getConfig( 'coreUpdatesEnabled' ) ? CORE_UPDATES : {} ),
90+
...( isPluginActive ? ASSET_UPDATES : {} ),
91+
...( isPluginActive && getConfig( 'coreUpdatesEnabled' )
92+
? CORE_UPDATES
93+
: {} ),
94+
...( isThemeActive ? FSE : {} ),
8295
};
8396

8497
export const KEY_PLACEHOLDER = '•••••••••••••••••••••••••••••';

plugin/assets/src/settings/utils/promises.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import apiFetch from '@wordpress/api-fetch';
2222
/**
2323
* Internal dependencies
2424
*/
25-
import getConfig from '../../admin/get-config';
25+
import getConfig, { getConfigTheme } from '../../admin/get-config';
26+
import { isPluginActive } from '../constants';
2627

2728
/**
2829
* Update fonts.
@@ -125,3 +126,20 @@ export const toggleAutoUpdate = ( type, currentStatus ) => {
125126
.catch( reject );
126127
} );
127128
};
129+
130+
export const toggleFseOptIn = checked => {
131+
return new Promise( ( resolve, reject ) => {
132+
apiFetch( {
133+
path: isPluginActive
134+
? getConfigTheme( 'restPath' )
135+
: getConfigTheme( 'restUrl' ),
136+
method: 'POST',
137+
data: { checked },
138+
headers: {
139+
'X-WP-Nonce': getConfigTheme( 'nonce' ),
140+
},
141+
} )
142+
.then( resolve )
143+
.catch( reject );
144+
} );
145+
};

0 commit comments

Comments
 (0)