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

Jetpack AI: add logo generator codebase to ai-client package #38391

Merged
merged 29 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
01e3e12
Initial commit
lhkowalski Jul 16, 2024
0546784
Use image generation hook and fix initial prompt request
lhkowalski Jul 17, 2024
07c0c9f
Add save-to-media-library hook on ai-client
lhkowalski Jul 17, 2024
88db3fe
Save the logos to the library using the new hook
lhkowalski Jul 17, 2024
eb9217f
Fix the prompt enhancing request
lhkowalski Jul 17, 2024
0a4bb16
Fix first generation trigger
lhkowalski Jul 17, 2024
80d374d
changelog
lhkowalski Jul 17, 2024
ebe460a
Changelog
lhkowalski Jul 17, 2024
def9d46
Cache image generation function to prevent it from triggering re-renders
lhkowalski Jul 18, 2024
a8fc666
Remove unnecessary useCallback on the image generation hook
lhkowalski Jul 18, 2024
9062a0c
Fix infinity loop when the correct dependencies are set
lhkowalski Jul 18, 2024
1844ce5
Fix content editable div placeholder
lhkowalski Jul 18, 2024
9bc1056
Fix the media exists function to use the proper URL and check for err…
lhkowalski Jul 18, 2024
336ad1e
Fix inverted condition that was preventing generation to happen
lhkowalski Jul 18, 2024
ad4f243
Uncomment logo history handling funtions
lhkowalski Jul 18, 2024
ee0910f
Update debug namespace
lhkowalski Jul 19, 2024
1a907d3
Fix feature fetching action to use the right URL and drop the site ID…
lhkowalski Jul 19, 2024
2291a85
Improve feature data handling to fix first generation bug
lhkowalski Jul 19, 2024
7483569
Add experimental shortcut for the logo generator so we can test the p…
lhkowalski Jul 19, 2024
0792803
Fix style and position so the experimental entrypoint does not mess w…
lhkowalski Jul 19, 2024
f93cf89
Add missing doc comments on logo storage handler
lhkowalski Jul 19, 2024
c5a331b
Remove duplicated save-to-media-library code
lhkowalski Jul 19, 2024
9093e62
Remove duplicated request-token code
lhkowalski Jul 19, 2024
cca151e
Add missing doc comments on set site logo lib
lhkowalski Jul 19, 2024
7b07f74
Fix linter issues on wpcom-limited-request lib
lhkowalski Jul 19, 2024
b46e999
Add missing doc comments on reducer
lhkowalski Jul 19, 2024
9a163d0
Merge branch 'trunk' into update/jetpack-ai-copy-logo-generator-code
lhkowalski Jul 19, 2024
95e6bc2
Fix ternary tranlated label that is breaking the build
lhkowalski Jul 19, 2024
c985882
Use fetch instead of api-fetch to avoid URL rewriting
lhkowalski Jul 19, 2024
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
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Jetpack AI: add logo generator codebase to the ai-client package.
2 changes: 2 additions & 0 deletions projects/js-packages/ai-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
"@automattic/jetpack-shared-extension-utils": "workspace:*",
"@microsoft/fetch-event-source": "2.0.1",
"@types/react": "18.3.1",
"@types/wordpress__block-editor": "11.5.14",
"@wordpress/api-fetch": "7.2.0",
"@wordpress/blob": "4.2.0",
"@wordpress/block-editor": "13.2.0",
"@wordpress/components": "28.2.0",
"@wordpress/compose": "7.2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* External dependencies
*/
import { isBlobURL } from '@wordpress/blob';
import { useSelect } from '@wordpress/data';
import { useState } from '@wordpress/element';
import debugFactory from 'debug';
/**
* Types
*/
import type { BlockEditorStore } from '../../types.js';

const debug = debugFactory( 'ai-client:save-to-media-library' );

