[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: InsertMenu.jsx
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 { __ } 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="-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> ); };
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: premium166.web-hosting.com
Server IP: 162.0.209.40
PHP Version: 8.1.34
Server Software: LiteSpeed
System: Linux premium166.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
HDD Total: 97.87 GB
HDD Free: 75.11 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
No
pkexec:
No
git:
Yes
User Info
Username: kataubyb
User ID (UID): 624
Group ID (GID): 625
Script Owner UID: 624
Current Dir Owner: 624