Skip to content

Commit

Permalink
AI Extension: Enhance blocks parsing flickering with child blocks (#3…
Browse files Browse the repository at this point in the history
…2635)

* add block comparison function

* add prompt tweaks and history with examples

* fix streaming flickering

* changelog

* update changelog
  • Loading branch information
dhasilva authored Aug 30, 2023
1 parent abe6bed commit fb9d637
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: enhancement

AI Extension: Enhance blocks parsing flickering with child blocks
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { store as noticesStore } from '@wordpress/notices';
* Internal dependencies
*/
import { isPossibleToExtendJetpackFormBlock } from '..';
import { compareBlocks } from '../../../lib/utils/compare-blocks';
import { fixIncompleteHTML } from '../../../lib/utils/fix-incomplete-html';
import { AiAssistantUiContextProvider } from './context';
/**
Expand Down Expand Up @@ -167,8 +168,28 @@ const withUiHandlerDataProvider = createHigherOrderComponent( BlockListBlock =>
return block.isValid && block.name !== 'core/freeform' && block.name !== 'core/missing';
} );

// Only update the blocks when the valid list changed, meaning a new block arrived.
if ( validBlocks.length !== currentListOfValidBlocks.current.length ) {
let lastBlockUpdated = false;

// While streaming, the last block can go from valid to invalid and back as new children are added token by token.
if ( validBlocks.length < currentListOfValidBlocks.current.length ) {
// The last block is temporarily invalid, so we use the last valid state.
validBlocks.push(
currentListOfValidBlocks.current[ currentListOfValidBlocks.current.length - 1 ]
);
} else if (
validBlocks.length === currentListOfValidBlocks.current.length &&
validBlocks.length > 0
) {
// Update the last valid block with the new content if it is different.
const lastBlock = validBlocks[ validBlocks.length - 1 ];
const lastBlockFromCurrentList =
currentListOfValidBlocks.current[ validBlocks.length - 1 ];

lastBlockUpdated = ! compareBlocks( lastBlock, lastBlockFromCurrentList );
}

// Only update the blocks when the valid list changed, meaning a new block arrived or the last block was updated.
if ( validBlocks.length !== currentListOfValidBlocks.current.length || lastBlockUpdated ) {
// Only update the valid blocks
replaceInnerBlocks( clientId, validBlocks );

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
type Block = {
attributes?: object;
clientId?: string;
innerBlocks?: Block[];
isValid?: boolean;
name?: string;
originalContent?: string;
};

const omitClientId = ( block: Block ): Block => {
delete block.clientId;

for ( const child of block.innerBlocks ?? [] ) {
omitClientId( child );
}

return block;
};

const copyBlock = ( block: Block ): Block => JSON.parse( JSON.stringify( block ) );
const copyBlockWithoutClientId = ( block: Block ) => omitClientId( copyBlock( block ) );

/**
* Deeply compares two blocks, ignoring the clientId property.
*
* @param {Block} blockA - The first block to compare.
* @param {Block} blockB - The second block to compare.
* @returns {boolean} Whether the two blocks are equal.
*/
export function compareBlocks( blockA: Block, blockB: Block ): boolean {
const aCopy = copyBlockWithoutClientId( blockA );
const bCopy = copyBlockWithoutClientId( blockB );

return JSON.stringify( aCopy ) === JSON.stringify( bCopy );
}

0 comments on commit fb9d637

Please sign in to comment.