/**
* Hook to save an image to the media library.
*
* @returns {object} Object with the loading state and the function to save the image to the media library.
*/
export default function useSaveToMediaLibrary() {
const [ isLoading, setIsLoading ] = useState( false );
const { getSettings } = useSelect(
select => select( 'core/block-editor' ),
[]
) as BlockEditorStore[ 'selectors' ];

const saveToMediaLibrary = (
url: string,
name?: string
): Promise< { id: string; url: string } > => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const settings = getSettings() as any;

return new Promise( ( resolve, reject ) => {
setIsLoading( true );

debug( 'Fetching image from URL' );

fetch( url )
.then( response => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

await can help tame this horizontally moving code 😄

debug( 'Transforming response to blob' );

response
.blob()
.then( ( blob: Blob ) => {
debug( 'Uploading blob to media library' );
const filesList = Array< File | Blob >();

if ( name ) {
filesList.push( new File( [ blob ], name ) );
} else {
filesList.push( blob );
}

settings.mediaUpload( {
allowedTypes: [ 'image' ],
filesList,
onFileChange( [ image ] ) {
if ( isBlobURL( image?.url ) ) {
return;
}

if ( image ) {
debug( 'Image uploaded to media library', image );
resolve( image );
}

setIsLoading( false );
},
onError( message ) {
debug( 'Error uploading image to media library:', message );
reject( message );
setIsLoading( false );
},
} );
} )
.catch( e => {
debug( 'Error transforming response to blob:', e?.message );
reject( e?.message );
setIsLoading( false );
} );
} )
.catch( e => {
debug( 'Error fetching image from URL:', e?.message );
reject( e?.message );
setIsLoading( false );
} );
} );
};

return {
isLoading,
saveToMediaLibrary,
};
}
5 changes: 5 additions & 0 deletions projects/js-packages/ai-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ export * from './types.js';
* Libs
*/
export * from './libs/index.js';

/*
* Logo Generator
*/
export * from './logo-generator/index.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Internal dependencies
*/
import './icons.scss';

export default () => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="jetpack-ai-logo-generator-icon"
>
<path d="M6.99976 3.99994L7.84828 6.15141L9.99976 6.99994L7.84828 7.84847L6.99976 9.99994L6.15123 7.84847L3.99976 6.99994L6.15123 6.15141L6.99976 3.99994Z" />
<path d="M16 4L17.1314 6.86863L20 8L17.1314 9.13137L16 12L14.8686 9.13137L12 8L14.8686 6.86863L16 4Z" />
<path d="M11 10L12.4142 13.5858L16 15L12.4142 16.4142L11 20L9.58579 16.4142L6 15L9.58579 13.5858L11 10Z" />
</svg>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Internal dependencies
*/
import './icons.scss';

