@automattic/jetpack-ai-client 0.25.7 → 0.26.1
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 +13 -0
- package/build/components/ai-icon/index.d.ts +10 -0
- package/build/components/ai-icon/index.js +16 -0
- package/build/components/ai-image/components/ai-image-modal.d.ts +57 -0
- package/build/components/ai-image/components/ai-image-modal.js +92 -0
- package/build/components/ai-image/components/carrousel.d.ts +28 -0
- package/build/components/ai-image/components/carrousel.js +69 -0
- package/build/components/ai-image/components/usage-counter.d.ts +16 -0
- package/build/components/ai-image/components/usage-counter.js +29 -0
- package/build/components/ai-image/featured-image.d.ts +17 -0
- package/build/components/ai-image/featured-image.js +278 -0
- package/build/components/ai-image/general-purpose-image.d.ts +23 -0
- package/build/components/ai-image/general-purpose-image.js +184 -0
- package/build/components/ai-image/hooks/use-ai-image.d.ts +48 -0
- package/build/components/ai-image/hooks/use-ai-image.js +219 -0
- package/build/components/ai-image/hooks/use-site-type.d.ts +6 -0
- package/build/components/ai-image/hooks/use-site-type.js +23 -0
- package/build/components/ai-image/index.d.ts +4 -0
- package/build/components/ai-image/index.js +4 -0
- package/build/components/ai-image/types.d.ts +16 -0
- package/build/components/ai-image/types.js +6 -0
- package/build/{ai-client/src/components → components}/index.d.ts +4 -0
- package/build/{ai-client/src/components → components}/index.js +4 -0
- package/build/components/modal/index.d.ts +18 -0
- package/build/components/modal/index.js +23 -0
- package/build/components/quota-exceeded-message/index.d.ts +13 -0
- package/build/components/quota-exceeded-message/index.js +152 -0
- package/build/components/quota-exceeded-message/light-nudge.d.ts +11 -0
- package/build/components/quota-exceeded-message/light-nudge.js +8 -0
- package/build/{ai-client/src/constants.d.ts → constants.d.ts} +3 -0
- package/build/{ai-client/src/constants.js → constants.js} +4 -0
- package/build/hooks/use-ai-checkout/index.d.ts +13 -0
- package/build/hooks/use-ai-checkout/index.js +41 -0
- package/build/hooks/use-ai-feature/index.d.ts +33 -0
- package/build/hooks/use-ai-feature/index.js +37 -0
- package/build/hooks/use-post-content.d.ts +5 -0
- package/build/hooks/use-post-content.js +20 -0
- package/build/hooks/use-save-to-media-library.d.ts +12 -0
- package/build/hooks/use-save-to-media-library.js +74 -0
- package/build/{ai-client/src/index.d.ts → index.d.ts} +3 -0
- package/build/{ai-client/src/index.js → index.js} +3 -0
- package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.js +1 -1
- package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.js +1 -1
- package/package.json +20 -14
- package/src/components/ai-icon/index.tsx +39 -0
- package/src/components/ai-image/components/ai-image-modal.scss +88 -0
- package/src/components/ai-image/components/ai-image-modal.tsx +240 -0
- package/src/components/ai-image/components/carrousel.scss +163 -0
- package/src/components/ai-image/components/carrousel.tsx +217 -0
- package/src/components/ai-image/components/usage-counter.scss +19 -0
- package/src/components/ai-image/components/usage-counter.tsx +54 -0
- package/src/components/ai-image/featured-image.tsx +439 -0
- package/src/components/ai-image/general-purpose-image.tsx +303 -0
- package/src/components/ai-image/hooks/use-ai-image.ts +339 -0
- package/src/components/ai-image/hooks/use-site-type.ts +26 -0
- package/src/components/ai-image/index.ts +10 -0
- package/src/components/ai-image/style.scss +95 -0
- package/src/components/ai-image/types.ts +19 -0
- package/src/components/index.ts +12 -0
- package/src/components/modal/index.tsx +70 -0
- package/src/components/modal/style.scss +45 -0
- package/src/components/quota-exceeded-message/index.tsx +319 -0
- package/src/components/quota-exceeded-message/light-nudge.tsx +38 -0
- package/src/components/quota-exceeded-message/style.scss +35 -0
- package/src/constants.ts +5 -0
- package/src/hooks/use-ai-checkout/index.ts +65 -0
- package/src/hooks/use-ai-feature/Readme.md +20 -0
- package/src/hooks/use-ai-feature/index.ts +62 -0
- package/src/hooks/use-post-content.ts +27 -0
- package/src/hooks/use-save-to-media-library.ts +100 -0
- package/src/index.ts +3 -0
- package/src/logo-generator/components/upgrade-screen.tsx +1 -1
- package/src/logo-generator/hooks/use-fair-usage-notice-message.tsx +1 -1
- package/build/components/tools/jp-redirect/index.d.ts +0 -20
- package/build/components/tools/jp-redirect/index.js +0 -50
- package/build/components/tools/jp-redirect/types.d.ts +0 -39
- package/build/components/tools/jp-redirect/types.js +0 -1
- /package/build/{ai-client/src/api-fetch → api-fetch}/index.d.ts +0 -0
- /package/build/{ai-client/src/api-fetch → api-fetch}/index.js +0 -0
- /package/build/{ai-client/src/ask-question → ask-question}/index.d.ts +0 -0
- /package/build/{ai-client/src/ask-question → ask-question}/index.js +0 -0
- /package/build/{ai-client/src/ask-question → ask-question}/sync.d.ts +0 -0
- /package/build/{ai-client/src/ask-question → ask-question}/sync.js +0 -0
- /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.d.ts +0 -0
- /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/ai-control.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/ai-control.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-control/index.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-feedback/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-feedback/index.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-modal-footer/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-modal-footer/index.js +0 -0
- /package/build/{ai-client/src/components → components}/ai-status-indicator/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/ai-status-indicator/index.js +0 -0
- /package/build/{ai-client/src/components → components}/audio-duration-display/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/audio-duration-display/index.js +0 -0
- /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.js +0 -0
- /package/build/{ai-client/src/components → components}/message/index.d.ts +0 -0
- /package/build/{ai-client/src/components → components}/message/index.js +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/context.d.ts +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/context.js +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/index.d.ts +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/index.js +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.d.ts +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.js +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.d.ts +0 -0
- /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.js +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.d.ts +0 -0
- /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.js +0 -0
- /package/build/{ai-client/src/icons → icons}/ai-assistant.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/ai-assistant.js +0 -0
- /package/build/{ai-client/src/icons → icons}/error-exclamation.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/error-exclamation.js +0 -0
- /package/build/{ai-client/src/icons → icons}/index.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/index.js +0 -0
- /package/build/{ai-client/src/icons → icons}/mic.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/mic.js +0 -0
- /package/build/{ai-client/src/icons → icons}/origami-plane.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/origami-plane.js +0 -0
- /package/build/{ai-client/src/icons → icons}/player-pause.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/player-pause.js +0 -0
- /package/build/{ai-client/src/icons → icons}/player-play.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/player-play.js +0 -0
- /package/build/{ai-client/src/icons → icons}/player-stop.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/player-stop.js +0 -0
- /package/build/{ai-client/src/icons → icons}/speak-tone.d.ts +0 -0
- /package/build/{ai-client/src/icons → icons}/speak-tone.js +0 -0
- /package/build/{ai-client/src/jwt → jwt}/index.d.ts +0 -0
- /package/build/{ai-client/src/jwt → jwt}/index.js +0 -0
- /package/build/{ai-client/src/libs → libs}/index.d.ts +0 -0
- /package/build/{ai-client/src/libs → libs}/index.js +0 -0
- /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.d.ts +0 -0
- /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.js +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.d.ts +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.js +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/index.d.ts +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/index.js +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.d.ts +0 -0
- /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/constants.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/constants.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/index.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/index.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.js +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/types.d.ts +0 -0
- /package/build/{ai-client/src/logo-generator → logo-generator}/types.js +0 -0
- /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.d.ts +0 -0
- /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.js +0 -0
- /package/build/{ai-client/src/types.d.ts → types.d.ts} +0 -0
- /package/build/{ai-client/src/types.js → types.js} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import './style.scss';
|
|
5
|
+
/**
|
|
6
|
+
* The type for the callback function that is called when the user selects an image.
|
|
7
|
+
*/
|
|
8
|
+
type SetImageCallbackProps = {
|
|
9
|
+
id: number;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
12
|
+
type GeneralPurposeImageProps = {
|
|
13
|
+
placement: string;
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
onSetImage?: (image: SetImageCallbackProps) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* GeneralPurposeImage component
|
|
19
|
+
* @param {GeneralPurposeImageProps} props - The component properties.
|
|
20
|
+
* @return {React.ReactElement} - rendered component.
|
|
21
|
+
*/
|
|
22
|
+
export default function GeneralPurposeImage({ placement, onClose, onSetImage, }: GeneralPurposeImageProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics, PLAN_TYPE_UNLIMITED, usePlanType, } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button } from '@wordpress/components';
|
|
7
|
+
import { useCallback, useState } from '@wordpress/element';
|
|
8
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
9
|
+
import debugFactory from 'debug';
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import './style.scss';
|
|
14
|
+
import useAiFeature from '../../hooks/use-ai-feature/index.js';
|
|
15
|
+
import usePostContent from '../../hooks/use-post-content.js';
|
|
16
|
+
import useSaveToMediaLibrary from '../../hooks/use-save-to-media-library.js';
|
|
17
|
+
import AiImageModal from './components/ai-image-modal.js';
|
|
18
|
+
import useAiImage from './hooks/use-ai-image.js';
|
|
19
|
+
import useSiteType from './hooks/use-site-type.js';
|
|
20
|
+
import { IMAGE_GENERATION_MODEL_STABLE_DIFFUSION, IMAGE_GENERATION_MODEL_DALL_E_3, GENERAL_IMAGE_FEATURE_NAME, } from './types.js';
|
|
21
|
+
const debug = debugFactory('jetpack-ai:general-purpose-image');
|
|
22
|
+
/**
|
|
23
|
+
* GeneralPurposeImage component
|
|
24
|
+
* @param {GeneralPurposeImageProps} props - The component properties.
|
|
25
|
+
* @return {React.ReactElement} - rendered component.
|
|
26
|
+
*/
|
|
27
|
+
export default function GeneralPurposeImage({ placement, onClose = () => { }, onSetImage = () => { }, }) {
|
|
28
|
+
const [isFeaturedImageModalVisible, setIsFeaturedImageModalVisible] = useState(true);
|
|
29
|
+
const siteType = useSiteType();
|
|
30
|
+
const postContent = usePostContent();
|
|
31
|
+
const { saveToMediaLibrary } = useSaveToMediaLibrary();
|
|
32
|
+
const { tracks } = useAnalytics();
|
|
33
|
+
const { recordEvent } = tracks;
|
|
34
|
+
const [prompt, setPrompt] = useState('');
|
|
35
|
+
// Get feature data
|
|
36
|
+
const { requireUpgrade, requestsCount, requestsLimit, currentTier, costs } = useAiFeature();
|
|
37
|
+
const planType = usePlanType(currentTier);
|
|
38
|
+
const generalImageCost = costs?.[GENERAL_IMAGE_FEATURE_NAME]?.activeModel ?? 10;
|
|
39
|
+
const generalImageActiveModel = generalImageCost === costs?.[GENERAL_IMAGE_FEATURE_NAME]?.stableDiffusion
|
|
40
|
+
? IMAGE_GENERATION_MODEL_STABLE_DIFFUSION
|
|
41
|
+
: IMAGE_GENERATION_MODEL_DALL_E_3;
|
|
42
|
+
const isUnlimited = planType === PLAN_TYPE_UNLIMITED;
|
|
43
|
+
const requestsBalance = requestsLimit - requestsCount;
|
|
44
|
+
const notEnoughRequests = requestsBalance < generalImageCost;
|
|
45
|
+
const { current, setCurrent, processImageGeneration, handlePreviousImage, handleNextImage, currentImage, currentPointer, images, pointer, imageStyles, guessStyle, } = useAiImage({
|
|
46
|
+
cost: generalImageCost,
|
|
47
|
+
autoStart: false,
|
|
48
|
+
type: 'general-image-generation',
|
|
49
|
+
feature: GENERAL_IMAGE_FEATURE_NAME,
|
|
50
|
+
});
|
|
51
|
+
const hasPrompt = prompt.length >= 3;
|
|
52
|
+
const disableInput = notEnoughRequests || currentPointer?.generating || requireUpgrade;
|
|
53
|
+
const disableAction = disableInput || !hasPrompt;
|
|
54
|
+
const handleModalClose = useCallback(() => {
|
|
55
|
+
setIsFeaturedImageModalVisible(false);
|
|
56
|
+
onClose?.();
|
|
57
|
+
}, [onClose]);
|
|
58
|
+
const handleGenerate = useCallback(async ({ userPrompt, style }) => {
|
|
59
|
+
debug('handleGenerate', userPrompt, style);
|
|
60
|
+
// track the generate image event
|
|
61
|
+
recordEvent('jetpack_ai_general_image_generation_generate_image', {
|
|
62
|
+
placement,
|
|
63
|
+
model: generalImageActiveModel,
|
|
64
|
+
site_type: siteType,
|
|
65
|
+
style,
|
|
66
|
+
});
|
|
67
|
+
processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
|
|
68
|
+
recordEvent('jetpack_ai_general_image_generation_error', {
|
|
69
|
+
placement,
|
|
70
|
+
error: error?.message,
|
|
71
|
+
model: generalImageActiveModel,
|
|
72
|
+
site_type: siteType,
|
|
73
|
+
style,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}, [
|
|
77
|
+
recordEvent,
|
|
78
|
+
placement,
|
|
79
|
+
generalImageActiveModel,
|
|
80
|
+
siteType,
|
|
81
|
+
processImageGeneration,
|
|
82
|
+
postContent,
|
|
83
|
+
notEnoughRequests,
|
|
84
|
+
]);
|
|
85
|
+
const handleRegenerate = useCallback(({ userPrompt, style }) => {
|
|
86
|
+
debug('handleRegenerate', userPrompt);
|
|
87
|
+
// track the regenerate image event
|
|
88
|
+
recordEvent('jetpack_ai_general_image_generation_generate_another_image', {
|
|
89
|
+
placement,
|
|
90
|
+
model: generalImageActiveModel,
|
|
91
|
+
site_type: siteType,
|
|
92
|
+
style,
|
|
93
|
+
});
|
|
94
|
+
setCurrent(crrt => crrt + 1);
|
|
95
|
+
processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
|
|
96
|
+
recordEvent('jetpack_ai_general_image_generation_error', {
|
|
97
|
+
placement,
|
|
98
|
+
error: error?.message,
|
|
99
|
+
model: generalImageActiveModel,
|
|
100
|
+
site_type: siteType,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}, [
|
|
104
|
+
recordEvent,
|
|
105
|
+
placement,
|
|
106
|
+
generalImageActiveModel,
|
|
107
|
+
siteType,
|
|
108
|
+
processImageGeneration,
|
|
109
|
+
postContent,
|
|
110
|
+
notEnoughRequests,
|
|
111
|
+
setCurrent,
|
|
112
|
+
]);
|
|
113
|
+
const handleTryAgain = useCallback(({ userPrompt, style }) => {
|
|
114
|
+
debug('handleTryAgain', userPrompt);
|
|
115
|
+
// track the try again event
|
|
116
|
+
recordEvent('jetpack_ai_general_image_generation_try_again', {
|
|
117
|
+
placement,
|
|
118
|
+
model: generalImageActiveModel,
|
|
119
|
+
site_type: siteType,
|
|
120
|
+
style,
|
|
121
|
+
});
|
|
122
|
+
processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
|
|
123
|
+
recordEvent('jetpack_ai_general_image_generation_error', {
|
|
124
|
+
placement,
|
|
125
|
+
error: error?.message,
|
|
126
|
+
model: generalImageActiveModel,
|
|
127
|
+
site_type: siteType,
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}, [
|
|
131
|
+
recordEvent,
|
|
132
|
+
placement,
|
|
133
|
+
generalImageActiveModel,
|
|
134
|
+
siteType,
|
|
135
|
+
processImageGeneration,
|
|
136
|
+
postContent,
|
|
137
|
+
notEnoughRequests,
|
|
138
|
+
]);
|
|
139
|
+
const handleAccept = useCallback(() => {
|
|
140
|
+
// track the accept/use image event
|
|
141
|
+
recordEvent('jetpack_ai_general_image_generation_use_image', {
|
|
142
|
+
placement,
|
|
143
|
+
model: generalImageActiveModel,
|
|
144
|
+
site_type: siteType,
|
|
145
|
+
});
|
|
146
|
+
const setImage = image => {
|
|
147
|
+
onSetImage?.({ id: image.id, url: image.url });
|
|
148
|
+
handleModalClose();
|
|
149
|
+
};
|
|
150
|
+
// If the image is already in the media library, use it directly, if it failed for some reason
|
|
151
|
+
// save it to the media library and then use it.
|
|
152
|
+
if (currentImage?.libraryId) {
|
|
153
|
+
setImage({
|
|
154
|
+
id: currentImage?.libraryId,
|
|
155
|
+
url: currentImage?.libraryUrl,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
saveToMediaLibrary(currentImage?.image).then(image => {
|
|
160
|
+
setImage(image);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}, [
|
|
164
|
+
recordEvent,
|
|
165
|
+
placement,
|
|
166
|
+
generalImageActiveModel,
|
|
167
|
+
siteType,
|
|
168
|
+
currentImage?.libraryId,
|
|
169
|
+
currentImage?.libraryUrl,
|
|
170
|
+
currentImage?.image,
|
|
171
|
+
onSetImage,
|
|
172
|
+
handleModalClose,
|
|
173
|
+
saveToMediaLibrary,
|
|
174
|
+
]);
|
|
175
|
+
const generateAgainText = __('Generate another image', 'jetpack-ai-client');
|
|
176
|
+
const generateText = __('Generate', 'jetpack-ai-client');
|
|
177
|
+
const upgradeDescription = notEnoughRequests
|
|
178
|
+
? sprintf(
|
|
179
|
+
// Translators: %d is the cost of generating a featured image.
|
|
180
|
+
__("Image generation costs %d requests per image. You don't have enough requests to generate another image.", 'jetpack-ai-client'), generalImageCost)
|
|
181
|
+
: null;
|
|
182
|
+
const acceptButton = (_jsx(Button, { onClick: handleAccept, variant: "primary", disabled: !currentImage?.image || currentImage?.generating, children: __('Insert image', 'jetpack-ai-client') }));
|
|
183
|
+
return (_jsx(AiImageModal, { postContent: true, images: images, currentIndex: current, title: __('Generate an image with AI', 'jetpack-ai-client'), cost: generalImageCost, open: isFeaturedImageModalVisible, placement: placement, onClose: handleModalClose, onTryAgain: handleTryAgain, onGenerate: pointer?.current > 0 ? handleRegenerate : handleGenerate, generating: currentPointer?.generating, notEnoughRequests: notEnoughRequests, requireUpgrade: requireUpgrade, upgradeDescription: upgradeDescription, currentLimit: requestsLimit, currentUsage: requestsCount, isUnlimited: isUnlimited, hasError: Boolean(currentPointer?.error), handlePreviousImage: handlePreviousImage, handleNextImage: handleNextImage, acceptButton: acceptButton, generateButtonLabel: pointer?.current > 0 ? generateAgainText : generateText, instructionsPlaceholder: __("Describe the image you'd like to create and select a style.", 'jetpack-ai-client'), imageStyles: imageStyles, onGuessStyle: guessStyle, prompt: prompt, setPrompt: setPrompt, inputDisabled: disableInput, actionDisabled: disableAction }));
|
|
184
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ImageStyleObject, ImageStyle } from '../../../hooks/use-image-generator/constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Types
|
|
5
|
+
*/
|
|
6
|
+
import { FEATURED_IMAGE_FEATURE_NAME, GENERAL_IMAGE_FEATURE_NAME } from '../types.js';
|
|
7
|
+
import type { CarrouselImageData, CarrouselImages } from '../components/carrousel.js';
|
|
8
|
+
type AiImageType = 'featured-image-generation' | 'general-image-generation';
|
|
9
|
+
type AiImageFeature = typeof FEATURED_IMAGE_FEATURE_NAME | typeof GENERAL_IMAGE_FEATURE_NAME;
|
|
10
|
+
export type ImageResponse = {
|
|
11
|
+
image?: string;
|
|
12
|
+
libraryId?: string;
|
|
13
|
+
libraryUrl?: string;
|
|
14
|
+
revisedPrompt?: string;
|
|
15
|
+
};
|
|
16
|
+
type ProcessImageGenerationProps = {
|
|
17
|
+
userPrompt?: string | null;
|
|
18
|
+
postContent?: string | null;
|
|
19
|
+
notEnoughRequests: boolean;
|
|
20
|
+
style?: string;
|
|
21
|
+
};
|
|
22
|
+
type UseAiImageProps = {
|
|
23
|
+
feature: AiImageFeature;
|
|
24
|
+
type: AiImageType;
|
|
25
|
+
cost: number;
|
|
26
|
+
autoStart?: boolean;
|
|
27
|
+
previousMediaId?: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Hook to get properties for AiImage
|
|
31
|
+
*
|
|
32
|
+
* @param {UseAiImageProps} props - The component properties.
|
|
33
|
+
* @return {UseAiImageReturn} - Object containing properties for AiImage.
|
|
34
|
+
*/
|
|
35
|
+
export default function useAiImage({ feature, type, cost, autoStart, previousMediaId, }: UseAiImageProps): {
|
|
36
|
+
current: number;
|
|
37
|
+
setCurrent: React.Dispatch<React.SetStateAction<number>>;
|
|
38
|
+
processImageGeneration: ({ userPrompt, postContent, notEnoughRequests, style, }: ProcessImageGenerationProps) => Promise<ImageResponse>;
|
|
39
|
+
handlePreviousImage: () => void;
|
|
40
|
+
handleNextImage: () => void;
|
|
41
|
+
currentImage: CarrouselImageData;
|
|
42
|
+
currentPointer: CarrouselImageData;
|
|
43
|
+
images: CarrouselImages;
|
|
44
|
+
pointer: React.MutableRefObject<number>;
|
|
45
|
+
imageStyles: ImageStyleObject[];
|
|
46
|
+
guessStyle: (prompt: string, requestType?: string, content?: string) => Promise<ImageStyle | null>;
|
|
47
|
+
};
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
5
|
+
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { cleanForSlug } from '@wordpress/url';
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import askQuestionSync from '../../../ask-question/sync.js';
|
|
12
|
+
import useAiFeature from '../../../hooks/use-ai-feature/index.js';
|
|
13
|
+
import useImageGenerator from '../../../hooks/use-image-generator/index.js';
|
|
14
|
+
import useSaveToMediaLibrary from '../../../hooks/use-save-to-media-library.js';
|
|
15
|
+
/**
|
|
16
|
+
* Types
|
|
17
|
+
*/
|
|
18
|
+
import { FEATURED_IMAGE_FEATURE_NAME, } from '../types.js';
|
|
19
|
+
/**
|
|
20
|
+
* Hook to get properties for AiImage
|
|
21
|
+
*
|
|
22
|
+
* @param {UseAiImageProps} props - The component properties.
|
|
23
|
+
* @return {UseAiImageReturn} - Object containing properties for AiImage.
|
|
24
|
+
*/
|
|
25
|
+
export default function useAiImage({ feature, type, cost, autoStart = true, previousMediaId, }) {
|
|
26
|
+
const { generateImageWithParameters } = useImageGenerator();
|
|
27
|
+
const { increaseRequestsCount, featuresControl } = useAiFeature();
|
|
28
|
+
const { saveToMediaLibrary } = useSaveToMediaLibrary();
|
|
29
|
+
const { createNotice } = useDispatch('core/notices');
|
|
30
|
+
/* Images Control */
|
|
31
|
+
// pointer keeps track of request/generation iteration
|
|
32
|
+
const pointer = useRef(0);
|
|
33
|
+
// and current keeps track of what is the image exposed at the moment
|
|
34
|
+
// TODO: should current be any relevant here? It's just modal/carrousel logic after all
|
|
35
|
+
const [current, setCurrent] = useState(0);
|
|
36
|
+
const [images, setImages] = useState([{ generating: autoStart }]);
|
|
37
|
+
// map feature-to-control prop, if this goes over 2 options, make a hook for it
|
|
38
|
+
const featureControl = feature === FEATURED_IMAGE_FEATURE_NAME ? 'featured-image' : 'image';
|
|
39
|
+
const imageFeatureControl = featuresControl?.[featureControl];
|
|
40
|
+
const imageStyles = imageFeatureControl?.styles;
|
|
41
|
+
/* Merge the image data with the new data. */
|
|
42
|
+
const updateImages = useCallback((data, index) => {
|
|
43
|
+
setImages(currentImages => {
|
|
44
|
+
const newImages = [...currentImages];
|
|
45
|
+
newImages[index] = {
|
|
46
|
+
...newImages[index],
|
|
47
|
+
...data,
|
|
48
|
+
};
|
|
49
|
+
return newImages;
|
|
50
|
+
});
|
|
51
|
+
}, []);
|
|
52
|
+
// the selec/useEffect combo...
|
|
53
|
+
const loadedMedia = useSelect((select) => select('core')?.getMedia?.(previousMediaId), [previousMediaId]);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (loadedMedia) {
|
|
56
|
+
updateImages({
|
|
57
|
+
image: loadedMedia.source_url,
|
|
58
|
+
libraryId: loadedMedia.id,
|
|
59
|
+
libraryUrl: loadedMedia.source_url,
|
|
60
|
+
generating: false,
|
|
61
|
+
}, pointer.current);
|
|
62
|
+
}
|
|
63
|
+
}, [loadedMedia, updateImages]);
|
|
64
|
+
/*
|
|
65
|
+
* Function to show a snackbar notice on the editor.
|
|
66
|
+
*/
|
|
67
|
+
const showSnackbarNotice = useCallback((message) => {
|
|
68
|
+
createNotice('success', message, {
|
|
69
|
+
type: 'snackbar',
|
|
70
|
+
isDismissible: true,
|
|
71
|
+
});
|
|
72
|
+
}, [createNotice]);
|
|
73
|
+
/*
|
|
74
|
+
* Function to update the requests count after a featured image generation.
|
|
75
|
+
*/
|
|
76
|
+
const updateRequestsCount = useCallback(() => {
|
|
77
|
+
increaseRequestsCount(cost);
|
|
78
|
+
}, [increaseRequestsCount, cost]);
|
|
79
|
+
/*
|
|
80
|
+
* Function to suggest a name for the image based on the user prompt.
|
|
81
|
+
*/
|
|
82
|
+
const getImageNameSuggestion = useCallback((userPrompt) => {
|
|
83
|
+
if (!userPrompt) {
|
|
84
|
+
return 'image.png';
|
|
85
|
+
}
|
|
86
|
+
const truncatedPrompt = userPrompt.split(' ').slice(0, 10).join(' ');
|
|
87
|
+
return cleanForSlug(truncatedPrompt) + '.png';
|
|
88
|
+
}, []);
|
|
89
|
+
/*
|
|
90
|
+
* Function to generate a new image with the current value of the post content.
|
|
91
|
+
*/
|
|
92
|
+
const processImageGeneration = useCallback(({ userPrompt, postContent, notEnoughRequests, style = null, }) => {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
if (previousMediaId && pointer.current === 0) {
|
|
95
|
+
pointer.current++;
|
|
96
|
+
}
|
|
97
|
+
updateImages({ generating: true, error: null }, pointer.current);
|
|
98
|
+
// Ensure the site has enough requests to generate the image.
|
|
99
|
+
if (notEnoughRequests) {
|
|
100
|
+
updateImages({
|
|
101
|
+
generating: false,
|
|
102
|
+
error: new Error(__("You don't have enough requests to generate another image.", 'jetpack-ai-client')),
|
|
103
|
+
}, pointer.current);
|
|
104
|
+
resolve({});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Make a generic call to backend and let it decide the model.
|
|
109
|
+
*/
|
|
110
|
+
const generateImagePromise = generateImageWithParameters({
|
|
111
|
+
feature,
|
|
112
|
+
size: '1792x1024',
|
|
113
|
+
responseFormat: 'b64_json',
|
|
114
|
+
messages: [
|
|
115
|
+
{
|
|
116
|
+
role: 'jetpack-ai',
|
|
117
|
+
context: {
|
|
118
|
+
type,
|
|
119
|
+
request: userPrompt ? userPrompt : null,
|
|
120
|
+
content: postContent,
|
|
121
|
+
style,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
style: style || '',
|
|
126
|
+
});
|
|
127
|
+
const name = getImageNameSuggestion(userPrompt);
|
|
128
|
+
generateImagePromise
|
|
129
|
+
.then(result => {
|
|
130
|
+
if (result.data.length > 0) {
|
|
131
|
+
const image = 'data:image/png;base64,' + result.data[0].b64_json;
|
|
132
|
+
const prompt = userPrompt || null;
|
|
133
|
+
const revisedPrompt = result.data[0].revised_prompt || null;
|
|
134
|
+
updateImages({ image, prompt, revisedPrompt }, pointer.current);
|
|
135
|
+
updateRequestsCount();
|
|
136
|
+
saveToMediaLibrary(image, name)
|
|
137
|
+
.then(savedImage => {
|
|
138
|
+
showSnackbarNotice(__('Image saved to media library.', 'jetpack-ai-client'));
|
|
139
|
+
updateImages({ libraryId: savedImage?.id, libraryUrl: savedImage?.url, generating: false }, pointer.current);
|
|
140
|
+
pointer.current += 1;
|
|
141
|
+
resolve({
|
|
142
|
+
image,
|
|
143
|
+
libraryId: savedImage?.id,
|
|
144
|
+
libraryUrl: savedImage?.url,
|
|
145
|
+
revisedPrompt,
|
|
146
|
+
});
|
|
147
|
+
})
|
|
148
|
+
.catch(() => {
|
|
149
|
+
updateImages({ generating: false }, pointer.current);
|
|
150
|
+
pointer.current += 1;
|
|
151
|
+
resolve({ image });
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
.catch(e => {
|
|
156
|
+
updateImages({ generating: false, error: e }, pointer.current);
|
|
157
|
+
reject(e);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}, [
|
|
161
|
+
updateImages,
|
|
162
|
+
generateImageWithParameters,
|
|
163
|
+
feature,
|
|
164
|
+
type,
|
|
165
|
+
updateRequestsCount,
|
|
166
|
+
saveToMediaLibrary,
|
|
167
|
+
showSnackbarNotice,
|
|
168
|
+
getImageNameSuggestion,
|
|
169
|
+
previousMediaId,
|
|
170
|
+
]);
|
|
171
|
+
const handlePreviousImage = useCallback(() => {
|
|
172
|
+
setCurrent(Math.max(current - 1, 0));
|
|
173
|
+
}, [current]);
|
|
174
|
+
const handleNextImage = useCallback(() => {
|
|
175
|
+
setCurrent(Math.min(current + 1, images.length - 1));
|
|
176
|
+
}, [current, images.length]);
|
|
177
|
+
const guessStyle = useCallback(async function (prompt, requestType = '', content = '') {
|
|
178
|
+
if (!imageStyles || !imageStyles.length) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const messages = [
|
|
182
|
+
{
|
|
183
|
+
role: 'jetpack-ai',
|
|
184
|
+
context: {
|
|
185
|
+
type: requestType || 'general-image-guess-style',
|
|
186
|
+
request: prompt,
|
|
187
|
+
content,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
try {
|
|
192
|
+
const style = await askQuestionSync(messages, { feature: 'jetpack-ai-image-generator' });
|
|
193
|
+
if (!style) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
const styleObject = imageStyles.find(({ value }) => value === style);
|
|
197
|
+
if (!styleObject) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
return styleObject.value;
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
Promise.reject(error);
|
|
204
|
+
}
|
|
205
|
+
}, [imageStyles]);
|
|
206
|
+
return {
|
|
207
|
+
current,
|
|
208
|
+
setCurrent,
|
|
209
|
+
processImageGeneration,
|
|
210
|
+
handlePreviousImage,
|
|
211
|
+
handleNextImage,
|
|
212
|
+
currentImage: images[current],
|
|
213
|
+
currentPointer: images[pointer.current],
|
|
214
|
+
images,
|
|
215
|
+
pointer,
|
|
216
|
+
imageStyles,
|
|
217
|
+
guessStyle,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { isAtomicSite, isSimpleSite } from '@automattic/jetpack-shared-extension-utils';
|
|
5
|
+
import { useState } from '@wordpress/element';
|
|
6
|
+
/**
|
|
7
|
+
* Hook to get the type of site.
|
|
8
|
+
*
|
|
9
|
+
* @return {string} - The type of site.
|
|
10
|
+
*/
|
|
11
|
+
export default function useSiteType() {
|
|
12
|
+
const getSiteType = () => {
|
|
13
|
+
if (isAtomicSite()) {
|
|
14
|
+
return 'atomic';
|
|
15
|
+
}
|
|
16
|
+
if (isSimpleSite()) {
|
|
17
|
+
return 'simple';
|
|
18
|
+
}
|
|
19
|
+
return 'jetpack';
|
|
20
|
+
};
|
|
21
|
+
const [siteType] = useState(getSiteType());
|
|
22
|
+
return siteType;
|
|
23
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import FeaturedImage from './featured-image.js';
|
|
2
|
+
import GeneralPurposeImage from './general-purpose-image.js';
|
|
3
|
+
import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON } from './types.js';
|
|
4
|
+
export { FeaturedImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, GeneralPurposeImage, };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import FeaturedImage from './featured-image.js';
|
|
2
|
+
import GeneralPurposeImage from './general-purpose-image.js';
|
|
3
|
+
import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON } from './types.js';
|
|
4
|
+
export { FeaturedImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, GeneralPurposeImage, };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const FEATURED_IMAGE_FEATURE_NAME: "featured-post-image";
|
|
2
|
+
export declare const GENERAL_IMAGE_FEATURE_NAME: "general-image";
|
|
3
|
+
export declare const IMAGE_GENERATION_MODEL_STABLE_DIFFUSION: "stable-diffusion";
|
|
4
|
+
export declare const IMAGE_GENERATION_MODEL_DALL_E_3: "dall-e-3";
|
|
5
|
+
export declare const PLACEMENT_MEDIA_SOURCE_DROPDOWN: "media-source-dropdown";
|
|
6
|
+
export declare const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON: "block-placeholder-button";
|
|
7
|
+
export interface EditorSelectors {
|
|
8
|
+
getEditedPostAttribute: (attribute: string) => number;
|
|
9
|
+
isEditorPanelOpened: (panel: string) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface CoreSelectors {
|
|
12
|
+
getMedia: (mediaId: number) => {
|
|
13
|
+
id: number;
|
|
14
|
+
source_url: string;
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const FEATURED_IMAGE_FEATURE_NAME = 'featured-post-image';
|
|
2
|
+
export const GENERAL_IMAGE_FEATURE_NAME = 'general-image';
|
|
3
|
+
export const IMAGE_GENERATION_MODEL_STABLE_DIFFUSION = 'stable-diffusion';
|
|
4
|
+
export const IMAGE_GENERATION_MODEL_DALL_E_3 = 'dall-e-3';
|
|
5
|
+
export const PLACEMENT_MEDIA_SOURCE_DROPDOWN = 'media-source-dropdown';
|
|
6
|
+
export const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON = 'block-placeholder-button';
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { AIControl, BlockAIControl, ExtensionAIControl } from './ai-control/index.js';
|
|
2
2
|
export { default as AiFeedbackThumbs } from './ai-feedback/index.js';
|
|
3
|
+
export { default as AiIcon, AiSVG } from './ai-icon/index.js';
|
|
4
|
+
export { FeaturedImage, GeneralPurposeImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, } from './ai-image/index.js';
|
|
3
5
|
export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
|
|
4
6
|
export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
|
|
5
7
|
export { default as AiModalFooter } from './ai-modal-footer/index.js';
|
|
6
8
|
export { GuidelineMessage, UpgradeMessage, ErrorMessage, default as FooterMessage, } from './message/index.js';
|
|
9
|
+
export { default as AiAssistantModal } from './modal/index.js';
|
|
10
|
+
export { default as QuotaExceededMessage, FairUsageNotice, } from './quota-exceeded-message/index.js';
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { AIControl, BlockAIControl, ExtensionAIControl } from './ai-control/index.js';
|
|
2
2
|
export { default as AiFeedbackThumbs } from './ai-feedback/index.js';
|
|
3
|
+
export { default as AiIcon, AiSVG } from './ai-icon/index.js';
|
|
4
|
+
export { FeaturedImage, GeneralPurposeImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, } from './ai-image/index.js';
|
|
3
5
|
export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
|
|
4
6
|
export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
|
|
5
7
|
export { default as AiModalFooter } from './ai-modal-footer/index.js';
|
|
6
8
|
export { GuidelineMessage, UpgradeMessage, ErrorMessage, default as FooterMessage, } from './message/index.js';
|
|
9
|
+
export { default as AiAssistantModal } from './modal/index.js';
|
|
10
|
+
export { default as QuotaExceededMessage, FairUsageNotice, } from './quota-exceeded-message/index.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import type { RequestingStateProp } from '../../types.js';
|
|
3
|
+
import './style.scss';
|
|
4
|
+
type AiAssistantModalProps = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
handleClose: () => void;
|
|
7
|
+
hideHeader?: boolean;
|
|
8
|
+
requestingState?: RequestingStateProp;
|
|
9
|
+
title?: string;
|
|
10
|
+
maxWidth?: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* AiAssistantModal component
|
|
14
|
+
* @param {AiAssistantModalProps} props - The component properties.
|
|
15
|
+
* @return {React.ReactElement} - rendered component.
|
|
16
|
+
*/
|
|
17
|
+
export default function AiAssistantModal({ children, handleClose, hideHeader, requestingState, title, maxWidth, }: AiAssistantModalProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { Modal, Button } from '@wordpress/components';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { close } from '@wordpress/icons';
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import AiStatusIndicator from '../ai-status-indicator/index.js';
|
|
12
|
+
import './style.scss';
|
|
13
|
+
const ModalHeader = ({ requestingState, onClose, title, }) => {
|
|
14
|
+
return (_jsxs("div", { className: "ai-assistant-modal__header", children: [_jsxs("div", { className: "ai-assistant-modal__title-wrapper", children: [_jsx(AiStatusIndicator, { state: requestingState }), _jsx("h1", { className: "ai-assistant-modal__title", children: title })] }), _jsx(Button, { icon: close, label: __('Close', 'jetpack-ai-client'), onClick: onClose })] }));
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* AiAssistantModal component
|
|
18
|
+
* @param {AiAssistantModalProps} props - The component properties.
|
|
19
|
+
* @return {React.ReactElement} - rendered component.
|
|
20
|
+
*/
|
|
21
|
+
export default function AiAssistantModal({ children, handleClose, hideHeader = true, requestingState = 'init', title = __('AI Assistant', 'jetpack-ai-client'), maxWidth = 720, }) {
|
|
22
|
+
return (_jsx(Modal, { __experimentalHideHeader: hideHeader, className: "ai-assistant-modal", shouldCloseOnClickOutside: false, onRequestClose: handleClose, children: _jsxs("div", { className: "ai-assistant-modal__content", style: { maxWidth }, children: [_jsx(ModalHeader, { requestingState: requestingState, onClose: handleClose, title: title }), _jsx("hr", { className: "ai-assistant-modal__divider" }), children] }) }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import './style.scss';
|
|
2
|
+
type FairUsageNoticeProps = {
|
|
3
|
+
variant?: 'error' | 'muted';
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* The fair usage notice component.
|
|
7
|
+
* @param {FairUsageNoticeProps} props - Fair usage notice component props.
|
|
8
|
+
* @param {FairUsageNoticeProps.variant} props.variant - The variant of the notice to render.
|
|
9
|
+
* @return {ReactElement} the Notice component with the fair usage message.
|
|
10
|
+
*/
|
|
11
|
+
export declare const FairUsageNotice: ({ variant }: FairUsageNoticeProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
declare const QuotaExceededMessage: (props: any) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default QuotaExceededMessage;
|