From 927940e0329eb9f177a1a944352154549bb901cd Mon Sep 17 00:00:00 2001 From: Matias Benedetto Date: Thu, 4 Apr 2024 15:20:53 -0300 Subject: [PATCH] Avoid overriding custom settings on font library save (#60438) Co-authored-by: matiasbenedetto Co-authored-by: youknowriad Co-authored-by: mikachan Co-authored-by: creativecoder Co-authored-by: desrosj Co-authored-by: estelaris Co-authored-by: YanCol --- .../font-library-modal/context.js | 107 +++++++++++------- .../font-library-modal/installed-fonts.js | 5 +- .../push-changes-to-global-styles/index.js | 41 +------ .../edit-site/src/utils/set-nested-value.js | 39 +++++++ 4 files changed, 110 insertions(+), 82 deletions(-) create mode 100644 packages/edit-site/src/utils/set-nested-value.js diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/context.js b/packages/edit-site/src/components/global-styles/font-library-modal/context.js index ff8cfc1284b1ec..26ec6ede016b2c 100644 --- a/packages/edit-site/src/components/global-styles/font-library-modal/context.js +++ b/packages/edit-site/src/components/global-styles/font-library-modal/context.js @@ -35,12 +35,12 @@ import { checkFontFaceInstalled, } from './utils'; import { toggleFont } from './utils/toggleFont'; +import setNestedValue from '../../../utils/set-nested-value'; export const FontLibraryContext = createContext( {} ); function FontLibraryProvider( { children } ) { - const { __experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits } = - useDispatch( coreStore ); + const { saveEntityRecord } = useDispatch( coreStore ); const { globalStylesId } = useSelect( ( select ) => { const { __experimentalGetCurrentGlobalStylesId } = select( coreStore ); return { globalStylesId: __experimentalGetCurrentGlobalStylesId() }; @@ -94,11 +94,30 @@ function FontLibraryProvider( { children } ) { 'base' ); - // Save font families to the global styles post in the database. - const saveFontFamilies = () => { - saveSpecifiedEntityEdits( 'root', 'globalStyles', globalStylesId, [ - 'settings.typography.fontFamilies', - ] ); + /* + * Save the font families to the database. + + * This function is called when the user activates or deactivates a font family. + * It only updates the global styles post content in the database for new font families. + * This avoids saving other styles/settings changed by the user using other parts of the editor. + * + * It uses the font families from the param to avoid using the font families from an outdated state. + * + * @param {Array} fonts - The font families that will be saved to the database. + */ + const saveFontFamilies = async ( fonts ) => { + // Gets the global styles database post content. + const updatedGlobalStyles = globalStyles.record; + + // Updates the database version of global styles with the edited font families in the client. + setNestedValue( + updatedGlobalStyles, + [ 'settings', 'typography', 'fontFamilies' ], + fonts + ); + + // Saves a new version of the global styles in the database. + await saveEntityRecord( 'root', 'globalStyles', updatedGlobalStyles ); }; // Library Fonts @@ -322,15 +341,11 @@ function FontLibraryProvider( { children } ) { if ( fontFamiliesToActivate.length > 0 ) { // Activate the font family (add the font family to the global styles). - activateCustomFontFamilies( fontFamiliesToActivate ); - - // Save the global styles to the database. - await saveSpecifiedEntityEdits( - 'root', - 'globalStyles', - globalStylesId, - [ 'settings.typography.fontFamilies' ] + const activeFonts = activateCustomFontFamilies( + fontFamiliesToActivate ); + // Save the global styles to the database. + await saveFontFamilies( activeFonts ); refreshLibrary(); } @@ -360,14 +375,11 @@ function FontLibraryProvider( { children } ) { // Deactivate the font family if delete request is successful // (Removes the font family from the global styles). if ( uninstalledFontFamily.deleted ) { - deactivateFontFamily( fontFamilyToUninstall ); - // Save the global styles to the database. - await saveSpecifiedEntityEdits( - 'root', - 'globalStyles', - globalStylesId, - [ 'settings.typography.fontFamilies' ] + const activeFonts = deactivateFontFamily( + fontFamilyToUninstall ); + // Save the global styles to the database. + await saveFontFamilies( activeFonts ); } // Refresh the library (the library font families from database). @@ -391,42 +403,54 @@ function FontLibraryProvider( { children } ) { const newCustomFonts = initialCustomFonts.filter( ( f ) => f.slug !== font.slug ); - setFontFamilies( { + const activeFonts = { ...fontFamilies, [ font.source ]: newCustomFonts, - } ); + }; + setFontFamilies( activeFonts ); if ( font.fontFace ) { font.fontFace.forEach( ( face ) => { unloadFontFaceInBrowser( face, 'all' ); } ); } + return activeFonts; }; const activateCustomFontFamilies = ( fontsToAdd ) => { - // Removes the id from the families and faces to avoid saving that to global styles post content. - const fontsToActivate = fontsToAdd.map( - ( { id: _familyDbId, fontFace, ...font } ) => ( { - ...font, - ...( fontFace && fontFace.length > 0 - ? { - fontFace: fontFace.map( - ( { id: _faceDbId, ...face } ) => face - ), - } - : {} ), - } ) - ); + const fontsToActivate = cleanFontsForSave( fontsToAdd ); - // Activate the fonts by set the new custom fonts array. - setFontFamilies( { + const activeFonts = { ...fontFamilies, // Merge the existing custom fonts with the new fonts. custom: mergeFontFamilies( fontFamilies?.custom, fontsToActivate ), - } ); + }; + + // Activate the fonts by set the new custom fonts array. + setFontFamilies( activeFonts ); + + loadFontsInBrowser( fontsToActivate ); + + return activeFonts; + }; + + // Removes the id from the families and faces to avoid saving that to global styles post content. + const cleanFontsForSave = ( fonts ) => { + return fonts.map( ( { id: _familyDbId, fontFace, ...font } ) => ( { + ...font, + ...( fontFace && fontFace.length > 0 + ? { + fontFace: fontFace.map( + ( { id: _faceDbId, ...face } ) => face + ), + } + : {} ), + } ) ); + }; + const loadFontsInBrowser = ( fonts ) => { // Add custom fonts to the browser. - fontsToActivate.forEach( ( font ) => { + fonts.forEach( ( font ) => { if ( font.fontFace ) { font.fontFace.forEach( ( face ) => { // Load font faces just in the iframe because they already are in the document. @@ -518,6 +542,7 @@ function FontLibraryProvider( { children } ) { value={ { libraryFontSelected, handleSetLibraryFontSelected, + fontFamilies, themeFonts, baseThemeFonts, customFonts, diff --git a/packages/edit-site/src/components/global-styles/font-library-modal/installed-fonts.js b/packages/edit-site/src/components/global-styles/font-library-modal/installed-fonts.js index 226e9cf5a3eefc..69e645f57e6125 100644 --- a/packages/edit-site/src/components/global-styles/font-library-modal/installed-fonts.js +++ b/packages/edit-site/src/components/global-styles/font-library-modal/installed-fonts.js @@ -49,6 +49,7 @@ function InstalledFonts() { fontFamiliesHasChanges, notice, setNotice, + fontFamilies, } = useContext( FontLibraryContext ); const [ isConfirmDeleteOpen, setIsConfirmDeleteOpen ] = useState( false ); const customFontFamilyId = @@ -262,7 +263,9 @@ function InstalledFonts() { ) }