Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<HTMLDivElement>(null);

const { taskID } = useSafeSearchParams();
const { agentexClient } = useAgentexClient();
Expand Down Expand Up @@ -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 (
<motion.div
className="w-full"
Expand Down Expand Up @@ -90,9 +117,29 @@ function TaskMessageReasoningImpl({ message }: TaskMessageReasoningProps) {
/>
</button>
<Collapsible collapsed={isCollapsed}>
<MarkdownResponse className="ml-6 grid border-l-4 border-gray-300 pl-3 text-gray-500">
{reasoningText}
</MarkdownResponse>
<div className="relative ml-6">
<div
className={cn(
'pointer-events-none absolute inset-x-0 top-0 z-10 h-8 bg-gradient-to-b from-white to-transparent transition-opacity',
showTopBlur ? 'opacity-100' : 'opacity-0'
)}
/>
<div
ref={scrollContainerRef}
onScroll={updateBlurEffects}
className="max-h-48 overflow-y-auto"
>
<MarkdownResponse className="grid border-l-4 border-gray-300 pl-3 text-gray-500">
{reasoningText}
</MarkdownResponse>
</div>
<div
className={cn(
'pointer-events-none absolute inset-x-0 bottom-0 z-10 h-8 bg-gradient-to-t from-white to-transparent transition-opacity',
showBottomBlur ? 'opacity-100' : 'opacity-0'
)}
/>
</div>
</Collapsible>
</motion.div>
);
Expand Down