Server IP : 162.213.251.212 / Your IP : 13.59.89.228 [ Web Server : LiteSpeed System : Linux business55.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64 User : allssztx ( 535) PHP Version : 8.1.31 Disable Function : NONE Domains : 1 Domains MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/allssztx/./www/jollyprecast/wp-content/plugins/extendify/src/Draft/components/ |
Upload File : |
import { store as blockEditorStore } from '@wordpress/block-editor'; import { createBlock, pasteHandler } from '@wordpress/blocks'; import { MenuGroup, MenuItem, __experimentalDivider as Divider, } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; import { useEffect } from '@wordpress/element'; import { __, isRTL } from '@wordpress/i18n'; import { addSubmenu, rotateLeft, trash, replace, insertAfter, Icon, } from '@wordpress/icons'; import { useContentHighlight } from '@draft/hooks/useContentHighlight'; export const InsertMenu = ({ prompt, completion, loading, setPrompt, setInputText, }) => { const { toggleHighlight, toggleInsertionPoint } = useContentHighlight(); const { insertBlocks, replaceBlocks } = useDispatch(blockEditorStore); const { getSelectedBlock, getSelectedBlockClientIds, getBlockRootClientId, getBlockIndex, getBlock, } = useSelect((select) => select(blockEditorStore), []); const selectedBlock = getSelectedBlock(); const selectedBlockIds = getSelectedBlockClientIds(); const canReplaceContent = () => { const firstBlock = selectedBlock ? selectedBlock : getBlock(selectedBlockIds[0]); if (!firstBlock) return false; // If it's a header or a p, we can replace the content // TODO: support more? const unsupported = ['core/list-item', 'core/button']; if (unsupported.includes(firstBlock?.name)) { // Can we support the same block? const blocks = plainTextToBlocks(completion); return blocks[0]?.name === firstBlock?.name; } return true; }; const canInsertAfter = () => { const firstBlock = selectedBlock ? selectedBlock : getBlock(selectedBlockIds[0]); if (!firstBlock) return true; // TODO: more? or should we go up to the parent? const unsupported = ['core/list-item', 'core/button']; return unsupported.includes(firstBlock?.name) ? false : true; }; const plainTextToBlocks = (plainText) => { const blocks = pasteHandler({ plainText: plainText }); if (!Array.isArray(blocks)) { return [createBlock('core/paragraph', { content: blocks })]; } return blocks; }; const insertCompletion = ({ replaceContent = false, position }) => { setPrompt({ text: '', promptType: '', systemMessageKey: '' }); const targetBlockId = selectedBlock ? selectedBlock?.clientId : selectedBlockIds[0]; const targetBlock = getBlock(targetBlockId); const blocks = plainTextToBlocks(completion); if (!targetBlockId || position === 'end') { insertBlocks(blocks); return; } if (position === 'top') { insertBlocks(blocks, 0); return; } const targetIsEmpty = targetBlock?.attributes?.content === ''; const parentBlockId = getBlockRootClientId(targetBlockId); const blockIndex = getBlockIndex(selectedBlockIds.at(-1), parentBlockId); if (!replaceContent && !targetIsEmpty) { // Multiple blocks are selected, insert after insertBlocks(blocks, blockIndex + 1, parentBlockId); return; } const bothHaveContent = (one, two) => Object.prototype.hasOwnProperty.call(one?.attributes, 'content') && Object.prototype.hasOwnProperty.call(two?.attributes, 'content'); // If both have content, and it's only one block, they can be merged const mergable = blocks.length === 1 && bothHaveContent(targetBlock, blocks[0]); // Apply formatting to all the blocks const formattedBlocks = blocks.map((incomingBlock) => ({ ...incomingBlock, name: mergable ? targetBlock.name : incomingBlock.name, attributes: { ...targetBlock.attributes, content: // If they both have content, they can merge and give it to the incoing block // otherwise just default to the existing block content bothHaveContent(incomingBlock, targetBlock) ? incomingBlock?.attributes?.content : incomingBlock?.attributes?.content, }, })); // TODO: some blocks are harder to replace, like list items // Should we climb up to the parent in this case? // See notes in canReplaceContent() above replaceBlocks(selectedBlockIds, formattedBlocks); }; const discard = () => { setInputText(''); setPrompt({ text: '', promptType: '', systemMessageKey: '' }); }; const retry = () => { setInputText(''); setPrompt({ text: '', promptType: '', systemMessageKey: '' }); setTimeout(() => setPrompt(prompt)); }; useEffect(() => { return () => { toggleHighlight(selectedBlockIds, { isHighlighted: false }); }; }, [selectedBlockIds, toggleHighlight]); return ( <MenuGroup> <MenuItem onClick={() => insertCompletion({ replaceContent: true })} onMouseEnter={() => toggleHighlight(selectedBlockIds, { isHighlighted: true, }) } onMouseLeave={() => toggleHighlight(selectedBlockIds, { isHighlighted: false, }) } disabled={loading || !canReplaceContent()} icon={replace} iconPosition="left" data-test="replace-selected"> {__('Replace selected block text', 'extendify-local')} </MenuItem> <MenuItem onClick={() => insertCompletion({ replaceContent: false, position: 'top' }) } disabled={loading} iconPosition="left" data-test="insert-top"> <div className={isRTL() ? '-mr-1' : '-ml-1'}> <Icon icon={addSubmenu} className="rotate-180" /> </div> <div className="px-1">{__('Insert at top', 'extendify-local')}</div> </MenuItem> <MenuItem onClick={() => insertCompletion({ replaceContent: false })} onMouseEnter={() => toggleInsertionPoint(true)} onMouseLeave={() => toggleInsertionPoint(false)} disabled={loading || !canInsertAfter()} icon={insertAfter} iconPosition="left" data-test="insert-after"> {__('Insert after the selected text', 'extendify-local')} </MenuItem> <MenuItem onClick={() => insertCompletion({ replaceContent: false, position: 'end' }) } disabled={loading} icon={addSubmenu} iconPosition="left" data-test="insert-bottom"> {__('Insert at bottom', 'extendify-local')} </MenuItem> <Divider /> <MenuItem onClick={retry} disabled={loading} icon={rotateLeft} iconPosition="left" data-test="try-again-button"> {__('Try again', 'extendify-local')} </MenuItem> <MenuItem onClick={discard} disabled={loading} icon={trash} iconPosition="left" data-test="discard-button"> {__('Discard', 'extendify-local')} </MenuItem> </MenuGroup> ); };