Skip to content

Commit

Permalink
External Media: Move the external-media to the new @automattic/jetpac…
Browse files Browse the repository at this point in the history
…k-external-media package (#41078)

* External Media: Move OpenverseMedia to @automattic/jetpack-shared-extension-utils

* External Media: Move PexelsMedia to @automattic/jetpack-shared-extension-utils

* External Media: Move GooglePhotosMedia to @automattic/jetpack-shared-extension-utils

* changelog

* Fix textdomain

* Fix dependencies

* Fix the asset of the google-photos-picker-button

* Fix block assets

* Fix test of external-media

* Fix requestExternalAccess

* Fix GooglePhotosMediaIcon

* Introduce @automattic/jetpack-external-media

* Move all of external-media to @automattic/jetpack-shared-extension-utils

* changelog

* Fix dependencies

* Move all of external-media to @automattic/jetpack-external-media

* Fix lint

* Move store/wordpress-com to jetpack-ai-client

* Update projects/packages/external-media/.phan/baseline.php

* Fix types

* Fix apiFetch

* Fix the import of the jetpack-components under ai-client

* changelog

* Fix lint

* Fix block-nudge

* Fix build of @automattic/jetpack-external-media

* Fix tests

* Fix build of external-media

* Update pnpm-lock.yaml

* Fix translation

* Fix storybook

* changelog

* Load external-media assets

* Add external media module

* Add mirror repo

* Fix lint

* Move external-media module to module-extras.php

* Exclude babel.config.js on production

* Move number-control to jetpack-components

* Move libs/connection to jetpack-shared-extension-utils

* Update the comment of the external media module

* Move store/wordpress-com to jetpack-shared-extension-utils

* Use Connection_Initial_State::render_script to get rid of dependency

* Register JetpackExternalMediaData by external media package itself

* Update composer.lock

* Fix lint

* Export components and icons from subpath to resolve deps of the story block

* changelog
  • Loading branch information
arthur791004 authored Feb 5, 2025
1 parent 4967a2f commit 116f2cf
Show file tree
Hide file tree
Showing 197 changed files with 2,315 additions and 602 deletions.
562 changes: 562 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

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

Add shared components from ai-assistant-plugin
6 changes: 6 additions & 0 deletions projects/js-packages/ai-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,27 @@
"types": "./build/index.d.ts",
"dependencies": {
"@automattic/jetpack-base-styles": "workspace:*",
"@automattic/jetpack-components": "workspace:*",
"@automattic/jetpack-connection": "workspace:*",
"@automattic/jetpack-shared-extension-utils": "workspace:*",
"@microsoft/fetch-event-source": "2.0.1",
"@types/jest": "29.5.12",
"@types/react": "18.3.18",
"@types/wordpress__block-editor": "11.5.16",
"@wordpress/api-fetch": "7.17.0",
"@wordpress/base-styles": "5.17.0",
"@wordpress/blob": "4.17.0",
"@wordpress/blocks": "14.6.0",
"@wordpress/block-editor": "14.12.0",
"@wordpress/components": "29.3.0",
"@wordpress/compose": "7.17.0",
"@wordpress/data": "10.17.0",
"@wordpress/editor": "14.17.0",
"@wordpress/element": "6.17.0",
"@wordpress/i18n": "5.17.0",
"@wordpress/icons": "10.17.0",
"@wordpress/primitives": "4.17.0",
"@wordpress/url": "4.17.0",
"clsx": "2.1.1",
"debug": "4.4.0",
"markdown-it": "14.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export const AiSVG = (
</SVG>
);

/**
* AiIcon component
* @param {string} className - The wrapper class name.
* @return {React.ReactElement} The `AiIcon` component.
*/
export default function AiIcon( { className, size = 42 }: { className?: string; size?: number } ) {
return <Icon icon={ AiSVG } width={ size } height={ size } className={ className } />;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
/**
* External dependencies
*/
import {
AiModalPromptInput,
IMAGE_STYLE_NONE,
IMAGE_STYLE_AUTO,
ImageStyleObject,
ImageStyle,
AiModalFooter,
} from '@automattic/jetpack-ai-client';
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
import { SelectControl } from '@wordpress/components';
import { useCallback, useRef, useState, useEffect } from '@wordpress/element';
Expand All @@ -17,16 +9,64 @@ import debugFactory from 'debug';
/**
* Internal dependencies
*/
import QuotaExceededMessage from '../../../../../blocks/ai-assistant/components/quota-exceeded-message';
import AiAssistantModal from '../../modal';
import Carrousel, { CarrouselImages } from './carrousel';
import UsageCounter from './usage-counter';
import {
IMAGE_STYLE_NONE,
IMAGE_STYLE_AUTO,
ImageStyleObject,
ImageStyle,
} from '../../../hooks/use-image-generator/constants.js';
import { AiModalPromptInput } from '../../../logo-generator/index.js';
import AiModalFooter from '../../ai-modal-footer/index.js';
import AiAssistantModal from '../../modal/index.js';
import QuotaExceededMessage from '../../quota-exceeded-message/index.js';
import Carrousel, { CarrouselImages } from './carrousel.js';
import UsageCounter from './usage-counter.js';
import './ai-image-modal.scss';

type AiImageModalProps = {
title: string;
cost: number;
open: boolean;
placement: string;
images: CarrouselImages;
currentIndex: number;
onClose: () => void;
onTryAgain: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
onGenerate: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
generating: boolean;
notEnoughRequests: boolean;
requireUpgrade: boolean;
currentLimit: number;
currentUsage: number;
isUnlimited: boolean;
upgradeDescription: string;
hasError: boolean;
postContent?: string | boolean | null;
handlePreviousImage: () => void;
handleNextImage: () => void;
acceptButton: React.JSX.Element;
autoStart?: boolean;
autoStartAction?: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
generateButtonLabel: string;
instructionsPlaceholder: string;
imageStyles?: Array< ImageStyleObject >;
onGuessStyle?: ( userPrompt: string ) => Promise< ImageStyle >;
prompt?: string;
setPrompt?: ( userPrompt: string ) => void;
initialStyle?: ImageStyle;
inputDisabled?: boolean;
actionDisabled?: boolean;
};

const FEATURED_IMAGE_UPGRADE_PROMPT_PLACEMENT = 'ai-image-generator';

const debug = debugFactory( 'jetpack-ai:ai-image-modal' );
const debug = debugFactory( 'jetpack-ai-client:ai-image-modal' );

/**
* AiImageModal component
* @param {AiImageModalProps} props - The component properties.
* @return {React.ReactElement} - rendered component.
*/
export default function AiImageModal( {
title,
cost,
Expand Down Expand Up @@ -57,40 +97,7 @@ export default function AiImageModal( {
initialStyle = null,
inputDisabled = false,
actionDisabled = false,
}: {
title: string;
cost: number;
open: boolean;
placement: string;
images: CarrouselImages;
currentIndex: number;
onClose: () => void;
onTryAgain: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
onGenerate: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
generating: boolean;
notEnoughRequests: boolean;
requireUpgrade: boolean;
currentLimit: number;
currentUsage: number;
isUnlimited: boolean;
upgradeDescription: string;
hasError: boolean;
postContent?: string | boolean | null;
handlePreviousImage: () => void;
handleNextImage: () => void;
acceptButton: React.JSX.Element;
autoStart?: boolean;
autoStartAction?: ( { userPrompt, style }: { userPrompt?: string; style?: string } ) => void;
generateButtonLabel: string;
instructionsPlaceholder: string;
imageStyles?: Array< ImageStyleObject >;
onGuessStyle?: ( userPrompt: string ) => Promise< ImageStyle >;
prompt?: string;
setPrompt?: ( userPrompt: string ) => void;
initialStyle?: ImageStyle;
inputDisabled?: boolean;
actionDisabled?: boolean;
} ) {
}: AiImageModalProps ) {
const { tracks } = useAnalytics();
const { recordEvent: recordTracksEvent } = tracks;
const triggeredAutoGeneration = useRef( false );
Expand Down Expand Up @@ -133,8 +140,8 @@ export default function AiImageModal( {
const upgradePromptVisible = ( requireUpgrade || notEnoughRequests ) && ! generating;
const counterVisible = Boolean( ! isUnlimited && cost && currentLimit );

const generateLabel = __( 'Generate', 'jetpack' );
const tryAgainLabel = __( 'Try again', 'jetpack' );
const generateLabel = __( 'Generate', 'jetpack-ai-client' );
const tryAgainLabel = __( 'Try again', 'jetpack-ai-client' );

/**
* Trigger image generation automatically.
Expand Down Expand Up @@ -174,7 +181,7 @@ export default function AiImageModal( {
{ showStyleSelector && (
<div style={ { display: 'flex', alignItems: 'center', gap: 16 } }>
<div style={ { fontWeight: 500, flexGrow: 1 } }>
{ __( 'Generate image', 'jetpack' ) }
{ __( 'Generate image', 'jetpack-ai-client' ) }
</div>
<div>
<SelectControl
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* External dependencies
*/
import { AiFeedbackThumbs } from '@automattic/jetpack-ai-client';
import { Spinner } from '@wordpress/components';
import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
Expand All @@ -10,7 +9,8 @@ import clsx from 'clsx';
/**
* Internal dependencies
*/
import AiIcon from '../../ai-icon';
import AiFeedbackThumbs from '../../ai-feedback/index.js';
import AiIcon from '../../ai-icon/index.js';
import './carrousel.scss';

export type CarrouselImageData = {
Expand All @@ -27,7 +27,18 @@ export type CarrouselImageData = {

export type CarrouselImages = CarrouselImageData[];

function BlankImage( { children, isDotted = false, contentClassName = '' } ) {
type BlankImageProps = {
children: React.ReactNode;
isDotted?: boolean;
contentClassName?: string;
};

/**
* BlankImage component
* @param {BlankImageProps} props - The component properties.
* @return {React.ReactElement} - rendered component.
*/
function BlankImage( { children, isDotted = false, contentClassName = '' }: BlankImageProps ) {
const blankImage = (
<img
className="ai-assistant-image__carrousel-image"
Expand All @@ -50,19 +61,26 @@ function BlankImage( { children, isDotted = false, contentClassName = '' } ) {
);
}

type CarrouselProps = {
images: CarrouselImages;
current: number;
handlePreviousImage: () => void;
handleNextImage: () => void;
actions?: React.JSX.Element;
};

/**
* Carrousel component
* @param {CarrouselProps} props - The component properties.
* @return {React.ReactElement} - rendered component.
*/
export default function Carrousel( {
images,
current,
handlePreviousImage,
handleNextImage,
actions = null,
}: {
images: CarrouselImages;
current: number;
handlePreviousImage: () => void;
handleNextImage: () => void;
actions?: React.JSX.Element;
} ) {
}: CarrouselProps ) {
const [ imageFeedbackDisabled, setImageFeedbackDisabled ] = useState( false );
const prevButton = (
<button className="ai-carrousel__prev" onClick={ handlePreviousImage }>
Expand Down Expand Up @@ -126,7 +144,7 @@ export default function Carrousel( {
>
{ generating ? (
<BlankImage contentClassName="ai-assistant-image__loading">
{ __( 'Creating image…', 'jetpack' ) }
{ __( 'Creating image…', 'jetpack-ai-client' ) }
<Spinner
style={ {
width: '50px',
Expand All @@ -141,7 +159,7 @@ export default function Carrousel( {
<div className="ai-assistant-image__error">
{ __(
'An error occurred while generating the image. Please, try again!',
'jetpack'
'jetpack-ai-client'
) }
{ error?.message && (
<span className="ai-assistant-image__error-message">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,27 @@ type UsageCounterProps = {
cost: number;
};

/**
* UsageCounter component
* @param {UsageCounterProps} props - The component properties.
* @return {React.ReactElement} - rendered component.
*/
export default function UsageCounter( { currentLimit, currentUsage, cost }: UsageCounterProps ) {
const requestsBalance = currentLimit - currentUsage;

const requestsNeeded = createInterpolateElement(
// Translators: %d is the cost of one image.
sprintf( __( 'Requests needed: <counter>%d</counter>', 'jetpack' ), cost ),
sprintf( __( 'Requests needed: <counter>%d</counter>', 'jetpack-ai-client' ), cost ),
{
counter: <span />,
}
);
const requestsAvailable = createInterpolateElement(
// Translators: %d is the current requests balance.
sprintf( __( 'Requests available: <counter>%d</counter>', 'jetpack' ), requestsBalance ),
sprintf(
// Translators: %d is the current requests balance.
__( 'Requests available: <counter>%d</counter>', 'jetpack-ai-client' ),
requestsBalance
),
{
counter:
requestsBalance < cost ? (
Expand Down
Loading

0 comments on commit 116f2cf

Please sign in to comment.