import React, { useRef, useState, useMemo, useEffect, SetStateAction } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { SquarePen, Lightbulb, Navigation, Globe, Copy, SendHorizontal, X, Plus } from 'lucide-react'; import { ScriptData, ScriptBlock, ScriptContent, ThemeTagBgColor, ThemeType } from './types'; import ContentEditable, { ContentEditableEvent } from 'react-contenteditable'; import { SelectDropdown } from '@/components/ui/select-dropdown'; import { TypewriterText } from '@/components/workflow/work-office/common/TypewriterText'; import { msg } from '@/utils/message'; interface ScriptRendererProps { data: any[]; setIsPauseWorkFlow: (isPause: boolean) => void; setAnyAttribute: any; isPauseWorkFlow: boolean; applyScript: any; mode: string; from?: string; setIsUpdate?: (isUpdate: boolean) => void; } export const ScriptRenderer: React.FC = ({ data, setIsPauseWorkFlow, setAnyAttribute, isPauseWorkFlow, applyScript, mode, from, setIsUpdate }) => { const [activeBlockId, setActiveBlockId] = useState(null); const [hoveredBlockId, setHoveredBlockId] = useState(null); const contentRefs = useRef<{ [key: string]: HTMLDivElement | null }>({}); const [editBlockId, setEditBlockId] = useState(null); const contentEditableRef = useRef(null); const [addThemeTag, setAddThemeTag] = useState([]); const [isInit, setIsInit] = useState(true); // 监听继续 请求更新数据 useEffect(() => { const themeBlock = data.find(block => block.id === 'categories'); if (themeBlock && themeBlock.content.length > 0) { const themeTag = themeBlock.content[0].text.split(',').map((item: string) => item.trim()); console.log('themeTag', themeTag); setAddThemeTag(themeTag); } }, [data]); // 添加聚焦效果 useEffect(() => { if (editBlockId && contentEditableRef.current) { setTimeout(() => { contentEditableRef.current?.focus(); // 可选:将光标移到文本末尾 const range = document.createRange(); const sel = window.getSelection(); range.selectNodeContents(contentEditableRef.current as Node); range.collapse(false); sel?.removeAllRanges(); sel?.addRange(range); }, 0); } }, [editBlockId]); const scrollToBlock = (blockId: string) => { const element = contentRefs.current[blockId]; if (element) { element.scrollIntoView({ behavior: 'smooth' }); setActiveBlockId(blockId); } }; // 用于渲染展示的 JSX const renderContent = (content: ScriptContent) => { switch (content.type) { case 'heading': return

{content.text}

; case 'bold': return {content.text}; case 'italic': return {content.text}; default: return

{content.text}

; } }; // 用于生成编辑时的 HTML 字符串 const contentToHtml = (content: ScriptContent): string => { switch (content.type) { case 'heading': return `

${content.text}

`; case 'bold': return `${content.text}`; case 'italic': return `${content.text}`; default: return `

${content.text}

`; } }; // 格式化文本为 HTML const formatTextToHtml = (text: string) => { return text .split('\n') .map(line => line || '
') .join('
'); }; const handleBlockTextChange = (block: ScriptBlock) => (e: ContentEditableEvent) => { // console.log(e.target.value); }; const handleBlockTextBlur = (block: ScriptBlock) => () => { setEditBlockId(null); if (contentEditableRef.current) { const text = contentEditableRef.current.innerText; console.log('contentEditableRef---text', text); console.log('contentEditableRef---block', block.id, block); if (block.content[0].text !== text && setIsUpdate) { setIsUpdate(true); } setAnyAttribute(block.id, text,from !== 'tab',(old: string)=>{ if(old!==text){ console.log('contentEditableRef---change?') // mode.includes('auto') && applyScript(); setIsPauseWorkFlow(false); } }); } }; const handleThemeTagChange = (value: string[]) => { console.log('主题标签更改', value); if (value.length > 5) { msg.error('最多可选择5个主题标签', 3000); return; } setAddThemeTag(value); if (setIsUpdate) { setIsUpdate(true); } from !== 'tab' && setIsPauseWorkFlow(true); setAnyAttribute('categories', value.join(','),from !== 'tab',(old: string)=>{ if(old!==value.join(',')){ // mode.includes('auto') && applyScript(); setIsPauseWorkFlow(false); } }); }; const handleEditBlock = (block: ScriptBlock) => { from !== 'tab' && setIsPauseWorkFlow(true); setIsInit(false); setEditBlockId(block.id); setActiveBlockId(block.id); }; const renderEditBlock = (block: ScriptBlock) => { let blockHtmlText = ''; block.content.forEach(item => { blockHtmlText += contentToHtml(item); }); return ( ); }; const renderTypeBlock = (block: ScriptBlock, isHovered: boolean, isActive: boolean, isEditing: boolean) => { switch (block.id) { case 'categories': return (
{addThemeTag.map((item, index) => (
{item} handleThemeTagChange(addThemeTag.filter(v => v !== item)) } />
))} {/* 主题标签更改 */}
({ label: type, value: type }))} value={addThemeTag} placeholder="Select Theme Type" onChange={(value) => { console.log('主题标签更改', value); handleThemeTagChange(value as string[]); }} />
) default: return ( <> {/* 需要权限控制 */} {(isHovered || isActive) && ( { // 提示权限不够 msg.error('No permission!'); return; handleEditBlock(block); }} /> { navigator.clipboard.writeText(block.content.map(item => item.text).join('\n')); msg.success('Copied!'); }} /> )}
{isEditing ? ( renderEditBlock(block) ) : ( block.content.map((item, index) => ( //
handleEditBlock(block)}>{renderContent(item)}
{renderContent(item)}
)) )}
); } }; const renderBlock = (block: ScriptBlock) => { const isHovered = hoveredBlockId === block.id; const isActive = activeBlockId === block.id; const isEditing = editBlockId === block.id; console.log('block', block) return ( (contentRefs.current[block.id] = el)} onMouseEnter={() => setHoveredBlockId(block.id)} onMouseLeave={() => setHoveredBlockId(null)} initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3 }} >

{block.title}

{ renderTypeBlock(block, isHovered, isActive, isEditing) }
); }; return (
{data.map(renderBlock)}
{/* 翻译功能 待开发 */} {/*

翻译

*/}

navigation

{data.map((block) => ( scrollToBlock(block.id)} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > {block.title} ))}
); };