From 77f3a0ef5a2eb7f64208bbb409c0f48084185665 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 14:55:00 -0300 Subject: [PATCH 01/21] add changelog --- .../changelog/change-jetpack-ai-featured-image-show-current | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/change-jetpack-ai-featured-image-show-current diff --git a/projects/plugins/jetpack/changelog/change-jetpack-ai-featured-image-show-current b/projects/plugins/jetpack/changelog/change-jetpack-ai-featured-image-show-current new file mode 100644 index 0000000000000..84db90c3cf89e --- /dev/null +++ b/projects/plugins/jetpack/changelog/change-jetpack-ai-featured-image-show-current @@ -0,0 +1,4 @@ +Significance: minor +Type: other + +Jetpack AI: featured image generator modal noww shows current featured image if present From 35bfa8f24784116b16b603fb2d7f75ef14098bd3 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 14:33:42 -0300 Subject: [PATCH 02/21] accept previous images on use-ai-image hook to preload existing image(s), adapt pointer/current refs/states --- .../components/ai-image/hooks/use-ai-image.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index bd2fcdd96695a..91c3611fcde72 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -42,11 +42,13 @@ export default function useAiImage( { type, cost, autoStart = true, + previousImages, }: { feature: AiImageFeature; type: AiImageType; cost: number; autoStart?: boolean; + previousImages?: CarrouselImages; } ) { const { generateImageWithParameters } = useImageGenerator(); const { increaseRequestsCount, featuresControl } = useAiFeature(); @@ -54,9 +56,11 @@ export default function useAiImage( { const { createNotice } = useDispatch( 'core/notices' ); /* Images Control */ - const pointer = useRef( 0 ); + const pointer = useRef( previousImages ? 1 : 0 ); const [ current, setCurrent ] = useState( 0 ); - const [ images, setImages ] = useState< CarrouselImages >( [ { generating: autoStart } ] ); + const [ images, setImages ] = useState< CarrouselImages >( + previousImages || [ { generating: autoStart } ] + ); // map feature-to-control prop, if this goes over 2 options, make a hook for it const featureControl = feature === FEATURED_IMAGE_FEATURE_NAME ? 'featured-image' : 'image'; @@ -213,7 +217,7 @@ export default function useAiImage( { const handlePreviousImage = useCallback( () => { setCurrent( Math.max( current - 1, 0 ) ); - }, [ current, setCurrent ] ); + }, [ current ] ); const handleNextImage = useCallback( () => { setCurrent( Math.min( current + 1, images.length - 1 ) ); From ca55bba00231011beb5a9507a3c6e0bb1abd9ca4 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 14:53:59 -0300 Subject: [PATCH 03/21] retrieve current featured image to show on modal, if available. add selector/store types, fix linter issues with types as well --- .../components/ai-image/featured-image.tsx | 61 +++++++++++++------ .../components/ai-image/types.ts | 19 ++++++ 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index c132f83211bc2..507ddbb8b6f6a 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -30,6 +30,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; +import type { SelectState, EditorSelectors, CoreSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -49,14 +50,15 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia } = useSelect( select => { - return { - // @ts-expect-error - getEditedPostAttribute is not defined in the useSelect type - postTitle: select( 'core/editor' ).getEditedPostAttribute( 'title' ), - // @ts-expect-error - getEditedPostAttribute is not defined in the useSelect type - postFeaturedMedia: select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ), - }; - }, [] ); + const { postTitle, postFeaturedMedia } = useSelect( + ( select: ( store: keyof SelectState ) => EditorSelectors ) => { + return { + postTitle: select( 'core/editor' ).getEditedPostAttribute( 'title' ), + postFeaturedMedia: select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ), + }; + }, + [] + ); const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -87,14 +89,23 @@ export default function FeaturedImage( { // https://github.com/WordPress/gutenberg/blob/fe4d8cb936df52945c01c1863f7b87b58b7cc69f/packages/edit-post/CHANGELOG.md?plain=1#L19 const toggleEditorPanelOpened = toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; - const isEditorPanelOpened = useSelect( select => { - const isOpened = - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ( select( 'core/editor' ) as any ).isEditorPanelOpened ?? - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ( select( 'core/edit-post' ) as any ).isEditorPanelOpened; - return isOpened; - }, [] ); + const isEditorPanelOpened = useSelect( + ( select: ( store: keyof SelectState ) => EditorSelectors ) => { + const isOpened = + select( 'core/editor' ).isEditorPanelOpened ?? + select( 'core/edit-post' ).isEditorPanelOpened; + return isOpened; + }, + [] + ); + + const currentFeaturedMedia = useSelect( + ( select: ( store: keyof SelectState ) => EditorSelectors & CoreSelectors ) => { + const mediaId = select( 'core/editor' )?.getEditedPostAttribute?.( 'featured_media' ); + return mediaId ? select( 'core' )?.getMedia?.( mediaId as number ) : null; + }, + [] + ); const { pointer, @@ -113,6 +124,16 @@ export default function FeaturedImage( { cost: featuredImageCost, type: 'featured-image-generation', feature: FEATURED_IMAGE_FEATURE_NAME, + previousImages: currentFeaturedMedia + ? [ + { + image: currentFeaturedMedia.source_url, + libraryId: currentFeaturedMedia.id, + libraryUrl: currentFeaturedMedia.source_url, + generating: false, + }, + ] + : null, } ); const handleModalClose = useCallback( () => { @@ -341,7 +362,7 @@ export default function FeaturedImage( { const generateAgainText = __( 'Generate another image', 'jetpack' ); const generateText = __( 'Generate', 'jetpack' ); - const hasContent = postContent || postTitle; + const hasContent = postContent || postTitle ? true : false; const hasPrompt = hasContent ? prompt.length >= 0 : prompt.length >= 3; const disableInput = notEnoughRequests || currentPointer?.generating || requireUpgrade; const disableAction = disableInput || ( ! hasContent && ! hasPrompt ); @@ -361,7 +382,11 @@ export default function FeaturedImage( { diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts index f0c0c5ae3d125..6e33b519ff75b 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts @@ -4,3 +4,22 @@ export const IMAGE_GENERATION_MODEL_STABLE_DIFFUSION = 'stable-diffusion' as con export const IMAGE_GENERATION_MODEL_DALL_E_3 = 'dall-e-3' as const; export const PLACEMENT_MEDIA_SOURCE_DROPDOWN = 'media-source-dropdown' as const; export const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON = 'block-placeholder-button' as const; + +export interface EditorSelectors { + // actually getEditedPostAttribute can bring different values, but for our current use, number is fine (media ID) + getEditedPostAttribute: ( attribute: string ) => number; + isEditorPanelOpened: ( panel: string ) => boolean; +} + +export interface CoreSelectors { + getMedia: ( mediaId: number ) => { + id: number; + source_url: string; + } | null; +} + +export interface SelectState { + 'core/editor': EditorSelectors; + 'core/edit-post': EditorSelectors; + core: CoreSelectors; +} From e2a003e97481765c32fe048d0133f89d5b38562b Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 15:54:01 -0300 Subject: [PATCH 04/21] use exported store and type from wordpress/editor --- .../components/ai-image/featured-image.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 507ddbb8b6f6a..bb9eed05bad2a 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -5,6 +5,7 @@ import { ImageStyle } from '@automattic/jetpack-ai-client'; import { useAnalytics } from '@automattic/jetpack-shared-extension-utils'; import { Button } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; +import { store as editorStore } from '@wordpress/editor'; import { useCallback, useState } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import debugFactory from 'debug'; @@ -50,15 +51,12 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia } = useSelect( - ( select: ( store: keyof SelectState ) => EditorSelectors ) => { - return { - postTitle: select( 'core/editor' ).getEditedPostAttribute( 'title' ), - postFeaturedMedia: select( 'core/editor' ).getEditedPostAttribute( 'featured_media' ), - }; - }, - [] - ); + const { postTitle, postFeaturedMedia } = useSelect( select => { + return { + postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), + postFeaturedMedia: select( editorStore ).getEditedPostAttribute( 'featured_media' ), + }; + }, [] ); const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -71,7 +69,7 @@ export default function FeaturedImage( { const { toggleEditorPanelOpened: toggleEditorPanelOpenedFromEditPost } = useDispatch( 'core/edit-post' ); const { editPost, toggleEditorPanelOpened: toggleEditorPanelOpenedFromEditor } = - useDispatch( 'core/editor' ); + useDispatch( editorStore ); // Get feature data const { requireUpgrade, requestsCount, requestsLimit, currentTier, costs } = useAiFeature(); From adaf88ecb99e409987cc44b1be7cb9482fbeaa11 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 16:06:03 -0300 Subject: [PATCH 05/21] use cleaner types --- .../components/ai-image/featured-image.tsx | 20 ++++++++----------- .../components/ai-image/types.ts | 6 ------ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index bb9eed05bad2a..db2589ce386e5 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -31,7 +31,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; -import type { SelectState, EditorSelectors, CoreSelectors } from './types'; +import type { EditorSelectors, CoreSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -87,19 +87,15 @@ export default function FeaturedImage( { // https://github.com/WordPress/gutenberg/blob/fe4d8cb936df52945c01c1863f7b87b58b7cc69f/packages/edit-post/CHANGELOG.md?plain=1#L19 const toggleEditorPanelOpened = toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; - const isEditorPanelOpened = useSelect( - ( select: ( store: keyof SelectState ) => EditorSelectors ) => { - const isOpened = - select( 'core/editor' ).isEditorPanelOpened ?? - select( 'core/edit-post' ).isEditorPanelOpened; - return isOpened; - }, - [] - ); + const isEditorPanelOpened = useSelect( ( select: ( store ) => EditorSelectors ) => { + const isOpened = + select( editorStore ).isEditorPanelOpened ?? select( 'core/edit-post' ).isEditorPanelOpened; + return isOpened; + }, [] ); const currentFeaturedMedia = useSelect( - ( select: ( store: keyof SelectState ) => EditorSelectors & CoreSelectors ) => { - const mediaId = select( 'core/editor' )?.getEditedPostAttribute?.( 'featured_media' ); + ( select: ( store ) => EditorSelectors & CoreSelectors ) => { + const mediaId = select( editorStore )?.getEditedPostAttribute?.( 'featured_media' ); return mediaId ? select( 'core' )?.getMedia?.( mediaId as number ) : null; }, [] diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts index 6e33b519ff75b..77f688f7dd94a 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts @@ -17,9 +17,3 @@ export interface CoreSelectors { source_url: string; } | null; } - -export interface SelectState { - 'core/editor': EditorSelectors; - 'core/edit-post': EditorSelectors; - core: CoreSelectors; -} From cef2399cf63b4efe3ddf63a1c14394ff6d6e871b Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Mon, 16 Dec 2024 16:39:32 -0300 Subject: [PATCH 06/21] use a single call for all editorStore selects --- .../components/ai-image/featured-image.tsx | 35 +++++++++---------- .../components/ai-image/hooks/use-ai-image.ts | 2 +- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index db2589ce386e5..847738a4a5976 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -51,12 +51,22 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia } = useSelect( select => { - return { - postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), - postFeaturedMedia: select( editorStore ).getEditedPostAttribute( 'featured_media' ), - }; - }, [] ); + const { postTitle, postFeaturedMedia, currentFeaturedMedia, isEditorPanelOpened } = useSelect( + ( select: ( store ) => EditorSelectors & CoreSelectors ) => { + const featuredMediaId = select( editorStore ).getEditedPostAttribute( 'featured_media' ); + return { + postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), + postFeaturedMedia: featuredMediaId, + currentFeaturedMedia: featuredMediaId + ? select( 'core' )?.getMedia?.( featuredMediaId as number ) + : null, + isEditorPanelOpened: + select( editorStore ).isEditorPanelOpened ?? + select( 'core/edit-post' ).isEditorPanelOpened, + }; + }, + [] + ); const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -87,19 +97,6 @@ export default function FeaturedImage( { // https://github.com/WordPress/gutenberg/blob/fe4d8cb936df52945c01c1863f7b87b58b7cc69f/packages/edit-post/CHANGELOG.md?plain=1#L19 const toggleEditorPanelOpened = toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; - const isEditorPanelOpened = useSelect( ( select: ( store ) => EditorSelectors ) => { - const isOpened = - select( editorStore ).isEditorPanelOpened ?? select( 'core/edit-post' ).isEditorPanelOpened; - return isOpened; - }, [] ); - - const currentFeaturedMedia = useSelect( - ( select: ( store ) => EditorSelectors & CoreSelectors ) => { - const mediaId = select( editorStore )?.getEditedPostAttribute?.( 'featured_media' ); - return mediaId ? select( 'core' )?.getMedia?.( mediaId as number ) : null; - }, - [] - ); const { pointer, diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index 91c3611fcde72..89f2098e77b46 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -56,7 +56,7 @@ export default function useAiImage( { const { createNotice } = useDispatch( 'core/notices' ); /* Images Control */ - const pointer = useRef( previousImages ? 1 : 0 ); + const pointer = useRef( previousImages ? previousImages.length : 0 ); const [ current, setCurrent ] = useState( 0 ); const [ images, setImages ] = useState< CarrouselImages >( previousImages || [ { generating: autoStart } ] From ef273736e9b1388e112bb53d5c4b674742bff11b Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 17 Dec 2024 11:16:27 -0300 Subject: [PATCH 07/21] split selector to use media ID as dependency to fetch media object --- .../components/ai-image/featured-image.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 847738a4a5976..5de21f7e34d33 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -51,15 +51,12 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia, currentFeaturedMedia, isEditorPanelOpened } = useSelect( - ( select: ( store ) => EditorSelectors & CoreSelectors ) => { + const { postTitle, postFeaturedMedia, isEditorPanelOpened } = useSelect( + ( select: ( store ) => EditorSelectors ) => { const featuredMediaId = select( editorStore ).getEditedPostAttribute( 'featured_media' ); return { postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), postFeaturedMedia: featuredMediaId, - currentFeaturedMedia: featuredMediaId - ? select( 'core' )?.getMedia?.( featuredMediaId as number ) - : null, isEditorPanelOpened: select( editorStore ).isEditorPanelOpened ?? select( 'core/edit-post' ).isEditorPanelOpened, @@ -67,6 +64,15 @@ export default function FeaturedImage( { }, [] ); + const currentFeaturedMedia = useSelect( + ( select: ( store ) => CoreSelectors ) => { + if ( postFeaturedMedia ) { + return select( 'core' )?.getMedia?.( postFeaturedMedia ); + } + return null; + }, + [ postFeaturedMedia ] + ); const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; From 6441dea9b5ef04faecf7bac24bc51bed6e48ba44 Mon Sep 17 00:00:00 2001 From: Douglas Date: Tue, 17 Dec 2024 17:10:50 -0300 Subject: [PATCH 08/21] get featured image URL from getEditedPostAttribute --- .../components/ai-image/featured-image.tsx | 38 +++++++++---------- .../components/ai-image/types.ts | 9 +---- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 5de21f7e34d33..8a62593295361 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -31,7 +31,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; -import type { EditorSelectors, CoreSelectors } from './types'; +import type { EditorSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -51,12 +51,20 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia, isEditorPanelOpened } = useSelect( + const { postTitle, postFeaturedMediaURL, postFeaturedMediaId, isEditorPanelOpened } = useSelect( ( select: ( store ) => EditorSelectors ) => { - const featuredMediaId = select( editorStore ).getEditedPostAttribute( 'featured_media' ); + const editorStoreSelect = select( editorStore ); + const featuredMediaURL = editorStoreSelect.getEditedPostAttribute( + 'jetpack_featured_media_url' + ) as string; + const featuredMediaId = editorStoreSelect.getEditedPostAttribute( + 'featured_media' + ) as number; + return { postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), - postFeaturedMedia: featuredMediaId, + postFeaturedMediaURL: featuredMediaURL, + postFeaturedMediaId: featuredMediaId, isEditorPanelOpened: select( editorStore ).isEditorPanelOpened ?? select( 'core/edit-post' ).isEditorPanelOpened, @@ -64,15 +72,7 @@ export default function FeaturedImage( { }, [] ); - const currentFeaturedMedia = useSelect( - ( select: ( store ) => CoreSelectors ) => { - if ( postFeaturedMedia ) { - return select( 'core' )?.getMedia?.( postFeaturedMedia ); - } - return null; - }, - [ postFeaturedMedia ] - ); + const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -121,12 +121,12 @@ export default function FeaturedImage( { cost: featuredImageCost, type: 'featured-image-generation', feature: FEATURED_IMAGE_FEATURE_NAME, - previousImages: currentFeaturedMedia + previousImages: postFeaturedMediaURL ? [ { - image: currentFeaturedMedia.source_url, - libraryId: currentFeaturedMedia.id, - libraryUrl: currentFeaturedMedia.source_url, + image: postFeaturedMediaURL, + libraryId: postFeaturedMediaId, + libraryUrl: postFeaturedMediaURL, generating: false, }, ] @@ -382,7 +382,7 @@ export default function FeaturedImage( { disabled={ ! currentImage?.image || currentImage?.generating || - currentImage?.image === currentFeaturedMedia?.source_url + currentImage?.image === postFeaturedMediaURL } > { __( 'Set as featured image', 'jetpack' ) } @@ -407,7 +407,7 @@ export default function FeaturedImage( { ) } number; + getEditedPostAttribute: ( attribute: string ) => string | number; isEditorPanelOpened: ( panel: string ) => boolean; } - -export interface CoreSelectors { - getMedia: ( mediaId: number ) => { - id: number; - source_url: string; - } | null; -} From 3d81239c21f656316798082ce992f286d89051ee Mon Sep 17 00:00:00 2001 From: Douglas Date: Tue, 17 Dec 2024 17:16:20 -0300 Subject: [PATCH 09/21] simplify types --- .../components/ai-image/featured-image.tsx | 6 +++--- .../ai-assistant-plugin/components/ai-image/types.ts | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 8a62593295361..1a50c419eb744 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -31,7 +31,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; -import type { EditorSelectors } from './types'; +import type { CoreEditPostSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -52,7 +52,7 @@ export default function FeaturedImage( { const siteType = useSiteType(); const postContent = usePostContent(); const { postTitle, postFeaturedMediaURL, postFeaturedMediaId, isEditorPanelOpened } = useSelect( - ( select: ( store ) => EditorSelectors ) => { + select => { const editorStoreSelect = select( editorStore ); const featuredMediaURL = editorStoreSelect.getEditedPostAttribute( 'jetpack_featured_media_url' @@ -67,7 +67,7 @@ export default function FeaturedImage( { postFeaturedMediaId: featuredMediaId, isEditorPanelOpened: select( editorStore ).isEditorPanelOpened ?? - select( 'core/edit-post' ).isEditorPanelOpened, + ( select( 'core/edit-post' ) as CoreEditPostSelectors ).isEditorPanelOpened, }; }, [] diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts index d4c51a6a46d43..472d4950347e6 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/types.ts @@ -5,8 +5,6 @@ export const IMAGE_GENERATION_MODEL_DALL_E_3 = 'dall-e-3' as const; export const PLACEMENT_MEDIA_SOURCE_DROPDOWN = 'media-source-dropdown' as const; export const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON = 'block-placeholder-button' as const; -export interface EditorSelectors { - // actually getEditedPostAttribute can bring different values, but for our current use, number is fine (media ID) - getEditedPostAttribute: ( attribute: string ) => string | number; +export interface CoreEditPostSelectors { isEditorPanelOpened: ( panel: string ) => boolean; } From 96c2c8a2e38fabd9315f7ddd1edac08b3e5efbff Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Wed, 18 Dec 2024 17:46:09 -0300 Subject: [PATCH 10/21] Revert "get featured image URL from getEditedPostAttribute" This reverts commit 7e23832ba09724a37afa4c4eb3413c3496a03a86. --- .../components/ai-image/featured-image.tsx | 51 +++++++++---------- .../components/ai-image/types.ts | 11 +++- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 1a50c419eb744..ba985ce93b075 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -31,7 +31,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; -import type { CoreEditPostSelectors } from './types'; +import type { EditorSelectors, CoreSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -51,28 +51,25 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMediaURL, postFeaturedMediaId, isEditorPanelOpened } = useSelect( - select => { - const editorStoreSelect = select( editorStore ); - const featuredMediaURL = editorStoreSelect.getEditedPostAttribute( - 'jetpack_featured_media_url' - ) as string; - const featuredMediaId = editorStoreSelect.getEditedPostAttribute( - 'featured_media' - ) as number; - - return { - postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), - postFeaturedMediaURL: featuredMediaURL, - postFeaturedMediaId: featuredMediaId, - isEditorPanelOpened: - select( editorStore ).isEditorPanelOpened ?? - ( select( 'core/edit-post' ) as CoreEditPostSelectors ).isEditorPanelOpened, - }; + const { postTitle, postFeaturedMedia, isEditorPanelOpened } = useSelect( select => { + const featuredMediaId = select( editorStore ).getEditedPostAttribute( 'featured_media' ); + return { + postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), + postFeaturedMedia: featuredMediaId, + isEditorPanelOpened: + select( editorStore ).isEditorPanelOpened ?? + ( select( 'core/edit-post' ) as EditorSelectors ).isEditorPanelOpened, + }; + }, [] ); + const currentFeaturedMedia = useSelect( + ( select: ( store ) => CoreSelectors ) => { + if ( postFeaturedMedia ) { + return select( 'core' )?.getMedia?.( postFeaturedMedia ); + } + return null; }, - [] + [ postFeaturedMedia ] ); - const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -121,12 +118,12 @@ export default function FeaturedImage( { cost: featuredImageCost, type: 'featured-image-generation', feature: FEATURED_IMAGE_FEATURE_NAME, - previousImages: postFeaturedMediaURL + previousImages: currentFeaturedMedia ? [ { - image: postFeaturedMediaURL, - libraryId: postFeaturedMediaId, - libraryUrl: postFeaturedMediaURL, + image: currentFeaturedMedia.source_url, + libraryId: currentFeaturedMedia.id, + libraryUrl: currentFeaturedMedia.source_url, generating: false, }, ] @@ -382,7 +379,7 @@ export default function FeaturedImage( { disabled={ ! currentImage?.image || currentImage?.generating || - currentImage?.image === postFeaturedMediaURL + currentImage?.image === currentFeaturedMedia?.source_url } > { __( 'Set as featured image', 'jetpack' ) } @@ -407,7 +404,7 @@ export default function FeaturedImage( { ) } number; isEditorPanelOpened: ( panel: string ) => boolean; } + +export interface CoreSelectors { + getMedia: ( mediaId: number ) => { + id: number; + source_url: string; + } | null; +} From 9a5ef6eaf3942bb9846b596d3c34a8e66f544c9f Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 19 Dec 2024 12:28:21 -0300 Subject: [PATCH 11/21] add debug calls to figure out why modal isn't showing the featured image on first open --- .../components/ai-image/components/ai-image-modal.tsx | 1 + .../components/ai-image/featured-image.tsx | 2 ++ .../components/ai-image/hooks/use-ai-image.ts | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/ai-image-modal.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/ai-image-modal.tsx index ea6256a9a7bc7..671b2ff39c312 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/ai-image-modal.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/ai-image-modal.tsx @@ -166,6 +166,7 @@ export default function AiImageModal( { } }, [ imageStyles, initialStyle ] ); + debug( 'images', images ); return ( <> { open && ( diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index ba985ce93b075..1564e5e1b1bc0 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -101,6 +101,8 @@ export default function FeaturedImage( { const toggleEditorPanelOpened = toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; + debug( 'postFeatureMedia', postFeaturedMedia ); + debug( 'currentFeaturedMedia', currentFeaturedMedia ); const { pointer, current, diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index 89f2098e77b46..7b7f5495a0562 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -11,6 +11,7 @@ import { useDispatch } from '@wordpress/data'; import { useCallback, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { cleanForSlug } from '@wordpress/url'; +import debugFactory from 'debug'; /** * Internal dependencies */ @@ -37,6 +38,8 @@ export type ImageResponse = { revisedPrompt?: string; }; +const debug = debugFactory( 'jetpack-ai:use-ai-image' ); + export default function useAiImage( { feature, type, @@ -50,6 +53,7 @@ export default function useAiImage( { autoStart?: boolean; previousImages?: CarrouselImages; } ) { + debug( 'previousImages', previousImages ); const { generateImageWithParameters } = useImageGenerator(); const { increaseRequestsCount, featuresControl } = useAiFeature(); const { saveToMediaLibrary } = useSaveToMediaLibrary(); @@ -61,7 +65,7 @@ export default function useAiImage( { const [ images, setImages ] = useState< CarrouselImages >( previousImages || [ { generating: autoStart } ] ); - + debug( 'images', images ); // map feature-to-control prop, if this goes over 2 options, make a hook for it const featureControl = feature === FEATURED_IMAGE_FEATURE_NAME ? 'featured-image' : 'image'; const imageFeatureControl = featuresControl?.[ featureControl ] as ImageFeatureControl; From a60829c8ab92652db14c21ebd85f89707b7a8eae Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 19 Dec 2024 13:56:50 -0300 Subject: [PATCH 12/21] move getMedia selector to ai image hook, use selector/useEffect combo to try and get the value --- .../components/ai-image/featured-image.tsx | 27 +++----------- .../components/ai-image/hooks/use-ai-image.ts | 37 ++++++++++++++----- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 1564e5e1b1bc0..874cf1d4067be 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -31,7 +31,7 @@ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, } from './types'; import type { ImageResponse } from './hooks/use-ai-image'; -import type { EditorSelectors, CoreSelectors } from './types'; +import type { EditorSelectors } from './types'; const debug = debugFactory( 'jetpack-ai:featured-image' ); @@ -61,15 +61,7 @@ export default function FeaturedImage( { ( select( 'core/edit-post' ) as EditorSelectors ).isEditorPanelOpened, }; }, [] ); - const currentFeaturedMedia = useSelect( - ( select: ( store ) => CoreSelectors ) => { - if ( postFeaturedMedia ) { - return select( 'core' )?.getMedia?.( postFeaturedMedia ); - } - return null; - }, - [ postFeaturedMedia ] - ); + const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { tracks } = useAnalytics(); const { recordEvent } = tracks; @@ -102,7 +94,7 @@ export default function FeaturedImage( { toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; debug( 'postFeatureMedia', postFeaturedMedia ); - debug( 'currentFeaturedMedia', currentFeaturedMedia ); + const { pointer, current, @@ -120,16 +112,7 @@ export default function FeaturedImage( { cost: featuredImageCost, type: 'featured-image-generation', feature: FEATURED_IMAGE_FEATURE_NAME, - previousImages: currentFeaturedMedia - ? [ - { - image: currentFeaturedMedia.source_url, - libraryId: currentFeaturedMedia.id, - libraryUrl: currentFeaturedMedia.source_url, - generating: false, - }, - ] - : null, + previousMediaId: postFeaturedMedia, } ); const handleModalClose = useCallback( () => { @@ -381,7 +364,7 @@ export default function FeaturedImage( { disabled={ ! currentImage?.image || currentImage?.generating || - currentImage?.image === currentFeaturedMedia?.source_url + currentImage?.libraryId === postFeaturedMedia } > { __( 'Set as featured image', 'jetpack' ) } diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index 7b7f5495a0562..b5c25f6d8c3c7 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -7,8 +7,8 @@ import { ImageStyle, askQuestionSync, } from '@automattic/jetpack-ai-client'; -import { useDispatch } from '@wordpress/data'; -import { useCallback, useRef, useState } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { useCallback, useEffect, useRef, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { cleanForSlug } from '@wordpress/url'; import debugFactory from 'debug'; @@ -20,7 +20,7 @@ import useSaveToMediaLibrary from '../../../hooks/use-save-to-media-library'; /** * Types */ -import { FEATURED_IMAGE_FEATURE_NAME, GENERAL_IMAGE_FEATURE_NAME } from '../types'; +import { CoreSelectors, FEATURED_IMAGE_FEATURE_NAME, GENERAL_IMAGE_FEATURE_NAME } from '../types'; import type { CarrouselImageData, CarrouselImages } from '../components/carrousel'; import type { RoleType } from '@automattic/jetpack-ai-client'; import type { FeatureControl } from 'extensions/store/wordpress-com/types.js'; @@ -45,26 +45,24 @@ export default function useAiImage( { type, cost, autoStart = true, - previousImages, + previousMediaId, }: { feature: AiImageFeature; type: AiImageType; cost: number; autoStart?: boolean; - previousImages?: CarrouselImages; + previousMediaId?: number; } ) { - debug( 'previousImages', previousImages ); + debug( 'previousImages', previousMediaId ); const { generateImageWithParameters } = useImageGenerator(); const { increaseRequestsCount, featuresControl } = useAiFeature(); const { saveToMediaLibrary } = useSaveToMediaLibrary(); const { createNotice } = useDispatch( 'core/notices' ); /* Images Control */ - const pointer = useRef( previousImages ? previousImages.length : 0 ); + const pointer = useRef( 0 ); const [ current, setCurrent ] = useState( 0 ); - const [ images, setImages ] = useState< CarrouselImages >( - previousImages || [ { generating: autoStart } ] - ); + const [ images, setImages ] = useState< CarrouselImages >( [ { generating: autoStart } ] ); debug( 'images', images ); // map feature-to-control prop, if this goes over 2 options, make a hook for it const featureControl = feature === FEATURED_IMAGE_FEATURE_NAME ? 'featured-image' : 'image'; @@ -83,6 +81,25 @@ export default function useAiImage( { } ); }, [] ); + // the selec/useEffect combo... + const currentFeaturedMedia = useSelect( + ( select: ( store ) => CoreSelectors ) => select( 'core' )?.getMedia?.( previousMediaId ), + [ previousMediaId ] + ); + useEffect( () => { + if ( currentFeaturedMedia ) { + updateImages( + { + image: currentFeaturedMedia.source_url, + libraryId: currentFeaturedMedia.id, + libraryUrl: currentFeaturedMedia.source_url, + generating: false, + }, + pointer.current + ); + } + }, [ currentFeaturedMedia, updateImages ] ); + /* * Function to show a snackbar notice on the editor. */ From 051c0119b3515579811fbf6a5973fe0bde27b6ea Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Thu, 19 Dec 2024 15:26:08 -0300 Subject: [PATCH 13/21] refactor var name to reflect value --- .../components/ai-image/featured-image.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx index 874cf1d4067be..60ce8005deb0c 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/featured-image.tsx @@ -51,11 +51,10 @@ export default function FeaturedImage( { ); const siteType = useSiteType(); const postContent = usePostContent(); - const { postTitle, postFeaturedMedia, isEditorPanelOpened } = useSelect( select => { - const featuredMediaId = select( editorStore ).getEditedPostAttribute( 'featured_media' ); + const { postTitle, postFeaturedMediaId, isEditorPanelOpened } = useSelect( select => { return { postTitle: select( editorStore ).getEditedPostAttribute( 'title' ), - postFeaturedMedia: featuredMediaId, + postFeaturedMediaId: select( editorStore ).getEditedPostAttribute( 'featured_media' ), isEditorPanelOpened: select( editorStore ).isEditorPanelOpened ?? ( select( 'core/edit-post' ) as EditorSelectors ).isEditorPanelOpened, @@ -93,7 +92,7 @@ export default function FeaturedImage( { const toggleEditorPanelOpened = toggleEditorPanelOpenedFromEditor ?? toggleEditorPanelOpenedFromEditPost; - debug( 'postFeatureMedia', postFeaturedMedia ); + debug( 'postFeaturedMediaId', postFeaturedMediaId ); const { pointer, @@ -112,7 +111,7 @@ export default function FeaturedImage( { cost: featuredImageCost, type: 'featured-image-generation', feature: FEATURED_IMAGE_FEATURE_NAME, - previousMediaId: postFeaturedMedia, + previousMediaId: postFeaturedMediaId, } ); const handleModalClose = useCallback( () => { @@ -364,7 +363,7 @@ export default function FeaturedImage( { disabled={ ! currentImage?.image || currentImage?.generating || - currentImage?.libraryId === postFeaturedMedia + currentImage?.libraryId === postFeaturedMediaId } > { __( 'Set as featured image', 'jetpack' ) } @@ -389,7 +388,7 @@ export default function FeaturedImage( { ) } Date: Thu, 19 Dec 2024 16:45:27 -0300 Subject: [PATCH 14/21] rename var so it makes a bit more sense of what it is --- .../components/ai-image/hooks/use-ai-image.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index b5c25f6d8c3c7..a317ddb8e560f 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -82,23 +82,23 @@ export default function useAiImage( { }, [] ); // the selec/useEffect combo... - const currentFeaturedMedia = useSelect( + const loadedMedia = useSelect( ( select: ( store ) => CoreSelectors ) => select( 'core' )?.getMedia?.( previousMediaId ), [ previousMediaId ] ); useEffect( () => { - if ( currentFeaturedMedia ) { + if ( loadedMedia ) { updateImages( { - image: currentFeaturedMedia.source_url, - libraryId: currentFeaturedMedia.id, - libraryUrl: currentFeaturedMedia.source_url, + image: loadedMedia.source_url, + libraryId: loadedMedia.id, + libraryUrl: loadedMedia.source_url, generating: false, }, pointer.current ); } - }, [ currentFeaturedMedia, updateImages ] ); + }, [ loadedMedia, updateImages ] ); /* * Function to show a snackbar notice on the editor. From b1ddd3090b508846bc1ee47dc7dfb1bf45465164 Mon Sep 17 00:00:00 2001 From: Douglas Date: Thu, 19 Dec 2024 18:06:08 -0300 Subject: [PATCH 15/21] set fixed image height on image modal --- .../components/ai-image/components/carrousel.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.scss b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.scss index fe4e880a78200..402da821cc327 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.scss +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.scss @@ -1,3 +1,5 @@ +$scale-factor: 0.55; + .ai-assistant-image { &__blank { display: flex; @@ -47,6 +49,7 @@ display: flex; align-items: center; overflow: hidden; + height: calc( 768px * $scale-factor ); .ai-carrousel { &__prev { @@ -129,14 +132,17 @@ } &-image { - width: 78%; + max-height: calc( 768px * $scale-factor ); + max-width: calc( 1024px * $scale-factor ); + width: auto; height: auto; + margin: auto 0; } &-image-container { display: flex; width: 100%; - height: auto; + height: 100%; position: absolute; left: 8px; transform: translateX( 100% ); From b073048c1a4bb41d207e39019c7e338ed03e28e3 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Fri, 20 Dec 2024 17:06:40 -0300 Subject: [PATCH 16/21] if we've loaded a previous image, generate a mock image before triggering the generation process --- .../components/ai-image/hooks/use-ai-image.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts index a317ddb8e560f..194c131afb486 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/hooks/use-ai-image.ts @@ -60,7 +60,10 @@ export default function useAiImage( { const { createNotice } = useDispatch( 'core/notices' ); /* Images Control */ + // pointer keeps track of request/generation iteration const pointer = useRef( 0 ); + // and current keeps track of what is the image exposed at the moment + // TODO: should current be any relevant here? It's just modal/carrousel logic after all const [ current, setCurrent ] = useState( 0 ); const [ images, setImages ] = useState< CarrouselImages >( [ { generating: autoStart } ] ); debug( 'images', images ); @@ -148,6 +151,9 @@ export default function useAiImage( { style?: string; } ) => { return new Promise< ImageResponse >( ( resolve, reject ) => { + if ( previousMediaId && pointer.current === 0 ) { + pointer.current++; + } updateImages( { generating: true, error: null }, pointer.current ); // Ensure the site has enough requests to generate the image. @@ -233,6 +239,7 @@ export default function useAiImage( { saveToMediaLibrary, showSnackbarNotice, getImageNameSuggestion, + previousMediaId, ] ); @@ -284,7 +291,7 @@ export default function useAiImage( { }, [ imageStyles ] ); - + debug( pointer.current, current ); return { current, setCurrent, From cb4e4130c714f21cf1802dada2158f8b86d2a20b Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Fri, 20 Dec 2024 17:08:46 -0300 Subject: [PATCH 17/21] consider libraryId besides image prop to decide and use on image src. Also, change how disabling feedback is evaluated --- .../ai-image/components/carrousel.tsx | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.tsx b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.tsx index f9dec07e3cb2b..78e252e34880b 100644 --- a/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.tsx +++ b/projects/plugins/jetpack/extensions/plugins/ai-assistant-plugin/components/ai-image/components/carrousel.tsx @@ -3,9 +3,11 @@ */ import { AiFeedbackThumbs } from '@automattic/jetpack-ai-client'; import { Spinner } from '@wordpress/components'; +import { useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Icon, chevronLeft, chevronRight } from '@wordpress/icons'; import clsx from 'clsx'; +import debugFactory from 'debug'; /** * Internal dependencies */ @@ -49,6 +51,7 @@ function BlankImage( { children, isDotted = false, contentClassName = '' } ) { ); } +const debug = debugFactory( 'jetpack-ai:carrousel' ); export default function Carrousel( { images, current, @@ -62,6 +65,7 @@ export default function Carrousel( { handleNextImage: () => void; actions?: React.JSX.Element; } ) { + const [ imageFeedbackDisabled, setImageFeedbackDisabled ] = useState( false ); const prevButton = (