diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/index.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/index.tsx
index 375095a4ece..b2c43506ea5 100644
--- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/index.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/index.tsx
@@ -45,12 +45,12 @@ import { addFilter } from '@wordpress/hooks';
import { CustomizeStoreComponent } from '../types';
import { Layout } from './layout';
import './style.scss';
-import { PreloadFonts } from './preload-fonts';
import { GoBackWarningModal } from './go-back-warning-modal';
import { onBackButtonClicked } from '../utils';
import { getNewPath } from '@woocommerce/navigation';
import useBodyClass from '../hooks/use-body-class';
-
+import { OptInSubscribe } from './opt-in/opt-in';
+import { OptInContextProvider } from './opt-in/context';
import './tracking';
const { RouterProvider } = unlock( routerPrivateApis );
@@ -181,12 +181,14 @@ export const AssemblerHub: CustomizeStoreComponent = ( props ) => {
) }
-
-
-
-
-
-
+
+
+
+
+
+
+
+
>
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/context.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/context.tsx
new file mode 100644
index 00000000000..a2efc98c311
--- /dev/null
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/context.tsx
@@ -0,0 +1,53 @@
+/**
+ * External dependencies
+ */
+import { OPTIONS_STORE_NAME } from '@woocommerce/data';
+import { useSelect } from '@wordpress/data';
+import React, { createContext, useState } from '@wordpress/element';
+import type { ReactNode } from 'react';
+
+export const enum OPTIN_FLOW_STATUS {
+ 'IDLE' = 'IDLE',
+ 'LOADING' = 'LOADING',
+ 'DONE' = 'DONE',
+}
+
+export const OptInContext = createContext< {
+ optInFlowStatus: OPTIN_FLOW_STATUS;
+ setOptInFlowStatus: ( status: OPTIN_FLOW_STATUS ) => void;
+} >( {
+ optInFlowStatus: OPTIN_FLOW_STATUS.IDLE,
+ setOptInFlowStatus: () => {},
+} );
+
+export const OptInContextProvider = ( {
+ children,
+}: {
+ children: ReactNode;
+} ) => {
+ const isAllowTrackingEnabled = useSelect(
+ ( select ) =>
+ select( OPTIONS_STORE_NAME ).getOption(
+ 'woocommerce_allow_tracking'
+ ) === 'yes',
+ []
+ );
+
+ const [ optInFlowStatus, setOptInFlowStatus ] =
+ useState< OPTIN_FLOW_STATUS >(
+ isAllowTrackingEnabled
+ ? OPTIN_FLOW_STATUS.DONE
+ : OPTIN_FLOW_STATUS.IDLE
+ );
+
+ return (
+
+ { children }
+
+ );
+};
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/opt-in.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/opt-in.tsx
new file mode 100644
index 00000000000..23758b5e218
--- /dev/null
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/opt-in/opt-in.tsx
@@ -0,0 +1,161 @@
+/**
+ * External dependencies
+ */
+import { OPTIONS_STORE_NAME } from '@woocommerce/data';
+import apiFetch from '@wordpress/api-fetch';
+import { resolveSelect, select, subscribe, useDispatch } from '@wordpress/data';
+import { useContext, useEffect } from '@wordpress/element';
+// @ts-expect-error No types for this exist yet.
+// eslint-disable-next-line @woocommerce/dependency-group
+import { store as coreStore } from '@wordpress/core-data';
+// @ts-expect-error No types for this exist yet.
+// eslint-disable-next-line @woocommerce/dependency-group
+import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
+// @ts-expect-error No types for this exist yet.
+// eslint-disable-next-line @woocommerce/dependency-group
+import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
+
+/**
+ * Internal dependencies
+ */
+import { FontFamily, FontFace } from '../../types/font';
+import { usePatterns } from '../hooks/use-patterns';
+import { installFontFamilies } from '../utils/fonts';
+import { FONT_FAMILIES_TO_INSTALL } from '../sidebar/global-styles/font-pairing-variations/constants';
+import { OptInContext, OPTIN_FLOW_STATUS } from './context';
+
+const { useGlobalSetting } = unlock( blockEditorPrivateApis );
+
+export const OptInSubscribe = () => {
+ const { setOptInFlowStatus } = useContext( OptInContext );
+
+ const [ enabledFontFamilies, setFontFamilies ]: [
+ {
+ custom: Array< FontFamily >;
+ theme: Array< FontFamily >;
+ },
+ ( font: {
+ custom: Array< FontFamily >;
+ theme: Array< FontFamily >;
+ } ) => void
+ ] = useGlobalSetting( 'typography.fontFamilies' );
+
+ const {
+ // @ts-expect-error No types for this exist yet.
+ __experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits,
+ } = useDispatch( coreStore );
+
+ const installPatterns = async () => {
+ await apiFetch< {
+ success: boolean;
+ } >( {
+ path: `/wc/private/patterns`,
+ method: 'POST',
+ } );
+ };
+
+ const installFonts = async () => {
+ await installFontFamilies();
+
+ const globalStylesId =
+ // @ts-expect-error No types for this exist yet.
+ select( coreStore ).__experimentalGetCurrentGlobalStylesId();
+
+ const installedFontFamilies = ( await resolveSelect(
+ coreStore
+ // @ts-expect-error No types for this exist yet.
+ ).getEntityRecords( 'postType', 'wp_font_family', {
+ _embed: true,
+ per_page: -1,
+ } ) ) as Array< {
+ id: number;
+ font_family_settings: FontFamily;
+ _embedded: {
+ font_faces: Array< {
+ font_face_settings: FontFace;
+ } >;
+ };
+ } >;
+
+ const parsedInstalledFontFamilies = ( installedFontFamilies || [] ).map(
+ ( fontFamilyPost ) => {
+ return {
+ id: fontFamilyPost.id,
+ ...fontFamilyPost.font_family_settings,
+ fontFace:
+ fontFamilyPost?._embedded?.font_faces.map(
+ ( face ) => face.font_face_settings
+ ) || [],
+ };
+ }
+ );
+
+ const { custom } = enabledFontFamilies;
+
+ const enabledFontSlugs = [
+ ...( custom ? custom.map( ( font ) => font.slug ) : [] ),
+ ];
+
+ const fontFamiliesToEnable = parsedInstalledFontFamilies.reduce(
+ ( acc, font ) => {
+ if (
+ enabledFontSlugs.includes( font.slug ) ||
+ FONT_FAMILIES_TO_INSTALL[ font.slug ] === undefined
+ ) {
+ return acc;
+ }
+
+ return [
+ ...acc,
+ {
+ ...font,
+ },
+ ];
+ },
+ [] as Array< FontFamily >
+ );
+
+ setFontFamilies( {
+ ...enabledFontFamilies,
+ custom: [
+ ...( enabledFontFamilies.custom ?? [] ),
+ ...( fontFamiliesToEnable ?? [] ),
+ ],
+ } );
+
+ saveSpecifiedEntityEdits( 'root', 'globalStyles', globalStylesId, [
+ 'settings.typography.fontFamilies',
+ ] );
+ };
+
+ const { invalidateCache } = usePatterns();
+
+ useEffect( () => {
+ const unsubscribe = subscribe( async () => {
+ const isOptedIn =
+ select( OPTIONS_STORE_NAME ).getOption(
+ 'woocommerce_allow_tracking'
+ ) === 'yes';
+
+ if ( isOptedIn ) {
+ setOptInFlowStatus( OPTIN_FLOW_STATUS.LOADING );
+ await installPatterns();
+ invalidateCache();
+ await installFonts();
+
+ setOptInFlowStatus( OPTIN_FLOW_STATUS.DONE );
+
+ unsubscribe();
+ }
+ // @ts-expect-error The type is not updated.
+ }, OPTIONS_STORE_NAME );
+
+ return () => {
+ unsubscribe();
+ };
+ // We don't want to run this effect on every render, only once because it is a subscription.
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [] );
+
+ return null;
+};
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/preload-fonts.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/preload-fonts.tsx
index 25624729f1b..9ee86a64894 100644
--- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/preload-fonts.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/preload-fonts.tsx
@@ -2,9 +2,6 @@
/**
* External dependencies
*/
-// @ts-expect-error No types for this exist yet.
-import { store as coreStore } from '@wordpress/core-data';
-import { useSelect, useDispatch } from '@wordpress/data';
import {
privateApis as blockEditorPrivateApis,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -16,26 +13,18 @@ import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
/**
* Internal dependencies
*/
-import {
- FONT_PAIRINGS,
- FONT_FAMILIES_TO_INSTALL,
-} from './sidebar/global-styles/font-pairing-variations/constants';
+import { FONT_PAIRINGS } from './sidebar/global-styles/font-pairing-variations/constants';
import { FontFamiliesLoader } from './sidebar/global-styles/font-pairing-variations/font-families-loader';
-import { useContext, useEffect, useMemo } from '@wordpress/element';
-import { FontFace, FontFamily } from '../types/font';
+import { useContext, useMemo } from '@wordpress/element';
+import { FontFamily } from '../types/font';
import { FontFamiliesLoaderDotCom } from './sidebar/global-styles/font-pairing-variations/font-families-loader-dot-com';
import { CustomizeStoreContext } from '.';
import { isAIFlow, isNoAIFlow } from '../guards';
const { useGlobalSetting } = unlock( blockEditorPrivateApis );
-let areFontsPreloaded = false;
-
export const PreloadFonts = () => {
- // @ts-expect-error No types for this exist yet.
- const { __experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits } =
- useDispatch( coreStore );
- const [ enabledFontFamilies, setFontFamilies ]: [
+ const [ enabledFontFamilies ]: [
{
custom: Array< FontFamily >;
theme: Array< FontFamily >;
@@ -55,99 +44,6 @@ export const PreloadFonts = () => {
const { context } = useContext( CustomizeStoreContext );
- const { globalStylesId, installedFontFamilies } = useSelect( ( select ) => {
- // @ts-expect-error No types for this exist yet.
- const { __experimentalGetCurrentGlobalStylesId, getEntityRecords } =
- select( coreStore );
- return {
- globalStylesId: __experimentalGetCurrentGlobalStylesId(),
- installedFontFamilies: getEntityRecords(
- 'postType',
- 'wp_font_family',
- { _embed: true, per_page: -1 }
- ) as Array< {
- id: number;
- font_family_settings: FontFamily;
- _embedded: {
- font_faces: Array< {
- font_face_settings: FontFace;
- } >;
- };
- } >,
- };
- } );
-
- const parsedInstalledFontFamilies = useMemo( () => {
- return (
- ( installedFontFamilies || [] ).map( ( fontFamilyPost ) => {
- return {
- id: fontFamilyPost.id,
- ...fontFamilyPost.font_family_settings,
- fontFace:
- fontFamilyPost?._embedded?.font_faces.map(
- ( face ) => face.font_face_settings
- ) || [],
- };
- } ) || []
- );
- }, [ installedFontFamilies ] );
-
- useEffect( () => {
- if (
- areFontsPreloaded ||
- installedFontFamilies === null ||
- enabledFontFamilies === null
- ) {
- return;
- }
-
- const { custom } = enabledFontFamilies;
-
- const enabledFontSlugs = [
- ...( custom ? custom.map( ( font ) => font.slug ) : [] ),
- ];
-
- const fontFamiliesToEnable = parsedInstalledFontFamilies.reduce(
- ( acc, font ) => {
- if (
- enabledFontSlugs.includes( font.slug ) ||
- FONT_FAMILIES_TO_INSTALL[ font.slug ] === undefined
- ) {
- return acc;
- }
-
- return [
- ...acc,
- {
- ...font,
- },
- ];
- },
- [] as Array< FontFamily >
- );
-
- setFontFamilies( {
- ...enabledFontFamilies,
- custom: [
- ...( enabledFontFamilies.custom ?? [] ),
- ...( fontFamiliesToEnable ?? [] ),
- ],
- } );
-
- saveSpecifiedEntityEdits( 'root', 'globalStyles', globalStylesId, [
- 'settings.typography.fontFamilies',
- ] );
-
- areFontsPreloaded = true;
- }, [
- enabledFontFamilies,
- globalStylesId,
- installedFontFamilies,
- parsedInstalledFontFamilies,
- saveSpecifiedEntityEdits,
- setFontFamilies,
- ] );
-
const allFontChoices = FONT_PAIRINGS.map(
( fontPair ) => fontPair?.settings?.typography?.fontFamilies?.theme
);
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/global-styles/font-pairing-variations/index.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/global-styles/font-pairing-variations/index.tsx
index 26c0a85c4a5..eb15bd471b4 100644
--- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/global-styles/font-pairing-variations/index.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/global-styles/font-pairing-variations/index.tsx
@@ -30,6 +30,10 @@ import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { FlowType } from '~/customize-store/types';
import { FontFamily } from './font-families-loader-dot-com';
import { isAIFlow } from '~/customize-store/guards';
+import {
+ OptInContext,
+ OPTIN_FLOW_STATUS,
+} from '~/customize-store/assembler-hub/opt-in/context';
export const FontPairing = () => {
const { aiSuggestions, isLoading } = useSelect( ( select ) => {
@@ -72,6 +76,8 @@ export const FontPairing = () => {
) === 'yes'
);
+ const { optInFlowStatus } = useContext( OptInContext );
+
const fontPairings = useMemo( () => {
if ( isAIFlow( context.flowType ) ) {
return aiOnline && aiSuggestions?.lookAndFeel
@@ -106,7 +112,15 @@ export const FontPairing = () => {
}
);
- if ( ! trackingAllowed || ! isFontLibraryAvailable ) {
+ // We only show the default fonts when:
+ // - user did not allow tracking
+ // - site doesn't have the Font Library available
+ // - opt-in flow is still processing
+ if (
+ ! trackingAllowed ||
+ ! isFontLibraryAvailable ||
+ optInFlowStatus !== OPTIN_FLOW_STATUS.DONE
+ ) {
return defaultFonts;
}
@@ -134,14 +148,15 @@ export const FontPairing = () => {
}, [
aiOnline,
aiSuggestions?.lookAndFeel,
- baseFontFamilies,
+ baseFontFamilies.theme,
context.flowType,
custom,
isFontLibraryAvailable,
+ optInFlowStatus,
trackingAllowed,
] );
- if ( isLoading ) {
+ if ( isLoading || optInFlowStatus === OPTIN_FLOW_STATUS.LOADING ) {
return (
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-homepage-ptk/sidebar-navigation-screen-homepage-ptk.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-homepage-ptk/sidebar-navigation-screen-homepage-ptk.tsx
index 1d0bdd44c23..e3b0c875c3f 100644
--- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-homepage-ptk/sidebar-navigation-screen-homepage-ptk.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-homepage-ptk/sidebar-navigation-screen-homepage-ptk.tsx
@@ -163,7 +163,7 @@ export const SidebarNavigationScreenHomepagePTK = ( {
const [ optInDataSharing, setIsOptInDataSharing ] =
useState< boolean >( true );
- const [ isFetchingPatterns, setIsFetchingPatterns ] = useState( false );
+ const [ isSettingTracking, setIsSettingTracking ] = useState( false );
const optIn = () => {
trackEvent(
@@ -324,25 +324,18 @@ export const SidebarNavigationScreenHomepagePTK = ( {
onClick={ async () => {
optIn();
await enableTracking();
- setIsFetchingPatterns(
+ setIsSettingTracking(
true
);
- await apiFetch< {
- success: boolean;
- } >( {
- path: `/wc/private/patterns`,
- method: 'POST',
- } );
- invalidateCache();
closeModal();
- setIsFetchingPatterns(
+ setIsSettingTracking(
false
);
} }
variant="primary"
disabled={ ! optInDataSharing }
>
- { isFetchingPatterns ? (
+ { isSettingTracking ? (
) : (
__(
diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-typography/sidebar-navigation-screen-typography.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-typography/sidebar-navigation-screen-typography.tsx
index 88b26ec2820..115dd3561c6 100644
--- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-typography/sidebar-navigation-screen-typography.tsx
+++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-typography/sidebar-navigation-screen-typography.tsx
@@ -24,7 +24,6 @@ import { FontPairing } from '../global-styles';
import { CustomizeStoreContext } from '../..';
import { FlowType } from '~/customize-store/types';
import { trackEvent } from '~/customize-store/tracking';
-import { installFontFamilies } from '../../utils/fonts';
import { enableTracking } from '~/customize-store/design-without-ai/services';
export const SidebarNavigationScreenTypography = ( {
@@ -91,7 +90,7 @@ export const SidebarNavigationScreenTypography = ( {
const openModal = () => setIsModalOpen( true );
const closeModal = () => setIsModalOpen( false );
- const [ isFetchingFonts, setIsFetchingFonts ] = useState( false );
+ const [ isSettingTracking, setIsSettingTracking ] = useState( false );
const [ OptInDataSharing, setIsOptInDataSharing ] =
useState< boolean >( true );
@@ -175,17 +174,15 @@ export const SidebarNavigationScreenTypography = ( {