added possibility to send any blocks as context

This commit is contained in:
Nikita 2024-12-12 10:36:33 +03:00
parent 207b97c6cc
commit 1e37194365
7 changed files with 50 additions and 39 deletions

View file

@ -202,6 +202,7 @@ class Mind_Rest extends WP_REST_Controller {
[
'Rules:',
$context ? '- The context for the user request placed under "Context".' : '',
$context ? '- Context usually contains the current blocks JSON, use it to improve by the user request. Try to keep essential information, links and images.' : '',
'- Respond to the user request placed under "Request".',
'- See the "Response Format Rules" section for block output rules.',
'- Avoid offensive or sensitive content.',

View file

@ -27,6 +27,7 @@ import { ReactComponent as AIImproveIcon } from '../../../icons/ai-improve.svg';
import { ReactComponent as AIFixSpellingIcon } from '../../../icons/ai-fix-spelling.svg';
import { ReactComponent as AIShorterIcon } from '../../../icons/ai-shorter.svg';
import { ReactComponent as AILongerIcon } from '../../../icons/ai-longer.svg';
import { ReactComponent as AIMessage } from '../../../icons/ai-message.svg';
import { ReactComponent as AISummarizeIcon } from '../../../icons/ai-summarize.svg';
import { ReactComponent as AIToneIcon } from '../../../icons/ai-tone.svg';
import { ReactComponent as AIParaphraseIcon } from '../../../icons/ai-paraphrase.svg';
@ -34,8 +35,6 @@ import { ReactComponent as AITranslateIcon } from '../../../icons/ai-translate.s
import { ReactComponent as MindLogoIcon } from '../../../icons/mind-logo.svg';
import wrapEmoji from '../../../utils/wrap-emoji';
const ALLOWED_BLOCKS = ['core/paragraph', 'core/heading'];
const TONE = [
[__('professional', 'mind'), __('🧐 Professional', 'mind')],
[__('friendly', 'mind'), __('😀 Friendly', 'mind')],
@ -63,16 +62,6 @@ const LANGUAGE = [
[__('vietnamese', 'mind'), __('🇻🇳 Vietnamese', 'mind')],
];
/**
* Check if Mind allowed in block toolbar.
*
* @param {Object} data - block data.
* @return {boolean} allowed.
*/
function isToolbarAllowed(data) {
return ALLOWED_BLOCKS.includes(data.name);
}
function Toolbar() {
const { open, setInput, setContext, setInsertionPlace, requestAI } =
useDispatch('mind/popup');
@ -82,7 +71,10 @@ function Toolbar() {
setInput(prompt);
setContext('selected-blocks');
setInsertionPlace('selected-blocks');
requestAI();
if (prompt) {
requestAI();
}
}
return (
@ -97,6 +89,15 @@ function Toolbar() {
return (
<>
<MenuGroup>
<MenuItem
icon={<AIMessage />}
iconPosition="left"
onClick={() => {
openModal();
}}
>
{__('Ask AI', 'mind')}
</MenuItem>
<MenuItem
icon={<AIImproveIcon />}
iconPosition="left"
@ -290,12 +291,6 @@ function Toolbar() {
*/
const withToolbarControl = createHigherOrderComponent((OriginalComponent) => {
function MindToolbarToggle(props) {
const allow = isToolbarAllowed(props);
if (!allow) {
return <OriginalComponent {...props} />;
}
return (
<>
<OriginalComponent {...props} />

View file

@ -11,15 +11,6 @@ import { useDispatch, useSelect } from '@wordpress/data';
*/
import EditorStyles from '../../components/editor-styles';
const HIGHLIGHT_BLOCKS = [
'core/paragraph',
'core/list',
'core/code',
'core/preformatted',
'core/quote',
'core/blockquote',
];
/**
* Add new blocks highlight to see what exactly added by the AI.
*
@ -30,7 +21,7 @@ const HIGHLIGHT_BLOCKS = [
const withMindAIEditorStyles = createHigherOrderComponent(
(OriginalComponent) => {
function MindHighlightInsertedBlocks(props) {
const { name, clientId } = props;
const { clientId } = props;
const [animateOpacity, setAnimateOpacity] = useState(false);
@ -45,7 +36,6 @@ const withMindAIEditorStyles = createHigherOrderComponent(
});
const allowHighlight =
HIGHLIGHT_BLOCKS.includes(name) &&
highlightBlocks &&
highlightBlocks.length &&
highlightBlocks.includes(clientId);

View file

@ -5,7 +5,7 @@ import './style.scss';
*/
import { __ } from '@wordpress/i18n';
import { createRoot } from '@wordpress/element';
import { subscribe, useDispatch } from '@wordpress/data';
import { subscribe, useSelect, useDispatch } from '@wordpress/data';
import domReady from '@wordpress/dom-ready';
// eslint-disable-next-line import/no-extraneous-dependencies
import { throttle } from 'lodash';
@ -18,7 +18,14 @@ import { ReactComponent as MindLogoIcon } from '../../../icons/mind-logo.svg';
const TOOLBAR_TOGGLE_CONTAINER_CLASS = 'mind-post-toolbar-toggle';
function Toggle() {
const { toggle } = useDispatch('mind/popup');
const { open, setContext, setInsertionPlace } = useDispatch('mind/popup');
const { getSelectedBlockClientIds } = useSelect((select) => {
return {
getSelectedBlockClientIds:
select('core/block-editor').getSelectedBlockClientIds,
};
});
return (
<button
@ -27,7 +34,17 @@ function Toggle() {
onClick={(e) => {
e.preventDefault();
toggle();
open();
const selectedIDs = getSelectedBlockClientIds();
// This is a temporary solution to provide context when multiple blocks selected.
// We need this because Gutenberg does not provide an ability to add toolbar button when multiple selection.
// We actually should make a toggle in `extensions/block-toolbar/index.js` to handle this case.
if (selectedIDs && selectedIDs.length > 1) {
setContext('selected-blocks');
setInsertionPlace('selected-blocks');
}
}}
>
<MindLogoIcon />

View file

@ -8,7 +8,7 @@ import apiFetch from '@wordpress/api-fetch';
* Internal dependencies.
*/
import BlocksStreamProcessor from '../../processors/blocks-stream-processor';
import getSelectedBlocksContent from '../../../utils/get-selected-blocks-content';
import getSelectedBlocksJSON from '../../../utils/get-selected-blocks-json';
import { isConnected } from '../core/selectors';
export function open() {
@ -105,7 +105,7 @@ export function requestAI() {
// Add context if needed
if (select.getContext() === 'selected-blocks') {
data.context = getSelectedBlocksContent();
data.context = getSelectedBlocksJSON();
}
// Initialize stream processor

8
src/icons/ai-message.svg Normal file
View file

@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M8.27676 18.7113C9.98373 19.5869 11.9473 19.8241 13.8137 19.3801C15.6801 18.936 17.3265 17.84 18.4562 16.2895C19.586 14.739 20.1248 12.8359 19.9756 10.9233C19.8264 9.01062 18.999 7.21415 17.6424 5.8576C16.2858 4.50104 14.4894 3.67361 12.5767 3.52439C10.6641 3.37518 8.76104 3.91401 7.21052 5.04377C5.66 6.17354 4.56397 7.81994 4.11995 9.68631C3.67592 11.5527 3.9131 13.5163 4.78873 15.2232L3 20.5L8.27676 18.7113Z"
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
<path d="M8 11.5H8.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
<path d="M12 11.5H12.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
<path d="M16 11.5H16.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>

After

Width:  |  Height:  |  Size: 966 B

View file

@ -1,17 +1,17 @@
export default function getSelectedBlocksContent() {
export default function getSelectedBlocksJSON() {
const { getBlock, getSelectedBlockClientIds } =
wp.data.select('core/block-editor');
const ids = getSelectedBlockClientIds();
let blocksContent = '';
const blocksJSON = [];
ids.forEach((id) => {
const blockData = getBlock(id);
if (blockData?.attributes?.content) {
blocksContent = `${blocksContent}<p>${blockData.attributes.content}</p>`;
blocksJSON.push(blockData);
}
});
return blocksContent;
return JSON.stringify(blocksJSON);
}