Skip to content

Commit

Permalink
AI Assistant: Link toolbar actions to requests on inline extensions (#…
Browse files Browse the repository at this point in the history
…37168)

* remove block ref

* fix input state

* show quick action text on input

* add getContent to block handler

* add buildPromptForExtensions function

* link toolbar requests to content

* changelog
  • Loading branch information
dhasilva authored May 2, 2024
1 parent 48f3288 commit 002b870
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 108 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

AI Assistant: Link toolbar actions to requests on inline extensions
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import {
PROMPT_TYPE_CHANGE_LANGUAGE,
PROMPT_TYPE_USER_PROMPT,
} from '../../lib/prompt';
import { I18nMenuDropdown } from '../i18n-dropdown-control';
import { ToneDropdownMenu } from '../tone-dropdown-control';
import { capitalize } from '../../lib/utils/capitalize';
import { I18nMenuDropdown, TRANSLATE_LABEL } from '../i18n-dropdown-control';
import { TONE_LABEL, ToneDropdownMenu } from '../tone-dropdown-control';
import './style.scss';
/**
* Types and constants
Expand Down Expand Up @@ -112,7 +113,8 @@ export type AiAssistantDropdownOnChangeOptionsArgProps = {

export type OnRequestSuggestion = (
promptType: PromptTypeProp,
options?: AiAssistantDropdownOnChangeOptionsArgProps
options?: AiAssistantDropdownOnChangeOptionsArgProps,
humanText?: string
) => void;

type AiAssistantToolbarDropdownContentProps = {
Expand Down Expand Up @@ -162,7 +164,11 @@ export default function AiAssistantToolbarDropdownContent( {
iconPosition="left"
key={ `key-${ quickAction.key }` }
onClick={ () => {
onRequestSuggestion( quickAction.aiSuggestion, { ...( quickAction.options ?? {} ) } );
onRequestSuggestion(
quickAction.aiSuggestion,
{ ...( quickAction.options ?? {} ) },
quickAction.name
);
} }
disabled={ disabled }
>
Expand All @@ -172,14 +178,22 @@ export default function AiAssistantToolbarDropdownContent( {

<ToneDropdownMenu
onChange={ tone => {
onRequestSuggestion( PROMPT_TYPE_CHANGE_TONE, { tone } );
onRequestSuggestion(
PROMPT_TYPE_CHANGE_TONE,
{ tone },
`${ TONE_LABEL }: ${ capitalize( tone ) }`
);
} }
disabled={ disabled }
/>

<I18nMenuDropdown
onChange={ language => {
onRequestSuggestion( PROMPT_TYPE_CHANGE_LANGUAGE, { language } );
onChange={ ( language, name ) => {
onRequestSuggestion(
PROMPT_TYPE_CHANGE_LANGUAGE,
{ language },
`${ TRANSLATE_LABEL }: ${ name }`
);
} }
disabled={ disabled }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { __ } from '@wordpress/i18n';
import { Icon, chevronRight } from '@wordpress/icons';
import { globe } from '@wordpress/icons';
import React from 'react';
/*
* Internal dependencies
*/
Expand All @@ -38,15 +39,15 @@ export type LanguageProp = ( typeof LANGUAGE_LIST )[ number ];

type LanguageDropdownControlProps = {
value?: LanguageProp;
onChange: ( value: string ) => void;
onChange: ( value: string, name?: string ) => void;
label?: string;
disabled?: boolean;
};

const defaultLanguageLocale =
window?.Jetpack_Editor_Initial_State?.siteLocale || navigator?.language;

const defaultLabel = __( 'Translate', 'jetpack' );
export const TRANSLATE_LABEL = __( 'Translate', 'jetpack' );

export const defaultLanguage = ( defaultLanguageLocale?.split( '-' )[ 0 ] || 'en' ) as LanguageProp;

Expand Down Expand Up @@ -89,16 +90,6 @@ export const LANGUAGE_MAP = {
ko: {
label: __( 'Korean', 'jetpack' ),
},

id: {
label: __( 'Indonesian', 'jetpack' ),
},
tl: {
label: __( 'Filipino', 'jetpack' ),
},
vi: {
label: __( 'Vietnamese', 'jetpack' ),
},
};

