REDROOM
PHP 8.2.31
Path:
Logout
Edit File
Size: 6.07 KB
Close
/home/nshryvcy/radiantskinclinics.org/wp-content/plugins/extendify_old/src/Agent/components/ChatMessages.jsx
Text
Base64
import { AgentMessage } from '@agent/components/messages/AgentMessage'; import { StatusMessage } from '@agent/components/messages/StatusMessage'; import { UserMessage } from '@agent/components/messages/UserMessage'; import { WorkflowComponent } from '@agent/components/messages/WorkflowComponent'; import { WorkflowMessage } from '@agent/components/messages/WorkflowMessage'; import { ScrollDownButton } from '@agent/components/ScrollDownButton'; import { ScrollIntoViewOnce } from '@agent/components/ScrollIntoViewOnce'; import { useWhenFinishedToolProps } from '@agent/hooks/useWhenFinishedToolProps'; import { useChatStore } from '@agent/state/chat'; import { useGlobalStore } from '@agent/state/global'; import { useWorkflowStore } from '@agent/state/workflows'; import { createElement, useEffect, useLayoutEffect, useRef, useState, } from '@wordpress/element'; export const ChatMessages = () => { const { open } = useGlobalStore(); const { messages } = useChatStore(); const { getWorkflow } = useWorkflowStore(); const workflow = getWorkflow(); const whenFinishedToolProps = useWhenFinishedToolProps(); const whenFinishedComponent = workflow?.whenFinished?.component; const [canScrollDown, setCanScrollDown] = useState(false); const containerRef = useRef(null); const isFreshPageLoad = useRef(true); const [ready, setReady] = useState(false); // If last message is a user message, move it to the top const isUserMessage = messages.filter(({ type }) => type !== 'status').at(-1)?.details?.role === 'user'; useEffect(() => { if (!containerRef.current || !open) return; if (!isFreshPageLoad.current) return; isFreshPageLoad.current = false; // Scroll to the bottom of the chat container on load const c = containerRef.current; const last = c.querySelector( '#extendify-agent-chat-scroll-area > :last-child', ); let id2; const id = requestAnimationFrame(() => { id2 = requestAnimationFrame(() => { last?.scrollIntoView({ behavior: 'auto', block: 'start' }); setReady(true); }); }); return () => { cancelAnimationFrame(id); cancelAnimationFrame(id2); isFreshPageLoad.current = true; setReady(false); }; }, [open]); // Handles scrolling to the top of the last user message // TODO: if the user sends in a long message, maybe we scroll to the bottom // of the message offset by 2-3 lines useEffect(() => { if (!containerRef.current) return; if (!isUserMessage) return; const c = containerRef.current; const messages = c.querySelectorAll('[data-agent-message-role="user"]'); const last = messages[messages.length - 1]; if (!last || messages.length < 2) return; const scrollArea = c.querySelector('#extendify-agent-chat-scroll-area'); const lastRect = last.getBoundingClientRect(); const innerHeight = Array.from(scrollArea.children).reduce( (sum, child) => sum + child.offsetHeight, 0, ); const minHeight = innerHeight + c.clientHeight - lastRect.height; scrollArea.style.minHeight = `${minHeight}px`; last.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, [isUserMessage, messages]); // Handles the scroll down button visibility useLayoutEffect(() => { const c = containerRef.current; if (!c) return; const last = c.querySelector( '#extendify-agent-chat-scroll-area > :last-child', ); if (!last) return; const areWeAtBottom = c.scrollTop + c.clientHeight >= c.scrollHeight - 4; if (areWeAtBottom) return setCanScrollDown(false); const observer = new IntersectionObserver( ([entry]) => { const last = c.querySelector( '#extendify-agent-chat-scroll-area > :last-child', ); if (!last) return setCanScrollDown(false); const areWeAtBottom = c.scrollTop + c.clientHeight >= c.scrollHeight - 4; if (areWeAtBottom) return setCanScrollDown(false); setCanScrollDown(!entry.isIntersecting); }, { root: c, threshold: 0.1 }, ); observer.observe(last); return () => observer.disconnect(); }, [messages]); return ( <div ref={containerRef} style={{ overscrollBehavior: 'contain' }} className="relative grow overflow-y-auto overflow-x-hidden p-1 pb-0 text-sm text-gray-900 md:p-2" > <div id="extendify-agent-chat-scroll-area" className={ready ? '' : 'invisible pointer-events-none'} > {messages.map((message) => { const isLastMessage = messages.at(-1)?.id === message.id; const freshLoad = isFreshPageLoad.current; if (message.details?.role === 'user') { return <UserMessage key={message.id} message={message} />; } if (message.details?.role === 'assistant') { return ( <AgentMessage key={message.id} animate={!freshLoad} message={message} /> ); } if (message.type === 'workflow') { return <WorkflowMessage key={message.id} message={message} />; } if (message.type === 'workflow-component') { return <WorkflowComponent key={message.id} message={message} />; } if ( message.type === 'status' && // Only show the status if it's last, or a workflow-tool-completed message (isLastMessage || ['workflow-tool-completed', 'workflow-canceled'].includes( message.details?.type, )) ) { const isError = message.details?.type === 'error'; return ( <StatusMessage animate={!isError} key={message.id} status={message} /> ); } return null; })} {!workflow?.needsRedirect?.() && whenFinishedToolProps?.id && whenFinishedComponent ? ( <ScrollIntoViewOnce> {createElement(whenFinishedComponent, whenFinishedToolProps)} </ScrollIntoViewOnce> ) : null} {workflow?.needsRedirect?.() ? <workflow.redirectComponent /> : null} </div> <ScrollDownButton canScrollDown={canScrollDown} onClick={() => { if (!containerRef.current) return; const c = containerRef.current; // Scroll the last message into view const last = c.querySelector( '#extendify-agent-chat-scroll-area > :last-child', ); if (!last) return; last.scrollIntoView({ behavior: 'smooth', block: 'start' }); }} /> </div> ); };
Save
Close
Exit & Reset
Text mode: syntax highlighting auto-detects file type.
Directory Contents
Dirs: 5 × Files: 13
Delete Selected
Select All
Select None
Sort:
Name
Size
Modified
Enable drag-to-move
Name
Size
Perms
Modified
Actions
buttons
DIR
-
drwxr-xr-x
2026-04-28 02:40:01
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
layouts
DIR
-
drwxr-xr-x
2026-04-28 02:40:01
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
messages
DIR
-
drwxr-xr-x
2026-04-28 02:40:01
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
redirects
DIR
-
drwxr-xr-x
2026-04-28 02:40:01
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
__tests__
DIR
-
drwxr-xr-x
2026-04-28 02:40:01
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ChatInput.jsx
6.98 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ChatMessages.jsx
6.07 KB
lrw-r--r--
2026-03-05 22:57:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ChatSuggestions.jsx
2.94 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ChatTools.jsx
1.28 KB
lrw-r--r--
2026-03-05 22:57:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
DOMHighlighter.jsx
8.77 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ErrorMessage.jsx
872 B
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
GuidedTour.jsx
14.88 KB
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ImageUploader.jsx
6.03 KB
lrw-r--r--
2026-04-09 23:45:00
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
OptionsPopover.jsx
5.36 KB
lrw-r--r--
2026-03-19 23:35:18
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
PageDocument.jsx
1.04 KB
lrw-r--r--
2026-03-05 22:57:38
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Rating.jsx
1.85 KB
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ScrollDownButton.jsx
1.10 KB
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
ScrollIntoViewOnce.jsx
876 B
lrw-r--r--
2026-02-19 03:27:14
Edit
Download
Rename
Chmod
Change Date
Delete
OK
Cancel
recursive
OK
Cancel
recursive
OK
Cancel
Zip Selected
If ZipArchive is unavailable, a
.tar
will be created (no compression).