diff --git a/agentex-ui/components/task-messages/task-message-reasoning-content.tsx b/agentex-ui/components/task-messages/task-message-reasoning-content.tsx index 0910fff4..449c86f6 100644 --- a/agentex-ui/components/task-messages/task-message-reasoning-content.tsx +++ b/agentex-ui/components/task-messages/task-message-reasoning-content.tsx @@ -1,4 +1,4 @@ -import { memo, useState, useMemo } from 'react'; +import { memo, useState, useMemo, useRef, useEffect } from 'react'; import { motion } from 'framer-motion'; import { BrainIcon, ChevronDownIcon } from 'lucide-react'; @@ -21,6 +21,9 @@ type TaskMessageReasoningProps = { function TaskMessageReasoningImpl({ message }: TaskMessageReasoningProps) { const [isCollapsed, setIsCollapsed] = useState(true); + const [showTopBlur, setShowTopBlur] = useState(false); + const [showBottomBlur, setShowBottomBlur] = useState(false); + const scrollContainerRef = useRef(null); const { taskID } = useSafeSearchParams(); const { agentexClient } = useAgentexClient(); @@ -61,6 +64,30 @@ function TaskMessageReasoningImpl({ message }: TaskMessageReasoningProps) { ].join('\n\n'); }, [message.content]); + const updateBlurEffects = () => { + const container = scrollContainerRef.current; + if (!container) return; + + const { scrollTop, scrollHeight, clientHeight } = container; + const isScrollable = scrollHeight > clientHeight; + + setShowTopBlur(isScrollable && scrollTop > 10); + setShowBottomBlur( + isScrollable && scrollTop < scrollHeight - clientHeight - 10 + ); + }; + + useEffect(() => { + const container = scrollContainerRef.current; + if (!container) return; + + updateBlurEffects(); + const resizeObserver = new ResizeObserver(updateBlurEffects); + resizeObserver.observe(container); + + return () => resizeObserver.disconnect(); + }, [isCollapsed, reasoningText]); + return ( - - {reasoningText} - +
+
+
+ + {reasoningText} + +
+
+
);