setIsHovering(true)}
onPointerLeave={() => setIsHovering(false)}
onWheel={(e) => {
if (isSelected || isHovering) {
e.preventDefault()
e.stopPropagation()
if (chatContainerRef.current) {
chatContainerRef.current.scrollTop += e.deltaY
}
}
}}
>
{shape.props.error && (
⚠️
{shape.props.error}
{
this.editor.updateShape({
id: shape.id,
type: "Prompt",
props: { error: null },
})
}}
style={{
marginLeft: "auto",
padding: "4px 8px",
backgroundColor: "#fcc",
border: "1px solid #c99",
borderRadius: "4px",
cursor: "pointer",
fontSize: "11px",
}}
>
Dismiss
)}
{shape.props.value ? (
shape.props.value.split('\n').map((message, index) => {
if (!message.trim()) return null;
try {
const parsed = JSON.parse(message);
const isUser = parsed.role === "user";
return (
{parsed.content}
{
e.stopPropagation()
}}
onClick={async () => {
try {
await navigator.clipboard.writeText(parsed.content)
setCopiedIndex(index)
setTimeout(() => {
setCopiedIndex(null)
}, 2000)
} catch (err) {
console.error('Failed to copy text:', err)
}
}}
onMouseEnter={(e) => {
e.currentTarget.style.opacity = '1'
}}
onMouseLeave={(e) => {
e.currentTarget.style.opacity = '0.7'
}}
>
{copiedIndex === index ? : }
);
} catch {
return null; // Skip invalid JSON
}
})
) : (
"Chat history will appear here..."
)}
{/* AI Personality Selector */}
AI Personality:
{
this.editor.updateShape({
id: shape.id,
type: "Prompt",
props: { personality: e.target.value },
})
}}
style={{
padding: "4px 8px",
border: "1px solid rgba(0, 0, 0, 0.1)",
borderRadius: "4px",
fontSize: "12px",
backgroundColor: "rgba(255, 255, 255, 0.9)",
cursor: "pointer",
height: "28px"
}}
>
{AI_PERSONALITIES.map((personality) => (
{personality.name}
))}
{
this.editor.updateShape({
id: shape.id,
type: "Prompt",
props: { prompt: text.target.value },
})
}}
onKeyDown={(e) => {
e.stopPropagation()
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault()
if (shape.props.prompt.trim() && !shape.props.agentBinding) {
handlePrompt()
}
}
}}
onPointerDown={(e) => {
e.stopPropagation()
}}
onClick={(e) => {
e.stopPropagation()
}}
onFocus={(e) => {
e.stopPropagation()
}}
/>
{
e.stopPropagation()
e.preventDefault()
if (shape.props.prompt.trim() && !shape.props.agentBinding) {
handlePrompt()
}
}}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
if (shape.props.prompt.trim() && !shape.props.agentBinding) {
handlePrompt()
}
}}
type="button"
>
Prompt
{
e.stopPropagation()
}}
onClick={handleCopy}
>
{copyButtonText}