export const I18nMenuGroup = ( {
Expand All @@ -117,7 +108,12 @@ export const I18nMenuGroup = ( {
return (
<MenuItem
key={ `key-${ language }` }
onClick={ () => onChange( language + ' (' + LANGUAGE_MAP[ language ].label + ')' ) }
onClick={ () =>
onChange(
language + ' (' + LANGUAGE_MAP[ language ].label + ')',
LANGUAGE_MAP[ language ].label
)
}
isSelected={ value === language }
>
{ LANGUAGE_MAP[ language ].label }
Expand All @@ -130,7 +126,7 @@ export const I18nMenuGroup = ( {

export default function I18nDropdownControl( {
value = defaultLanguage,
label = defaultLabel,
label = TRANSLATE_LABEL,
onChange,
disabled = false,
}: LanguageDropdownControlProps ) {
Expand Down Expand Up @@ -164,7 +160,7 @@ export default function I18nDropdownControl( {

export function I18nMenuDropdown( {
value = defaultLanguage,
label = defaultLabel,
label = TRANSLATE_LABEL,
onChange,
disabled = false,
}: Pick< LanguageDropdownControlProps, 'label' | 'onChange' | 'value' | 'disabled' > & {
Expand All @@ -187,8 +183,8 @@ export function I18nMenuDropdown( {
>
{ ( { onClose } ) => (
<I18nMenuGroup
onChange={ newLanguage => {
onChange( newLanguage );
onChange={ ( ...args ) => {
onChange( ...args );
onClose();
} }
value={ value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { chevronRight } from '@wordpress/icons';
import React from 'react';
/**
* Internal dependencies
*/
Expand All @@ -23,27 +24,19 @@ const PROMPT_TONES_LIST = [
'formal',
'informal',
'optimistic',
// 'pessimistic',
'humorous',
'serious',
'skeptical',
'empathetic',
// 'enthusiastic',
// 'neutral',
'confident',
// 'curious',
// 'respectful',
'passionate',
// 'cautious',
'provocative',
// 'inspirational',
// 'satirical',
// 'dramatic',
// 'mysterious',
] as const;

export const DEFAULT_PROMPT_TONE = 'formal';

export const TONE_LABEL = __( 'Change tone', 'jetpack' );

export const PROMPT_TONES_MAP = {
formal: {
label: __( 'Formal', 'jetpack' ),
Expand All @@ -57,10 +50,6 @@ export const PROMPT_TONES_MAP = {
label: __( 'Optimistic', 'jetpack' ),
emoji: '😃',
},
// pessimistic: {
// label: __( 'Pessimistic', 'jetpack' ),
// emoji: '☹️',
// },
humorous: {
label: __( 'Humorous', 'jetpack' ),
emoji: '😂',
Expand All @@ -77,54 +66,18 @@ export const PROMPT_TONES_MAP = {
label: __( 'Empathetic', 'jetpack' ),
emoji: '💗',
},
// enthusiastic: {
// label: __( 'Enthusiastic', 'jetpack' ),
// emoji: '🤩',
// },
// neutral: {
// label: __( 'Neutral', 'jetpack' ),
// emoji: '😶',
// },
confident: {
label: __( 'Confident', 'jetpack' ),
emoji: '😎',
},
// curious: {
// label: __( 'Curious', 'jetpack' ),
// emoji: '🧐',
// },
// respectful: {
// label: __( 'Respectful', 'jetpack' ),
// emoji: '🙏',
// },
passionate: {
label: __( 'Passionate', 'jetpack' ),
emoji: '❤️',
},
// cautious: {
// label: __( 'Cautious', 'jetpack' ),
// emoji: '🚧',
// },
provocative: {
label: __( 'Provocative', 'jetpack' ),
emoji: '🔥',
},
// inspirational: {
// label: __( 'Inspirational', 'jetpack' ),
// emoji: '✨',
// },
// satirical: {
// label: __( 'Satirical', 'jetpack' ),
// emoji: '🃏',
// },
// dramatic: {
// label: __( 'Dramatic', 'jetpack' ),
// emoji: '🎭',
// },
// mysterious: {
// label: __( 'Mysterious', 'jetpack' ),
// emoji: '🔮',
// },
};

export type ToneProp = ( typeof PROMPT_TONES_LIST )[ number ];
Expand Down Expand Up @@ -153,7 +106,7 @@ const ToneMenuGroup = ( { value, onChange }: ToneToolbarDropdownMenuProps ) => (
);

export function ToneDropdownMenu( {
label = __( 'Change tone', 'jetpack' ),
label = TONE_LABEL,
value = DEFAULT_PROMPT_TONE,
onChange,
disabled = false,
Expand Down Expand Up @@ -194,7 +147,6 @@ export default function ToneToolbarDropdownMenu( {
onChange,
disabled = false,
}: ToneToolbarDropdownMenuProps ) {
const label = __( 'Change tone', 'jetpack' );
const { tracks } = useAnalytics();

const toggleHandler = isOpen => {
Expand All @@ -204,15 +156,15 @@ export default function ToneToolbarDropdownMenu( {
};

return disabled ? (
<Tooltip text={ label }>
<Tooltip text={ TONE_LABEL }>
<Button disabled>
<Icon icon={ speakToneIcon } />
</Button>
</Tooltip>
) : (
<ToolbarDropdownMenu
icon={ speakToneIcon }
label={ label }
label={ TONE_LABEL }
popoverProps={ {
variant: 'toolbar',
} }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export function blockHandler(

return {
onSuggestion: handler.onSuggestion.bind( handler ),
getContent: handler.getContent.bind( handler ),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* External dependencies
*/
import { ExtensionAIControl } from '@automattic/jetpack-ai-client';
import { useState } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import React from 'react';
/*
* Types
Expand All @@ -13,6 +14,7 @@ import type { ReactElement } from 'react';
export default function AiAssistantInput( {
requestingState,
wrapperRef,
action,
request,
stopSuggestion,
close,
Expand All @@ -24,6 +26,7 @@ export default function AiAssistantInput( {
requestingError?: RequestingErrorProps;
suggestion?: string;
wrapperRef?: React.MutableRefObject< HTMLDivElement | null >;
action?: string;
request: ( question: string ) => void;
stopSuggestion?: () => void;
close?: () => void;
Expand Down Expand Up @@ -52,8 +55,21 @@ export default function AiAssistantInput( {
throw new Error( 'Function not implemented.' );
}

// Clear the input value on reset and when the request is done.
useEffect( () => {
if ( [ 'init', 'done' ].includes( requestingState ) ) {
setValue( '' );
}
}, [ requestingState ] );

// Set the value to the quick action text once it changes.
useEffect( () => {
setValue( action || '' );
}, [ action ] );

return (
<ExtensionAIControl
placeholder={ __( 'Ask Jetpack AI to edit…', 'jetpack' ) }
disabled={ disabled }
value={ value }
state={ requestingState }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ function AiAssistantExtensionToolbarDropdownContent( {
onAskAiAssistant,
onRequestSuggestion,
}: AiAssistantExtensionToolbarDropdownContentProps ) {
const handleRequestSuggestion: OnRequestSuggestion = ( promptType, options ) => {
onRequestSuggestion?.( promptType, options );
const handleRequestSuggestion: OnRequestSuggestion = ( ...args ) => {
onRequestSuggestion?.( ...args );
onClose?.();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
* External dependencies
*/
import { renderMarkdownFromHTML, renderHTMLFromMarkdown } from '@automattic/jetpack-ai-client';
import { rawHandler } from '@wordpress/blocks';
import { rawHandler, getBlockContent } from '@wordpress/blocks';
import { select, dispatch } from '@wordpress/data';
/**
* Types
*/
import type { BlockEditorSelect, IBlockHandler } from '../types';
import type { Block } from '@automattic/jetpack-ai-client';

export function getContent( html ) {
export function getMarkdown( html ) {
return renderMarkdownFromHTML( { content: html } );
}

Expand All @@ -26,6 +26,10 @@ export class HeadingHandler implements IBlockHandler {
this.block = getBlock( clientId );
}

public getContent() {
return getMarkdown( getBlockContent( this.block ) );
}

public onSuggestion( suggestion: string ): void {
// Adjust suggestion if it does not start with a hash.
if ( ! suggestion.startsWith( '#' ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type OnSuggestion = ( suggestion: string ) => void;

export interface IBlockHandler {
onSuggestion: OnSuggestion;
getContent: () => string;
}

export type BlockEditorSelect = {
Expand Down
Loading

0 comments on commit 002b870

Please sign in to comment.