Skip to content

Commit e773e7d

Browse files
committed
Improve CLI scroll UX and refactor timer handling
- Add isUserCollapsingRef to prevent auto-scroll during user-initiated collapse actions - Refactor timer handling from simple timerStartTime to comprehensive timer object - Make timer prop optional in MessageBlock for better null safety - Pass timer object through component hierarchy for consistent elapsed time tracking - Fix scroll-to-latest button to use function call syntax
1 parent 3f5d8bc commit e773e7d

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

cli/src/chat.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,18 @@ export const Chat = ({
220220
activeSubagentsRef.current = activeSubagents
221221
}, [activeSubagents])
222222

223+
const abortControllerRef = useRef<AbortController | null>(null)
224+
const isUserCollapsingRef = useRef<boolean>(false)
225+
226+
// Reset the collapse flag after collapse state changes
227+
useEffect(() => {
228+
isUserCollapsingRef.current = false
229+
}, [collapsedAgents])
230+
223231
const { scrollToLatest, scrollboxProps, isAtBottom } = useChatScrollbox(
224232
scrollRef,
225233
messages,
234+
isUserCollapsingRef,
226235
)
227236

228237
const inertialScrollAcceleration = useMemo(
@@ -397,7 +406,7 @@ export const Chat = ({
397406
const hasStatus = useHasStatus({
398407
isActive: isStatusActive,
399408
clipboardMessage,
400-
timerStartTime,
409+
timer: mainAgentTimer,
401410
nextCtrlCWillExit,
402411
})
403412

@@ -504,8 +513,7 @@ export const Chat = ({
504513
<StatusIndicator
505514
clipboardMessage={clipboardMessage}
506515
isActive={isStatusActive}
507-
isWaitingForResponse={isWaitingForResponse}
508-
timerStartTime={timerStartTime}
516+
timer={mainAgentTimer}
509517
nextCtrlCWillExit={nextCtrlCWillExit}
510518
/>
511519
)
@@ -581,11 +589,12 @@ export const Chat = ({
581589
collapsedAgents={collapsedAgents}
582590
streamingAgents={streamingAgents}
583591
isWaitingForResponse={isWaitingForResponse}
584-
timerStartTime={timerStartTime}
592+
timer={mainAgentTimer}
585593
setCollapsedAgents={setCollapsedAgents}
586594
setFocusedAgentId={setFocusedAgentId}
587595
userOpenedAgents={userOpenedAgents}
588596
setUserOpenedAgents={setUserOpenedAgents}
597+
isUserCollapsingRef={isUserCollapsingRef}
589598
onBuildFast={handleBuildFast}
590599
onBuildMax={handleBuildMax}
591600
/>
@@ -625,7 +634,7 @@ export const Chat = ({
625634
{/* Center section - scroll indicator (always centered) */}
626635
<box style={{ flexShrink: 0 }}>
627636
{!isAtBottom && (
628-
<text onMouseDown={scrollToLatest}>
637+
<text onMouseDown={() => scrollToLatest()}>
629638
<span fg={theme.info} attributes={TextAttributes.BOLD}>
630639
631640
</span>

cli/src/components/message-renderer.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ interface MessageRendererProps {
2424
collapsedAgents: Set<string>
2525
streamingAgents: Set<string>
2626
isWaitingForResponse: boolean
27-
timerStartTime: number | null
27+
timer: any
2828
setCollapsedAgents: React.Dispatch<React.SetStateAction<Set<string>>>
2929
setFocusedAgentId: React.Dispatch<React.SetStateAction<string | null>>
3030
userOpenedAgents: Set<string>
3131
setUserOpenedAgents: React.Dispatch<React.SetStateAction<Set<string>>>
32+
isUserCollapsingRef: React.MutableRefObject<boolean>
3233
onBuildFast: () => void
3334
onBuildMax: () => void
3435
}
@@ -44,17 +45,24 @@ export const MessageRenderer = (props: MessageRendererProps): ReactNode => {
4445
collapsedAgents,
4546
streamingAgents,
4647
isWaitingForResponse,
47-
timerStartTime,
48+
timer,
4849
setCollapsedAgents,
4950
setFocusedAgentId,
5051
setUserOpenedAgents,
52+
isUserCollapsingRef,
5153
onBuildFast,
5254
onBuildMax,
5355
} = props
5456

57+
const timerStartTime = timer?.startTime ?? null
58+
5559
const onToggleCollapsed = useCallback(
5660
(id: string) => {
5761
const wasCollapsed = collapsedAgents.has(id)
62+
63+
// Set flag to prevent auto-scroll during user-initiated collapse
64+
isUserCollapsingRef.current = true
65+
5866
setCollapsedAgents((prev) => {
5967
const next = new Set(prev)
6068
if (next.has(id)) {
@@ -74,7 +82,7 @@ export const MessageRenderer = (props: MessageRendererProps): ReactNode => {
7482
return next
7583
})
7684
},
77-
[collapsedAgents, setCollapsedAgents, setUserOpenedAgents],
85+
[collapsedAgents, setCollapsedAgents, setUserOpenedAgents, isUserCollapsingRef],
7886
)
7987

8088
return (
@@ -98,7 +106,7 @@ export const MessageRenderer = (props: MessageRendererProps): ReactNode => {
98106
setUserOpenedAgents={setUserOpenedAgents}
99107
setFocusedAgentId={setFocusedAgentId}
100108
isWaitingForResponse={isWaitingForResponse}
101-
timerStartTime={timerStartTime}
109+
timer={timer}
102110
onToggleCollapsed={onToggleCollapsed}
103111
onBuildFast={onBuildFast}
104112
onBuildMax={onBuildMax}
@@ -124,7 +132,7 @@ interface MessageWithAgentsProps {
124132
setUserOpenedAgents: React.Dispatch<React.SetStateAction<Set<string>>>
125133
setFocusedAgentId: React.Dispatch<React.SetStateAction<string | null>>
126134
isWaitingForResponse: boolean
127-
timerStartTime: number | null
135+
timer: any
128136
onToggleCollapsed: (id: string) => void
129137
onBuildFast: () => void
130138
onBuildMax: () => void
@@ -146,13 +154,14 @@ const MessageWithAgents = memo(
146154
setUserOpenedAgents,
147155
setFocusedAgentId,
148156
isWaitingForResponse,
149-
timerStartTime,
157+
timer,
150158
onToggleCollapsed,
151159
onBuildFast,
152160
onBuildMax,
153161
}: MessageWithAgentsProps): ReactNode => {
154162
const SIDE_GUTTER = 1
155163
const isAgent = message.variant === 'agent'
164+
const timerStartTime = timer?.startTime ?? null
156165

157166
if (isAgent) {
158167
return (
@@ -283,7 +292,7 @@ const MessageWithAgents = memo(
283292
isComplete={message.isComplete}
284293
completionTime={message.completionTime}
285294
credits={message.credits}
286-
timerStartTime={timerStartTime}
295+
timer={timer}
287296
textColor={textColor}
288297
timestampColor={timestampColor}
289298
markdownOptions={markdownOptions}
@@ -358,7 +367,7 @@ const MessageWithAgents = memo(
358367
setUserOpenedAgents={setUserOpenedAgents}
359368
setFocusedAgentId={setFocusedAgentId}
360369
isWaitingForResponse={isWaitingForResponse}
361-
timerStartTime={timerStartTime}
370+
timer={timer}
362371
onToggleCollapsed={onToggleCollapsed}
363372
onBuildFast={onBuildFast}
364373
onBuildMax={onBuildMax}
@@ -602,7 +611,7 @@ const AgentMessage = memo(
602611
setUserOpenedAgents={setUserOpenedAgents}
603612
setFocusedAgentId={setFocusedAgentId}
604613
isWaitingForResponse={isWaitingForResponse}
605-
timerStartTime={timerStartTime}
614+
timer={timer}
606615
onToggleCollapsed={onToggleCollapsed}
607616
onBuildFast={onBuildFast}
608617
onBuildMax={onBuildMax}

0 commit comments

Comments
 (0)