export default () => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="jetpack-ai-logo-generator-icon"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M17.9291 7.96836L10.7308 17.6492L6.2145 14.2911L7.10952 13.0873L10.4221 15.5504L16.7253 7.07333L17.9291 7.96836Z"
/>
</svg>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.jetpack-ai-logo-generator-icon {
path {
fill: var(--color-link, #3858e9);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Internal dependencies
*/
import './icons.scss';

export default () => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="jetpack-ai-logo-generator-icon"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.2927 13.7485C18.5014 17.0423 15.5366 19.4901 12 19.4901C8.92508 19.4901 6.28236 17.6396 5.12469 14.9915L8.79556 12.8139L12.2508 14.0309C12.482 14.1123 12.7383 14.0756 12.9374 13.9327L15.8243 11.8601L15.9039 11.8992C16.1998 12.0451 16.6072 12.249 17.0533 12.4807C17.8331 12.8857 18.6946 13.3572 19.2927 13.7485ZM19.499 12.1129C18.9341 11.7788 18.3001 11.4379 17.7447 11.1495C17.287 10.9118 16.8698 10.7031 16.5672 10.5539C16.4158 10.4792 16.2928 10.4193 16.2074 10.378L16.1085 10.3303L16.0824 10.3177L16.0729 10.3132C15.8261 10.1954 15.5347 10.2214 15.3126 10.3809L12.3802 12.4861L8.9634 11.2827C8.75395 11.2089 8.52258 11.2318 8.3316 11.3451L4.65716 13.5248C4.55414 13.0294 4.5 12.5161 4.5 11.9901C4.5 7.84798 7.85786 4.49011 12 4.49011C16.1421 4.49011 19.5 7.84798 19.5 11.9901C19.5 12.0311 19.4997 12.072 19.499 12.1129ZM21 11.9901C21 16.9607 16.9706 20.9901 12 20.9901C7.02944 20.9901 3 16.9607 3 11.9901C3 7.01955 7.02944 2.99011 12 2.99011C16.9706 2.99011 21 7.01955 21 11.9901Z"
/>
</svg>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Internal dependencies
*/
import './icons.scss';

export default () => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="jetpack-ai-logo-generator-icon"
>
<path d="M7 6.49011L11 8.99011L7 11.4901V6.49011Z" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5 2.99011C3.89543 2.99011 3 3.88554 3 4.99011V18.9901C3 20.0947 3.89543 20.9901 5 20.9901H19C20.1046 20.9901 21 20.0947 21 18.9901V4.99011C21 3.88554 20.1046 2.99011 19 2.99011H5ZM19 4.49011H5C4.72386 4.49011 4.5 4.71397 4.5 4.99011V15.6973L8.12953 13.0508C8.38061 12.8677 8.71858 12.8584 8.97934 13.0274L11.906 14.9243L15.4772 11.4524C15.7683 11.1694 16.2317 11.1694 16.5228 11.4524L19.5 14.3469V4.99011C19.5 4.71397 19.2761 4.49011 19 4.49011ZM4.5 18.9901V17.5537L8.59643 14.5667L11.5921 16.5084C11.8857 16.6987 12.2719 16.6607 12.5228 16.4167L16 13.0361L19.4772 16.4167L19.5 16.3933V18.9901C19.5 19.2663 19.2761 19.4901 19 19.4901H5C4.72386 19.4901 4.5 19.2663 4.5 18.9901Z"
/>
</svg>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module '*.gif';
declare module '*.png';
declare module '*.svg';
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* External dependencies
*/
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
/**
* Types
*/
import type React from 'react';

export const FeatureFetchFailureScreen: React.FC< {
onCancel: () => void;
onRetry: () => void;
} > = ( { onCancel, onRetry } ) => {
const errorMessage = __(
'We are sorry. There was an error loading your Jetpack AI account settings. Please, try again.',
'jetpack-ai-client'
);

return (
<div className="jetpack-ai-logo-generator-modal__notice-message-wrapper">
<div className="jetpack-ai-logo-generator-modal__notice-message">
<span className="jetpack-ai-logo-generator-modal__loading-message">{ errorMessage }</span>
</div>
<div className="jetpack-ai-logo-generator-modal__notice-actions">
<Button variant="tertiary" onClick={ onCancel }>
{ __( 'Cancel', 'jetpack-ai-client' ) }
</Button>
<Button variant="primary" onClick={ onRetry }>
{ __( 'Try again', 'jetpack-ai-client' ) }
</Button>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.jetpack-ai-logo-generator-modal__loading-wrapper {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
justify-content: center;
flex-grow: 1;
}

.jetpack-ai-logo-generator-modal__loader {
margin-bottom: 29px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import React from 'react';
/**
* Internal dependencies
*/
import { ImageLoader } from './image-loader.js';
import './first-load-screen.scss';

export const FirstLoadScreen: React.FC< {
state?: 'loadingFeature' | 'analyzing' | 'generating';
} > = ( { state = 'loadingFeature' } ) => {
const loadingLabel = __( 'Loading…', 'jetpack-ai-client' );
const analyzingLabel = __(
'Analyzing your site to create the perfect logo…',
'jetpack-ai-client'
);
const generatingLabel = __( 'Generating logo…', 'jetpack-ai-client' );

return (
<div className="jetpack-ai-logo-generator-modal__loading-wrapper">
<ImageLoader />
<span className="jetpack-ai-logo-generator-modal__loading-message">
{ state === 'loadingFeature' && loadingLabel }
{ state === 'analyzing' && analyzingLabel }
{ state === 'generating' && generatingLabel }
</span>
</div>
);
};
Loading
Loading