Skip to content

Commit

Permalink
Refactored download/upload logic to support font faces with multiple …
Browse files Browse the repository at this point in the history
…src assets (#58216)

Co-authored-by: Grant Kinney <creativecoder@users.noreply.github.com>
  • Loading branch information
2 people authored and cbravobernal committed Jan 30, 2024
1 parent 6faff4e commit d3f8d3a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import CollectionFontDetails from './collection-font-details';
import { toggleFont } from './utils/toggleFont';
import { getFontsOutline } from './utils/fonts-outline';
import GoogleFontsConfirmDialog from './google-fonts-confirm-dialog';
import { downloadFontFaceAsset } from './utils';
import { downloadFontFaceAssets } from './utils';

const DEFAULT_CATEGORY = {
slug: 'all',
Expand Down Expand Up @@ -161,7 +161,7 @@ function FontCollection( { slug } ) {
await Promise.all(
fontFamily.fontFace.map( async ( fontFace ) => {
if ( fontFace.src ) {
fontFace.file = await downloadFontFaceAsset(
fontFace.file = await downloadFontFaceAssets(
fontFace.src
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,24 @@ export function makeFontFacesFormData( font ) {
const fontFacesFormData = font.fontFace.map( ( face, faceIndex ) => {
const formData = new FormData();
if ( face.file ) {
// Slugified file name because the it might contain spaces or characters treated differently on the server.
const fileId = `file-${ faceIndex }`;
// Add the files to the formData
formData.append( fileId, face.file, face.file.name );
// remove the file object from the face object the file is referenced in src
const { file, ...faceWithoutFileProperty } = face;
const fontFaceSettings = {
...faceWithoutFileProperty,
src: fileId,
};
formData.append(
'font_face_settings',
JSON.stringify( fontFaceSettings )
);
// Normalize to an array, since face.file may be a single file or an array of files.
const files = Array.isArray( face.file )
? face.file
: [ face.file ];
const src = [];

files.forEach( ( file, key ) => {
// Slugified file name because the it might contain spaces or characters treated differently on the server.
const fileId = `file-${ faceIndex }-${ key }`;
// Add the files to the formData
formData.append( fileId, file, file.name );
src.push( fileId );
} );

face.src = src.length === 1 ? src[ 0 ] : src;
delete face.file;

formData.append( 'font_face_settings', JSON.stringify( face ) );
} else {
formData.append( 'font_face_settings', JSON.stringify( face ) );
}
Expand Down Expand Up @@ -225,31 +229,33 @@ export async function batchInstallFontFaces( fontFamilyId, fontFacesData ) {
/*
* Downloads a font face asset from a URL to the client and returns a File object.
*/
export async function downloadFontFaceAsset( url ) {
return fetch( new Request( url ) )
.then( ( response ) => {
if ( ! response.ok ) {
throw new Error(
`Error downloading font face asset from ${ url }. Server responded with status: ${ response.status }`
);
}
return response.blob();
} )
.then( ( blob ) => {
const filename = url.split( '/' ).pop();
const file = new File( [ blob ], filename, {
type: blob.type,
} );
return file;
export async function downloadFontFaceAssets( src ) {
// Normalize to an array, since `src` could be a string or array.
src = Array.isArray( src ) ? src : [ src ];

const files = await Promise.all(
src.map( async ( url ) => {
return fetch( new Request( url ) )
.then( ( response ) => {
if ( ! response.ok ) {
throw new Error(
`Error downloading font face asset from ${ url }. Server responded with status: ${ response.status }`
);
}
return response.blob();
} )
.then( ( blob ) => {
const filename = url.split( '/' ).pop();
const file = new File( [ blob ], filename, {
type: blob.type,
} );
return file;
} );
} )
.catch( ( error ) => {
// eslint-disable-next-line no-console
console.error(
`Error downloading font face asset from ${ url }:`,
error
);
throw error;
} );
);

// If we only have one file return it (not the array). Otherwise return all of them in the array.
return files.length === 1 ? files[ 0 ] : files;
}

/*
Expand Down

0 comments on commit d3f8d3a

Please sign in to comment.