@automattic/jetpack-ai-client 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/build/hooks/use-image-generator/constants.d.ts +39 -0
- package/build/hooks/use-image-generator/constants.js +40 -0
- package/build/hooks/use-image-generator/index.d.ts +2 -0
- package/build/hooks/use-image-generator/index.js +11 -0
- package/build/logo-generator/components/generator-modal.js +2 -2
- package/build/logo-generator/components/prompt.d.ts +5 -3
- package/build/logo-generator/components/prompt.js +25 -8
- package/build/logo-generator/constants.d.ts +1 -0
- package/build/logo-generator/constants.js +1 -0
- package/build/logo-generator/hooks/use-logo-generator.d.ts +6 -2
- package/build/logo-generator/hooks/use-logo-generator.js +6 -4
- package/build/logo-generator/types.d.ts +1 -0
- package/package.json +3 -3
- package/src/hooks/use-image-generator/constants.ts +44 -0
- package/src/hooks/use-image-generator/index.ts +12 -0
- package/src/logo-generator/components/generator-modal.scss +3 -1
- package/src/logo-generator/components/generator-modal.tsx +4 -1
- package/src/logo-generator/components/prompt.scss +5 -3
- package/src/logo-generator/components/prompt.tsx +51 -6
- package/src/logo-generator/constants.ts +1 -0
- package/src/logo-generator/hooks/use-logo-generator.ts +14 -3
- package/src/logo-generator/types.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.20.0] - 2024-09-30
|
|
9
|
+
### Added
|
|
10
|
+
- AI Client: add support for showStyleSelector on logo generator and use-image-generator [#39530]
|
|
11
|
+
|
|
8
12
|
## [0.19.0] - 2024-09-23
|
|
9
13
|
### Changed
|
|
10
14
|
- AI Client: Don't send a default style to jetpack-ai-image endpoint, default is handled in backend and we need to not send it until we're ready for it to be a user option. [#39494]
|
|
@@ -415,6 +419,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
415
419
|
- Updated package dependencies. [#31659]
|
|
416
420
|
- Updated package dependencies. [#31785]
|
|
417
421
|
|
|
422
|
+
[0.20.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.19.0...v0.20.0
|
|
418
423
|
[0.19.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.18.1...v0.19.0
|
|
419
424
|
[0.18.1]: https://github.com/Automattic/jetpack-ai-client/compare/v0.18.0...v0.18.1
|
|
420
425
|
[0.18.0]: https://github.com/Automattic/jetpack-ai-client/compare/v0.17.0...v0.18.0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const IMAGE_STYLE_ENHANCE = "enhance";
|
|
2
|
+
export declare const IMAGE_STYLE_ANIME = "anime";
|
|
3
|
+
export declare const IMAGE_STYLE_PHOTOGRAPHIC = "photographic";
|
|
4
|
+
export declare const IMAGE_STYLE_DIGITAL_ART = "digital-art";
|
|
5
|
+
export declare const IMAGE_STYLE_COMICBOOK = "comicbook";
|
|
6
|
+
export declare const IMAGE_STYLE_FANTASY_ART = "fantasy-art";
|
|
7
|
+
export declare const IMAGE_STYLE_ANALOG_FILM = "analog-film";
|
|
8
|
+
export declare const IMAGE_STYLE_NEONPUNK = "neonpunk";
|
|
9
|
+
export declare const IMAGE_STYLE_ISOMETRIC = "isometric";
|
|
10
|
+
export declare const IMAGE_STYLE_LOWPOLY = "lowpoly";
|
|
11
|
+
export declare const IMAGE_STYLE_ORIGAMI = "origami";
|
|
12
|
+
export declare const IMAGE_STYLE_LINE_ART = "line-art";
|
|
13
|
+
export declare const IMAGE_STYLE_CRAFT_CLAY = "craft-clay";
|
|
14
|
+
export declare const IMAGE_STYLE_CINEMATIC = "cinematic";
|
|
15
|
+
export declare const IMAGE_STYLE_3D_MODEL = "3d-model";
|
|
16
|
+
export declare const IMAGE_STYLE_PIXEL_ART = "pixel-art";
|
|
17
|
+
export declare const IMAGE_STYLE_TEXTURE = "texture";
|
|
18
|
+
export declare const IMAGE_STYLE_MONTY_PYTHON = "monty-python";
|
|
19
|
+
export declare const IMAGE_STYLE_LABELS: {
|
|
20
|
+
enhance: string;
|
|
21
|
+
anime: string;
|
|
22
|
+
photographic: string;
|
|
23
|
+
"digital-art": string;
|
|
24
|
+
comicbook: string;
|
|
25
|
+
"fantasy-art": string;
|
|
26
|
+
"analog-film": string;
|
|
27
|
+
neonpunk: string;
|
|
28
|
+
isometric: string;
|
|
29
|
+
lowpoly: string;
|
|
30
|
+
origami: string;
|
|
31
|
+
"line-art": string;
|
|
32
|
+
"craft-clay": string;
|
|
33
|
+
cinematic: string;
|
|
34
|
+
"3d-model": string;
|
|
35
|
+
"pixel-art": string;
|
|
36
|
+
texture: string;
|
|
37
|
+
"monty-python": string;
|
|
38
|
+
};
|
|
39
|
+
export type ImageStyle = keyof typeof IMAGE_STYLE_LABELS;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
// Styles
|
|
3
|
+
export const IMAGE_STYLE_ENHANCE = 'enhance';
|
|
4
|
+
export const IMAGE_STYLE_ANIME = 'anime';
|
|
5
|
+
export const IMAGE_STYLE_PHOTOGRAPHIC = 'photographic';
|
|
6
|
+
export const IMAGE_STYLE_DIGITAL_ART = 'digital-art';
|
|
7
|
+
export const IMAGE_STYLE_COMICBOOK = 'comicbook';
|
|
8
|
+
export const IMAGE_STYLE_FANTASY_ART = 'fantasy-art';
|
|
9
|
+
export const IMAGE_STYLE_ANALOG_FILM = 'analog-film';
|
|
10
|
+
export const IMAGE_STYLE_NEONPUNK = 'neonpunk';
|
|
11
|
+
export const IMAGE_STYLE_ISOMETRIC = 'isometric';
|
|
12
|
+
export const IMAGE_STYLE_LOWPOLY = 'lowpoly';
|
|
13
|
+
export const IMAGE_STYLE_ORIGAMI = 'origami';
|
|
14
|
+
export const IMAGE_STYLE_LINE_ART = 'line-art';
|
|
15
|
+
export const IMAGE_STYLE_CRAFT_CLAY = 'craft-clay';
|
|
16
|
+
export const IMAGE_STYLE_CINEMATIC = 'cinematic';
|
|
17
|
+
export const IMAGE_STYLE_3D_MODEL = '3d-model';
|
|
18
|
+
export const IMAGE_STYLE_PIXEL_ART = 'pixel-art';
|
|
19
|
+
export const IMAGE_STYLE_TEXTURE = 'texture';
|
|
20
|
+
export const IMAGE_STYLE_MONTY_PYTHON = 'monty-python';
|
|
21
|
+
export const IMAGE_STYLE_LABELS = {
|
|
22
|
+
[IMAGE_STYLE_ENHANCE]: __('Enhance', 'jetpack-ai-client'),
|
|
23
|
+
[IMAGE_STYLE_ANIME]: __('Anime', 'jetpack-ai-client'),
|
|
24
|
+
[IMAGE_STYLE_PHOTOGRAPHIC]: __('Photographic', 'jetpack-ai-client'),
|
|
25
|
+
[IMAGE_STYLE_DIGITAL_ART]: __('Digital Art', 'jetpack-ai-client'),
|
|
26
|
+
[IMAGE_STYLE_COMICBOOK]: __('Comicbook', 'jetpack-ai-client'),
|
|
27
|
+
[IMAGE_STYLE_FANTASY_ART]: __('Fantasy Art', 'jetpack-ai-client'),
|
|
28
|
+
[IMAGE_STYLE_ANALOG_FILM]: __('Analog Film', 'jetpack-ai-client'),
|
|
29
|
+
[IMAGE_STYLE_NEONPUNK]: __('Neon Punk', 'jetpack-ai-client'),
|
|
30
|
+
[IMAGE_STYLE_ISOMETRIC]: __('Isometric', 'jetpack-ai-client'),
|
|
31
|
+
[IMAGE_STYLE_LOWPOLY]: __('Low Poly', 'jetpack-ai-client'),
|
|
32
|
+
[IMAGE_STYLE_ORIGAMI]: __('Origami', 'jetpack-ai-client'),
|
|
33
|
+
[IMAGE_STYLE_LINE_ART]: __('Line Art', 'jetpack-ai-client'),
|
|
34
|
+
[IMAGE_STYLE_CRAFT_CLAY]: __('Craft Clay', 'jetpack-ai-client'),
|
|
35
|
+
[IMAGE_STYLE_CINEMATIC]: __('Cinematic', 'jetpack-ai-client'),
|
|
36
|
+
[IMAGE_STYLE_3D_MODEL]: __('3D Model', 'jetpack-ai-client'),
|
|
37
|
+
[IMAGE_STYLE_PIXEL_ART]: __('Pixel Art', 'jetpack-ai-client'),
|
|
38
|
+
[IMAGE_STYLE_TEXTURE]: __('Texture', 'jetpack-ai-client'),
|
|
39
|
+
[IMAGE_STYLE_MONTY_PYTHON]: __('Monty Python', 'jetpack-ai-client'),
|
|
40
|
+
};
|
|
@@ -19,5 +19,7 @@ declare const useImageGenerator: () => {
|
|
|
19
19
|
userPrompt?: string;
|
|
20
20
|
}) => Promise<ImageGenerationResponse>;
|
|
21
21
|
generateImageWithParameters: (parameters: object) => Promise<ImageGenerationResponse>;
|
|
22
|
+
getImageStyles: () => object;
|
|
22
23
|
};
|
|
23
24
|
export default useImageGenerator;
|
|
25
|
+
export * from './constants.js';
|
|
@@ -7,6 +7,7 @@ import debugFactory from 'debug';
|
|
|
7
7
|
*/
|
|
8
8
|
import askQuestionSync from '../../ask-question/sync.js';
|
|
9
9
|
import requestJwt from '../../jwt/index.js';
|
|
10
|
+
import { IMAGE_STYLE_LABELS } from './constants.js';
|
|
10
11
|
const debug = debugFactory('ai-client:use-image-generator');
|
|
11
12
|
/**
|
|
12
13
|
* Cut the post content on a given lenght so the total length of the prompt is not longer than 4000 characters.
|
|
@@ -195,10 +196,20 @@ const useImageGenerator = () => {
|
|
|
195
196
|
return Promise.reject(error);
|
|
196
197
|
}
|
|
197
198
|
};
|
|
199
|
+
/**
|
|
200
|
+
* Get available styles.
|
|
201
|
+
*
|
|
202
|
+
* @return {object} with the styles {key:label} for the image generation.
|
|
203
|
+
*/
|
|
204
|
+
const getImageStyles = function () {
|
|
205
|
+
return IMAGE_STYLE_LABELS;
|
|
206
|
+
};
|
|
198
207
|
return {
|
|
199
208
|
generateImage,
|
|
200
209
|
generateImageWithStableDiffusion,
|
|
201
210
|
generateImageWithParameters: executeImageGeneration,
|
|
211
|
+
getImageStyles,
|
|
202
212
|
};
|
|
203
213
|
};
|
|
204
214
|
export default useImageGenerator;
|
|
215
|
+
export * from './constants.js';
|
|
@@ -29,7 +29,7 @@ import { UpgradeScreen } from './upgrade-screen.js';
|
|
|
29
29
|
import { VisitSiteBanner } from './visit-site-banner.js';
|
|
30
30
|
import './generator-modal.scss';
|
|
31
31
|
const debug = debugFactory('jetpack-ai-calypso:generator-modal');
|
|
32
|
-
export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDetails, context, placement, }) => {
|
|
32
|
+
export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDetails, context, placement, showStyleSelector, }) => {
|
|
33
33
|
const { tracks } = useAnalytics();
|
|
34
34
|
const { recordEvent: recordTracksEvent } = tracks;
|
|
35
35
|
const { setSiteDetails, fetchAiAssistantFeature, loadLogoHistory, setIsLoadingHistory } = useDispatch(STORE_NAME);
|
|
@@ -181,7 +181,7 @@ export const GeneratorModal = ({ isOpen, onClose, onApplyLogo, onReload, siteDet
|
|
|
181
181
|
body = (_jsx(UpgradeScreen, { onCancel: closeModal, upgradeURL: upgradeURL, reason: needsFeature ? 'feature' : 'requests' }));
|
|
182
182
|
}
|
|
183
183
|
else {
|
|
184
|
-
body = (_jsxs(_Fragment, { children: [!logoAccepted && _jsx(Prompt, { initialPrompt: initialPrompt }), _jsx(LogoPresenter, { logo: selectedLogo, onApplyLogo: handleApplyLogo, logoAccepted: logoAccepted, siteId: String(siteId) }), logoAccepted ? (_jsxs("div", { className: "jetpack-ai-logo-generator__accept", children: [_jsx(VisitSiteBanner, {}), _jsx("div", { className: "jetpack-ai-logo-generator__accept-actions", children: _jsx(Button, { variant: "primary", onClick: closeModal, children: __('Close', 'jetpack-ai-client') }) })] })) : (_jsxs(_Fragment, { children: [_jsx(HistoryCarousel, {}), _jsx("div", { className: "jetpack-ai-logo-generator__footer", children: _jsxs(Button, { variant: "link", className: "jetpack-ai-logo-generator__feedback-button", href: "https://jetpack.com/redirect/?source=jetpack-ai-feedback", target: "_blank", onClick: handleFeedbackClick, children: [_jsx("span", { children: __('Provide feedback', 'jetpack-ai-client') }), _jsx(Icon, { icon: external, className: "icon" })] }) })] }))] }));
|
|
184
|
+
body = (_jsxs(_Fragment, { children: [!logoAccepted && (_jsx(Prompt, { initialPrompt: initialPrompt, showStyleSelector: showStyleSelector })), _jsx(LogoPresenter, { logo: selectedLogo, onApplyLogo: handleApplyLogo, logoAccepted: logoAccepted, siteId: String(siteId) }), logoAccepted ? (_jsxs("div", { className: "jetpack-ai-logo-generator__accept", children: [_jsx(VisitSiteBanner, {}), _jsx("div", { className: "jetpack-ai-logo-generator__accept-actions", children: _jsx(Button, { variant: "primary", onClick: closeModal, children: __('Close', 'jetpack-ai-client') }) })] })) : (_jsxs(_Fragment, { children: [_jsx(HistoryCarousel, {}), _jsx("div", { className: "jetpack-ai-logo-generator__footer", children: _jsxs(Button, { variant: "link", className: "jetpack-ai-logo-generator__feedback-button", href: "https://jetpack.com/redirect/?source=jetpack-ai-feedback", target: "_blank", onClick: handleFeedbackClick, children: [_jsx("span", { children: __('Provide feedback', 'jetpack-ai-client') }), _jsx(Icon, { icon: external, className: "icon" })] }) })] }))] }));
|
|
185
185
|
}
|
|
186
186
|
return (_jsx(_Fragment, { children: isOpen && (_jsx(Modal, { className: "jetpack-ai-logo-generator-modal", onRequestClose: closeModal, shouldCloseOnClickOutside: false, shouldCloseOnEsc: false, title: __('Jetpack AI Logo Generator', 'jetpack-ai-client'), children: _jsx("div", { className: clsx('jetpack-ai-logo-generator-modal__body', {
|
|
187
187
|
'notice-modal': needsFeature || needsMoreRequests || featureFetchError || firstLogoPromptFetchError,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
/// <reference types="react" resolution-mode="require"/>
|
|
2
1
|
import './prompt.scss';
|
|
3
|
-
|
|
2
|
+
type PromptProps = {
|
|
4
3
|
initialPrompt?: string;
|
|
5
|
-
|
|
4
|
+
showStyleSelector?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare const Prompt: ({ initialPrompt, showStyleSelector }: PromptProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* External dependencies
|
|
4
4
|
*/
|
|
5
5
|
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
-
import { Button, Tooltip } from '@wordpress/components';
|
|
6
|
+
import { Button, Tooltip, SelectControl } from '@wordpress/components';
|
|
7
7
|
import { __, sprintf } from '@wordpress/i18n';
|
|
8
8
|
import { Icon, info } from '@wordpress/icons';
|
|
9
9
|
import debugFactory from 'debug';
|
|
@@ -11,8 +11,9 @@ import { useCallback, useEffect, useState, useRef } from 'react';
|
|
|
11
11
|
/**
|
|
12
12
|
* Internal dependencies
|
|
13
13
|
*/
|
|
14
|
+
import { IMAGE_STYLE_MONTY_PYTHON, IMAGE_STYLE_LINE_ART, } from '../../hooks/use-image-generator/constants.js';
|
|
14
15
|
import AiIcon from '../assets/icons/ai.js';
|
|
15
|
-
import { EVENT_GENERATE, MINIMUM_PROMPT_LENGTH, EVENT_UPGRADE, EVENT_PLACEMENT_INPUT_FOOTER, } from '../constants.js';
|
|
16
|
+
import { EVENT_GENERATE, MINIMUM_PROMPT_LENGTH, EVENT_UPGRADE, EVENT_PLACEMENT_INPUT_FOOTER, EVENT_SWITCH_STYLE, } from '../constants.js';
|
|
16
17
|
import { useCheckout } from '../hooks/use-checkout.js';
|
|
17
18
|
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
18
19
|
import useRequestErrors from '../hooks/use-request-errors.js';
|
|
@@ -20,7 +21,7 @@ import { FairUsageNotice } from './fair-usage-notice.js';
|
|
|
20
21
|
import { UpgradeNudge } from './upgrade-nudge.js';
|
|
21
22
|
import './prompt.scss';
|
|
22
23
|
const debug = debugFactory('jetpack-ai-calypso:prompt-box');
|
|
23
|
-
export const Prompt = ({ initialPrompt = '' }) => {
|
|
24
|
+
export const Prompt = ({ initialPrompt = '', showStyleSelector = false }) => {
|
|
24
25
|
const { tracks } = useAnalytics();
|
|
25
26
|
const { recordEvent: recordTracksEvent } = tracks;
|
|
26
27
|
const [prompt, setPrompt] = useState(initialPrompt);
|
|
@@ -28,7 +29,8 @@ export const Prompt = ({ initialPrompt = '' }) => {
|
|
|
28
29
|
const { enhancePromptFetchError, logoFetchError } = useRequestErrors();
|
|
29
30
|
const { nextTierCheckoutURL: checkoutUrl, hasNextTier } = useCheckout();
|
|
30
31
|
const hasPrompt = prompt?.length >= MINIMUM_PROMPT_LENGTH;
|
|
31
|
-
const
|
|
32
|
+
const [style, setStyle] = useState(showStyleSelector ? IMAGE_STYLE_LINE_ART : null);
|
|
33
|
+
const { generateLogo, enhancePrompt, setIsEnhancingPrompt, isBusy, isEnhancingPrompt, site, getAiAssistantFeature, requireUpgrade, context, tierPlansEnabled, getImageStyles, } = useLogoGenerator();
|
|
32
34
|
const enhancingLabel = __('Enhancing…', 'jetpack-ai-client');
|
|
33
35
|
const enhanceLabel = __('Enhance prompt', 'jetpack-ai-client');
|
|
34
36
|
const enhanceButtonLabel = isEnhancingPrompt ? enhancingLabel : enhanceLabel;
|
|
@@ -66,9 +68,10 @@ export const Prompt = ({ initialPrompt = '' }) => {
|
|
|
66
68
|
}
|
|
67
69
|
}, [prompt]);
|
|
68
70
|
const onGenerate = useCallback(async () => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
// shouldn't tool be "logo-generator" to be more specific?
|
|
72
|
+
recordTracksEvent(EVENT_GENERATE, { context, tool: 'image', style });
|
|
73
|
+
generateLogo({ prompt, style });
|
|
74
|
+
}, [context, generateLogo, prompt, style]);
|
|
72
75
|
const onPromptInput = (event) => {
|
|
73
76
|
setPrompt(event.target.textContent || '');
|
|
74
77
|
};
|
|
@@ -89,7 +92,21 @@ export const Prompt = ({ initialPrompt = '' }) => {
|
|
|
89
92
|
const onUpgradeClick = () => {
|
|
90
93
|
recordTracksEvent(EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_INPUT_FOOTER });
|
|
91
94
|
};
|
|
92
|
-
|
|
95
|
+
const updateStyle = useCallback((imageStyle) => {
|
|
96
|
+
debug('change style', imageStyle);
|
|
97
|
+
setStyle(imageStyle);
|
|
98
|
+
recordTracksEvent(EVENT_SWITCH_STYLE, { context, style: imageStyle });
|
|
99
|
+
}, [context, setStyle, recordTracksEvent]);
|
|
100
|
+
const imageStyles = getImageStyles();
|
|
101
|
+
const availableStyles = Object.keys(imageStyles).filter((styleKey) => styleKey !== IMAGE_STYLE_MONTY_PYTHON);
|
|
102
|
+
return (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt", children: [_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-header", children: [_jsx("div", { className: "jetpack-ai-logo-generator__prompt-label", children: __('Describe your site:', 'jetpack-ai-client') }), _jsx("div", { className: "jetpack-ai-logo-generator__prompt-actions", children: _jsxs(Button, { variant: "link", disabled: isBusy || requireUpgrade || !hasPrompt, onClick: onEnhance, children: [_jsx(AiIcon, {}), enhanceButtonLabel] }) }), showStyleSelector && availableStyles && (_jsx(SelectControl
|
|
103
|
+
// label={ __( 'Style', 'jetpack-ai-client' ) }
|
|
104
|
+
, {
|
|
105
|
+
// label={ __( 'Style', 'jetpack-ai-client' ) }
|
|
106
|
+
__nextHasNoMarginBottom: true, value: style, options: availableStyles.map(imageStyle => ({
|
|
107
|
+
label: imageStyles[imageStyle],
|
|
108
|
+
value: imageStyle,
|
|
109
|
+
})), onChange: updateStyle }))] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-query", children: [_jsx("div", { ref: inputRef, contentEditable: !isBusy && !requireUpgrade,
|
|
93
110
|
// The content editable div is expected to be updated by the enhance prompt, so warnings are suppressed
|
|
94
111
|
suppressContentEditableWarning: true, className: "prompt-query__input", onInput: onPromptInput, onPaste: onPromptPaste, "data-placeholder": __('Describe your site or simply ask for a logo specifying some details about it', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", className: "jetpack-ai-logo-generator__prompt-submit", onClick: onGenerate, disabled: isBusy || requireUpgrade || !hasPrompt, children: __('Generate', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-footer", children: [!isUnlimited && !requireUpgrade && (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-requests", children: [_jsx("div", { children: sprintf(
|
|
95
112
|
// translators: %u is the number of requests
|
|
@@ -8,6 +8,7 @@ export declare const EVENT_USE = "jetpack_ai_logo_generator_use";
|
|
|
8
8
|
export declare const EVENT_NAVIGATE = "jetpack_ai_logo_generator_navigate";
|
|
9
9
|
export declare const EVENT_FEEDBACK = "jetpack_ai_logo_generator_feedback";
|
|
10
10
|
export declare const EVENT_UPGRADE = "jetpack_ai_upgrade_button";
|
|
11
|
+
export declare const EVENT_SWITCH_STYLE = "jetpack_ai_logo_generator_switch_style";
|
|
11
12
|
export declare const EVENT_PLACEMENT_QUICK_LINKS = "quick_links";
|
|
12
13
|
export declare const EVENT_PLACEMENT_INPUT_FOOTER = "input_footer";
|
|
13
14
|
export declare const EVENT_PLACEMENT_FREE_USER_SCREEN = "free_user_screen";
|
|
@@ -9,6 +9,7 @@ export const EVENT_USE = 'jetpack_ai_logo_generator_use';
|
|
|
9
9
|
export const EVENT_NAVIGATE = 'jetpack_ai_logo_generator_navigate';
|
|
10
10
|
export const EVENT_FEEDBACK = 'jetpack_ai_logo_generator_feedback';
|
|
11
11
|
export const EVENT_UPGRADE = 'jetpack_ai_upgrade_button';
|
|
12
|
+
export const EVENT_SWITCH_STYLE = 'jetpack_ai_logo_generator_switch_style';
|
|
12
13
|
// Event placement constants
|
|
13
14
|
export const EVENT_PLACEMENT_QUICK_LINKS = 'quick_links';
|
|
14
15
|
export const EVENT_PLACEMENT_INPUT_FOOTER = 'input_footer';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Types
|
|
3
3
|
*/
|
|
4
|
+
import type { ImageStyle } from '../../hooks/use-image-generator/constants.js';
|
|
4
5
|
import type { Logo, SaveLogo } from '../store/types.js';
|
|
5
6
|
declare const useLogoGenerator: () => {
|
|
6
7
|
logos: Logo[];
|
|
@@ -15,8 +16,9 @@ declare const useLogoGenerator: () => {
|
|
|
15
16
|
generateFirstPrompt: () => Promise<string>;
|
|
16
17
|
saveLogo: SaveLogo;
|
|
17
18
|
applyLogo: () => Promise<void>;
|
|
18
|
-
generateImage: ({ prompt, }: {
|
|
19
|
+
generateImage: ({ prompt, style, }: {
|
|
19
20
|
prompt: string;
|
|
21
|
+
style?: ImageStyle | null;
|
|
20
22
|
}) => Promise<{
|
|
21
23
|
data: Array<{
|
|
22
24
|
url: string;
|
|
@@ -26,8 +28,9 @@ declare const useLogoGenerator: () => {
|
|
|
26
28
|
prompt: string;
|
|
27
29
|
}) => Promise<string>;
|
|
28
30
|
storeLogo: (logo: Logo) => void;
|
|
29
|
-
generateLogo: ({ prompt }: {
|
|
31
|
+
generateLogo: ({ prompt, style, }: {
|
|
30
32
|
prompt: string;
|
|
33
|
+
style?: ImageStyle | null;
|
|
31
34
|
}) => Promise<void>;
|
|
32
35
|
setIsEnhancingPrompt: any;
|
|
33
36
|
setIsRequestingImage: any;
|
|
@@ -45,5 +48,6 @@ declare const useLogoGenerator: () => {
|
|
|
45
48
|
tierPlansEnabled: boolean;
|
|
46
49
|
isLoadingHistory: boolean;
|
|
47
50
|
setIsLoadingHistory: any;
|
|
51
|
+
getImageStyles: () => object;
|
|
48
52
|
};
|
|
49
53
|
export default useLogoGenerator;
|
|
@@ -37,7 +37,7 @@ const useLogoGenerator = () => {
|
|
|
37
37
|
};
|
|
38
38
|
}, []);
|
|
39
39
|
const { setFirstLogoPromptFetchError, setEnhancePromptFetchError, setLogoFetchError, setSaveToLibraryError, setLogoUpdateError, } = useRequestErrors();
|
|
40
|
-
const { generateImageWithParameters } = useImageGenerator();
|
|
40
|
+
const { generateImageWithParameters, getImageStyles } = useImageGenerator();
|
|
41
41
|
const { saveToMediaLibrary } = useSaveToMediaLibrary();
|
|
42
42
|
const { ID = null, name = null, description = null } = siteDetails || {};
|
|
43
43
|
const siteId = ID ? String(ID) : null;
|
|
@@ -127,7 +127,7 @@ For example: user's prompt: A logo for an ice cream shop. Returned prompt: A log
|
|
|
127
127
|
throw error;
|
|
128
128
|
}
|
|
129
129
|
};
|
|
130
|
-
const generateImage = useCallback(async function ({ prompt, }) {
|
|
130
|
+
const generateImage = useCallback(async function ({ prompt, style = null, }) {
|
|
131
131
|
setLogoFetchError(null);
|
|
132
132
|
try {
|
|
133
133
|
const tokenData = await requestJwt();
|
|
@@ -148,6 +148,7 @@ User request:${prompt}`;
|
|
|
148
148
|
prompt: imageGenerationPrompt,
|
|
149
149
|
feature: 'jetpack-ai-logo-generator',
|
|
150
150
|
response_format: 'b64_json',
|
|
151
|
+
style: style || '', // backend expects an empty string if no style is provided
|
|
151
152
|
};
|
|
152
153
|
const data = await generateImageWithParameters(body);
|
|
153
154
|
return data;
|
|
@@ -212,7 +213,7 @@ User request:${prompt}`;
|
|
|
212
213
|
addLogoToHistory(logo);
|
|
213
214
|
stashLogo({ ...logo, siteId: String(siteId) });
|
|
214
215
|
}, [siteId, addLogoToHistory, stashLogo]);
|
|
215
|
-
const generateLogo = useCallback(async function ({ prompt }) {
|
|
216
|
+
const generateLogo = useCallback(async function ({ prompt, style, }) {
|
|
216
217
|
debug('Generating logo for site');
|
|
217
218
|
setIsRequestingImage(true);
|
|
218
219
|
try {
|
|
@@ -222,7 +223,7 @@ User request:${prompt}`;
|
|
|
222
223
|
increaseAiAssistantRequestsCount(logoGenerationCost);
|
|
223
224
|
let image;
|
|
224
225
|
try {
|
|
225
|
-
image = await generateImage({ prompt });
|
|
226
|
+
image = await generateImage({ prompt, style });
|
|
226
227
|
if (!image || !image.data.length) {
|
|
227
228
|
throw new Error('No image returned');
|
|
228
229
|
}
|
|
@@ -286,6 +287,7 @@ User request:${prompt}`;
|
|
|
286
287
|
tierPlansEnabled,
|
|
287
288
|
isLoadingHistory,
|
|
288
289
|
setIsLoadingHistory,
|
|
290
|
+
getImageStyles,
|
|
289
291
|
};
|
|
290
292
|
};
|
|
291
293
|
export default useLogoGenerator;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@automattic/jetpack-ai-client",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.20.0",
|
|
5
5
|
"description": "A JS client for consuming Jetpack AI services",
|
|
6
6
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/ai-client/#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"types": "./build/index.d.ts",
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@automattic/jetpack-base-styles": "^0.6.32",
|
|
47
|
-
"@automattic/jetpack-connection": "^0.35.
|
|
48
|
-
"@automattic/jetpack-shared-extension-utils": "^0.15.
|
|
47
|
+
"@automattic/jetpack-connection": "^0.35.10",
|
|
48
|
+
"@automattic/jetpack-shared-extension-utils": "^0.15.11",
|
|
49
49
|
"@microsoft/fetch-event-source": "2.0.1",
|
|
50
50
|
"@types/react": "18.3.3",
|
|
51
51
|
"@types/wordpress__block-editor": "11.5.15",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
|
|
3
|
+
// Styles
|
|
4
|
+
export const IMAGE_STYLE_ENHANCE = 'enhance';
|
|
5
|
+
export const IMAGE_STYLE_ANIME = 'anime';
|
|
6
|
+
export const IMAGE_STYLE_PHOTOGRAPHIC = 'photographic';
|
|
7
|
+
export const IMAGE_STYLE_DIGITAL_ART = 'digital-art';
|
|
8
|
+
export const IMAGE_STYLE_COMICBOOK = 'comicbook';
|
|
9
|
+
export const IMAGE_STYLE_FANTASY_ART = 'fantasy-art';
|
|
10
|
+
export const IMAGE_STYLE_ANALOG_FILM = 'analog-film';
|
|
11
|
+
export const IMAGE_STYLE_NEONPUNK = 'neonpunk';
|
|
12
|
+
export const IMAGE_STYLE_ISOMETRIC = 'isometric';
|
|
13
|
+
export const IMAGE_STYLE_LOWPOLY = 'lowpoly';
|
|
14
|
+
export const IMAGE_STYLE_ORIGAMI = 'origami';
|
|
15
|
+
export const IMAGE_STYLE_LINE_ART = 'line-art';
|
|
16
|
+
export const IMAGE_STYLE_CRAFT_CLAY = 'craft-clay';
|
|
17
|
+
export const IMAGE_STYLE_CINEMATIC = 'cinematic';
|
|
18
|
+
export const IMAGE_STYLE_3D_MODEL = '3d-model';
|
|
19
|
+
export const IMAGE_STYLE_PIXEL_ART = 'pixel-art';
|
|
20
|
+
export const IMAGE_STYLE_TEXTURE = 'texture';
|
|
21
|
+
export const IMAGE_STYLE_MONTY_PYTHON = 'monty-python';
|
|
22
|
+
|
|
23
|
+
export const IMAGE_STYLE_LABELS = {
|
|
24
|
+
[ IMAGE_STYLE_ENHANCE ]: __( 'Enhance', 'jetpack-ai-client' ),
|
|
25
|
+
[ IMAGE_STYLE_ANIME ]: __( 'Anime', 'jetpack-ai-client' ),
|
|
26
|
+
[ IMAGE_STYLE_PHOTOGRAPHIC ]: __( 'Photographic', 'jetpack-ai-client' ),
|
|
27
|
+
[ IMAGE_STYLE_DIGITAL_ART ]: __( 'Digital Art', 'jetpack-ai-client' ),
|
|
28
|
+
[ IMAGE_STYLE_COMICBOOK ]: __( 'Comicbook', 'jetpack-ai-client' ),
|
|
29
|
+
[ IMAGE_STYLE_FANTASY_ART ]: __( 'Fantasy Art', 'jetpack-ai-client' ),
|
|
30
|
+
[ IMAGE_STYLE_ANALOG_FILM ]: __( 'Analog Film', 'jetpack-ai-client' ),
|
|
31
|
+
[ IMAGE_STYLE_NEONPUNK ]: __( 'Neon Punk', 'jetpack-ai-client' ),
|
|
32
|
+
[ IMAGE_STYLE_ISOMETRIC ]: __( 'Isometric', 'jetpack-ai-client' ),
|
|
33
|
+
[ IMAGE_STYLE_LOWPOLY ]: __( 'Low Poly', 'jetpack-ai-client' ),
|
|
34
|
+
[ IMAGE_STYLE_ORIGAMI ]: __( 'Origami', 'jetpack-ai-client' ),
|
|
35
|
+
[ IMAGE_STYLE_LINE_ART ]: __( 'Line Art', 'jetpack-ai-client' ),
|
|
36
|
+
[ IMAGE_STYLE_CRAFT_CLAY ]: __( 'Craft Clay', 'jetpack-ai-client' ),
|
|
37
|
+
[ IMAGE_STYLE_CINEMATIC ]: __( 'Cinematic', 'jetpack-ai-client' ),
|
|
38
|
+
[ IMAGE_STYLE_3D_MODEL ]: __( '3D Model', 'jetpack-ai-client' ),
|
|
39
|
+
[ IMAGE_STYLE_PIXEL_ART ]: __( 'Pixel Art', 'jetpack-ai-client' ),
|
|
40
|
+
[ IMAGE_STYLE_TEXTURE ]: __( 'Texture', 'jetpack-ai-client' ),
|
|
41
|
+
[ IMAGE_STYLE_MONTY_PYTHON ]: __( 'Monty Python', 'jetpack-ai-client' ),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type ImageStyle = keyof typeof IMAGE_STYLE_LABELS;
|
|
@@ -7,6 +7,7 @@ import debugFactory from 'debug';
|
|
|
7
7
|
*/
|
|
8
8
|
import askQuestionSync from '../../ask-question/sync.js';
|
|
9
9
|
import requestJwt from '../../jwt/index.js';
|
|
10
|
+
import { IMAGE_STYLE_LABELS } from './constants.js';
|
|
10
11
|
|
|
11
12
|
const debug = debugFactory( 'ai-client:use-image-generator' );
|
|
12
13
|
|
|
@@ -255,11 +256,22 @@ const useImageGenerator = () => {
|
|
|
255
256
|
}
|
|
256
257
|
};
|
|
257
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Get available styles.
|
|
261
|
+
*
|
|
262
|
+
* @return {object} with the styles {key:label} for the image generation.
|
|
263
|
+
*/
|
|
264
|
+
const getImageStyles = function (): object {
|
|
265
|
+
return IMAGE_STYLE_LABELS;
|
|
266
|
+
};
|
|
267
|
+
|
|
258
268
|
return {
|
|
259
269
|
generateImage,
|
|
260
270
|
generateImageWithStableDiffusion,
|
|
261
271
|
generateImageWithParameters: executeImageGeneration,
|
|
272
|
+
getImageStyles,
|
|
262
273
|
};
|
|
263
274
|
};
|
|
264
275
|
|
|
265
276
|
export default useImageGenerator;
|
|
277
|
+
export * from './constants.js';
|
|
@@ -49,6 +49,7 @@ export const GeneratorModal: React.FC< GeneratorModalProps > = ( {
|
|
|
49
49
|
siteDetails,
|
|
50
50
|
context,
|
|
51
51
|
placement,
|
|
52
|
+
showStyleSelector,
|
|
52
53
|
} ) => {
|
|
53
54
|
const { tracks } = useAnalytics();
|
|
54
55
|
const { recordEvent: recordTracksEvent } = tracks;
|
|
@@ -242,7 +243,9 @@ export const GeneratorModal: React.FC< GeneratorModalProps > = ( {
|
|
|
242
243
|
} else {
|
|
243
244
|
body = (
|
|
244
245
|
<>
|
|
245
|
-
{ ! logoAccepted &&
|
|
246
|
+
{ ! logoAccepted && (
|
|
247
|
+
<Prompt initialPrompt={ initialPrompt } showStyleSelector={ showStyleSelector } />
|
|
248
|
+
) }
|
|
246
249
|
|
|
247
250
|
<LogoPresenter
|
|
248
251
|
logo={ selectedLogo }
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
.jetpack-ai-logo-generator__prompt-header {
|
|
11
11
|
display: flex;
|
|
12
|
-
|
|
13
|
-
align-items:
|
|
14
|
-
align-self: stretch;
|
|
12
|
+
gap: 16px;
|
|
13
|
+
align-items: center;
|
|
15
14
|
|
|
16
15
|
.jetpack-ai-logo-generator__prompt-label {
|
|
17
16
|
font-weight: 500;
|
|
17
|
+
flex-grow: 1;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.jetpack-ai-logo-generator__prompt-actions {
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
|
|
25
25
|
.jetpack-ai-logo-generator-icon {
|
|
26
26
|
margin-right: 4px;
|
|
27
|
+
// the svg icon with this class has no fill, only paths
|
|
28
|
+
stroke: currentColor;
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
5
|
-
import { Button, Tooltip } from '@wordpress/components';
|
|
5
|
+
import { Button, Tooltip, SelectControl } from '@wordpress/components';
|
|
6
6
|
import { __, sprintf } from '@wordpress/i18n';
|
|
7
7
|
import { Icon, info } from '@wordpress/icons';
|
|
8
8
|
import debugFactory from 'debug';
|
|
@@ -10,12 +10,17 @@ import { useCallback, useEffect, useState, useRef } from 'react';
|
|
|
10
10
|
/**
|
|
11
11
|
* Internal dependencies
|
|
12
12
|
*/
|
|
13
|
+
import {
|
|
14
|
+
IMAGE_STYLE_MONTY_PYTHON,
|
|
15
|
+
IMAGE_STYLE_LINE_ART,
|
|
16
|
+
} from '../../hooks/use-image-generator/constants.js';
|
|
13
17
|
import AiIcon from '../assets/icons/ai.js';
|
|
14
18
|
import {
|
|
15
19
|
EVENT_GENERATE,
|
|
16
20
|
MINIMUM_PROMPT_LENGTH,
|
|
17
21
|
EVENT_UPGRADE,
|
|
18
22
|
EVENT_PLACEMENT_INPUT_FOOTER,
|
|
23
|
+
EVENT_SWITCH_STYLE,
|
|
19
24
|
} from '../constants.js';
|
|
20
25
|
import { useCheckout } from '../hooks/use-checkout.js';
|
|
21
26
|
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
@@ -23,10 +28,19 @@ import useRequestErrors from '../hooks/use-request-errors.js';
|
|
|
23
28
|
import { FairUsageNotice } from './fair-usage-notice.js';
|
|
24
29
|
import { UpgradeNudge } from './upgrade-nudge.js';
|
|
25
30
|
import './prompt.scss';
|
|
31
|
+
/**
|
|
32
|
+
* Types
|
|
33
|
+
*/
|
|
34
|
+
import type { ImageStyle } from '../../hooks/use-image-generator/constants.js';
|
|
26
35
|
|
|
27
36
|
const debug = debugFactory( 'jetpack-ai-calypso:prompt-box' );
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
type PromptProps = {
|
|
39
|
+
initialPrompt?: string;
|
|
40
|
+
showStyleSelector?: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const Prompt = ( { initialPrompt = '', showStyleSelector = false }: PromptProps ) => {
|
|
30
44
|
const { tracks } = useAnalytics();
|
|
31
45
|
const { recordEvent: recordTracksEvent } = tracks;
|
|
32
46
|
const [ prompt, setPrompt ] = useState< string >( initialPrompt );
|
|
@@ -34,6 +48,9 @@ export const Prompt: React.FC< { initialPrompt?: string } > = ( { initialPrompt
|
|
|
34
48
|
const { enhancePromptFetchError, logoFetchError } = useRequestErrors();
|
|
35
49
|
const { nextTierCheckoutURL: checkoutUrl, hasNextTier } = useCheckout();
|
|
36
50
|
const hasPrompt = prompt?.length >= MINIMUM_PROMPT_LENGTH;
|
|
51
|
+
const [ style, setStyle ] = useState< ImageStyle >(
|
|
52
|
+
showStyleSelector ? IMAGE_STYLE_LINE_ART : null
|
|
53
|
+
);
|
|
37
54
|
|
|
38
55
|
const {
|
|
39
56
|
generateLogo,
|
|
@@ -46,6 +63,7 @@ export const Prompt: React.FC< { initialPrompt?: string } > = ( { initialPrompt
|
|
|
46
63
|
requireUpgrade,
|
|
47
64
|
context,
|
|
48
65
|
tierPlansEnabled,
|
|
66
|
+
getImageStyles,
|
|
49
67
|
} = useLogoGenerator();
|
|
50
68
|
|
|
51
69
|
const enhancingLabel = __( 'Enhancing…', 'jetpack-ai-client' );
|
|
@@ -91,9 +109,10 @@ export const Prompt: React.FC< { initialPrompt?: string } > = ( { initialPrompt
|
|
|
91
109
|
}, [ prompt ] );
|
|
92
110
|
|
|
93
111
|
const onGenerate = useCallback( async () => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
// shouldn't tool be "logo-generator" to be more specific?
|
|
113
|
+
recordTracksEvent( EVENT_GENERATE, { context, tool: 'image', style } );
|
|
114
|
+
generateLogo( { prompt, style } );
|
|
115
|
+
}, [ context, generateLogo, prompt, style ] );
|
|
97
116
|
|
|
98
117
|
const onPromptInput = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
99
118
|
setPrompt( event.target.textContent || '' );
|
|
@@ -122,6 +141,20 @@ export const Prompt: React.FC< { initialPrompt?: string } > = ( { initialPrompt
|
|
|
122
141
|
recordTracksEvent( EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_INPUT_FOOTER } );
|
|
123
142
|
};
|
|
124
143
|
|
|
144
|
+
const updateStyle = useCallback(
|
|
145
|
+
( imageStyle: ImageStyle ) => {
|
|
146
|
+
debug( 'change style', imageStyle );
|
|
147
|
+
setStyle( imageStyle );
|
|
148
|
+
recordTracksEvent( EVENT_SWITCH_STYLE, { context, style: imageStyle } );
|
|
149
|
+
},
|
|
150
|
+
[ context, setStyle, recordTracksEvent ]
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const imageStyles = getImageStyles();
|
|
154
|
+
const availableStyles = Object.keys( imageStyles ).filter(
|
|
155
|
+
( styleKey: ImageStyle ) => styleKey !== IMAGE_STYLE_MONTY_PYTHON
|
|
156
|
+
);
|
|
157
|
+
|
|
125
158
|
return (
|
|
126
159
|
<div className="jetpack-ai-logo-generator__prompt">
|
|
127
160
|
<div className="jetpack-ai-logo-generator__prompt-header">
|
|
@@ -135,9 +168,21 @@ export const Prompt: React.FC< { initialPrompt?: string } > = ( { initialPrompt
|
|
|
135
168
|
onClick={ onEnhance }
|
|
136
169
|
>
|
|
137
170
|
<AiIcon />
|
|
138
|
-
|
|
171
|
+
{ enhanceButtonLabel }
|
|
139
172
|
</Button>
|
|
140
173
|
</div>
|
|
174
|
+
{ showStyleSelector && availableStyles && (
|
|
175
|
+
<SelectControl
|
|
176
|
+
// label={ __( 'Style', 'jetpack-ai-client' ) }
|
|
177
|
+
__nextHasNoMarginBottom
|
|
178
|
+
value={ style }
|
|
179
|
+
options={ availableStyles.map( imageStyle => ( {
|
|
180
|
+
label: imageStyles[ imageStyle ],
|
|
181
|
+
value: imageStyle,
|
|
182
|
+
} ) ) }
|
|
183
|
+
onChange={ updateStyle }
|
|
184
|
+
/>
|
|
185
|
+
) }
|
|
141
186
|
</div>
|
|
142
187
|
<div className="jetpack-ai-logo-generator__prompt-query">
|
|
143
188
|
<div
|
|
@@ -10,6 +10,7 @@ export const EVENT_USE = 'jetpack_ai_logo_generator_use';
|
|
|
10
10
|
export const EVENT_NAVIGATE = 'jetpack_ai_logo_generator_navigate';
|
|
11
11
|
export const EVENT_FEEDBACK = 'jetpack_ai_logo_generator_feedback';
|
|
12
12
|
export const EVENT_UPGRADE = 'jetpack_ai_upgrade_button';
|
|
13
|
+
export const EVENT_SWITCH_STYLE = 'jetpack_ai_logo_generator_switch_style';
|
|
13
14
|
|
|
14
15
|
// Event placement constants
|
|
15
16
|
export const EVENT_PLACEMENT_QUICK_LINKS = 'quick_links';
|
|
@@ -17,6 +17,7 @@ import useRequestErrors from './use-request-errors.js';
|
|
|
17
17
|
/**
|
|
18
18
|
* Types
|
|
19
19
|
*/
|
|
20
|
+
import type { ImageStyle } from '../../hooks/use-image-generator/constants.js';
|
|
20
21
|
import type { Logo, Selectors, SaveLogo } from '../store/types.js';
|
|
21
22
|
|
|
22
23
|
const debug = debugFactory( 'jetpack-ai-calypso:use-logo-generator' );
|
|
@@ -78,7 +79,7 @@ const useLogoGenerator = () => {
|
|
|
78
79
|
setLogoUpdateError,
|
|
79
80
|
} = useRequestErrors();
|
|
80
81
|
|
|
81
|
-
const { generateImageWithParameters } = useImageGenerator();
|
|
82
|
+
const { generateImageWithParameters, getImageStyles } = useImageGenerator();
|
|
82
83
|
const { saveToMediaLibrary } = useSaveToMediaLibrary();
|
|
83
84
|
|
|
84
85
|
const { ID = null, name = null, description = null } = siteDetails || {};
|
|
@@ -193,8 +194,10 @@ For example: user's prompt: A logo for an ice cream shop. Returned prompt: A log
|
|
|
193
194
|
|
|
194
195
|
const generateImage = useCallback( async function ( {
|
|
195
196
|
prompt,
|
|
197
|
+
style = null,
|
|
196
198
|
}: {
|
|
197
199
|
prompt: string;
|
|
200
|
+
style?: ImageStyle | null;
|
|
198
201
|
} ): Promise< { data: Array< { url: string } > } > {
|
|
199
202
|
setLogoFetchError( null );
|
|
200
203
|
|
|
@@ -221,6 +224,7 @@ User request:${ prompt }`;
|
|
|
221
224
|
prompt: imageGenerationPrompt,
|
|
222
225
|
feature: 'jetpack-ai-logo-generator',
|
|
223
226
|
response_format: 'b64_json',
|
|
227
|
+
style: style || '', // backend expects an empty string if no style is provided
|
|
224
228
|
};
|
|
225
229
|
|
|
226
230
|
const data = await generateImageWithParameters( body );
|
|
@@ -309,7 +313,13 @@ User request:${ prompt }`;
|
|
|
309
313
|
);
|
|
310
314
|
|
|
311
315
|
const generateLogo = useCallback(
|
|
312
|
-
async function ( {
|
|
316
|
+
async function ( {
|
|
317
|
+
prompt,
|
|
318
|
+
style,
|
|
319
|
+
}: {
|
|
320
|
+
prompt: string;
|
|
321
|
+
style?: ImageStyle | null;
|
|
322
|
+
} ): Promise< void > {
|
|
313
323
|
debug( 'Generating logo for site' );
|
|
314
324
|
|
|
315
325
|
setIsRequestingImage( true );
|
|
@@ -324,7 +334,7 @@ User request:${ prompt }`;
|
|
|
324
334
|
let image;
|
|
325
335
|
|
|
326
336
|
try {
|
|
327
|
-
image = await generateImage( { prompt } );
|
|
337
|
+
image = await generateImage( { prompt, style } );
|
|
328
338
|
|
|
329
339
|
if ( ! image || ! image.data.length ) {
|
|
330
340
|
throw new Error( 'No image returned' );
|
|
@@ -391,6 +401,7 @@ User request:${ prompt }`;
|
|
|
391
401
|
tierPlansEnabled,
|
|
392
402
|
isLoadingHistory,
|
|
393
403
|
setIsLoadingHistory,
|
|
404
|
+
getImageStyles,
|
|
394
405
|
};
|
|
395
406
|
};
|
|
396
407
|
|