@@ -22,6 +22,7 @@ import ChatMarkdown from "../ChatMarkdown";
2222import {
2323 BotIcon ,
2424 CheckIcon ,
25+ ChevronRightIcon ,
2526 CircleAlertIcon ,
2627 EyeIcon ,
2728 GlobeIcon ,
@@ -303,6 +304,16 @@ export const MessagesTimeline = memo(function MessagesTimeline({
303304 } ) ) ;
304305 } , [ ] ) ;
305306
307+ const [ collapsedFileSectionsByTurnId , setCollapsedFileSectionsByTurnId ] = useState <
308+ Record < string , boolean >
309+ > ( { } ) ;
310+ const onToggleFileSection = useCallback ( ( turnId : TurnId ) => {
311+ setCollapsedFileSectionsByTurnId ( ( current ) => ( {
312+ ...current ,
313+ [ turnId ] : ! ( current [ turnId ] ?? false ) ,
314+ } ) ) ;
315+ } , [ ] ) ;
316+
306317 const renderRowContent = ( row : TimelineRow ) => (
307318 < div
308319 className = "pb-4"
@@ -463,10 +474,23 @@ export const MessagesTimeline = memo(function MessagesTimeline({
463474 const changedFileCountLabel = String ( checkpointFiles . length ) ;
464475 const allDirectoriesExpanded =
465476 allDirectoriesExpandedByTurnId [ turnSummary . turnId ] ?? true ;
477+ const isFileSectionCollapsed =
478+ collapsedFileSectionsByTurnId [ turnSummary . turnId ] ?? false ;
466479 return (
467480 < div className = "mt-2 rounded-lg border border-border/80 bg-card/45 p-2.5" >
468- < div className = "mb-1.5 flex items-center justify-between gap-2" >
469- < p className = "text-[10px] uppercase tracking-[0.12em] text-muted-foreground/65" >
481+ < div className = "flex items-center justify-between gap-2" >
482+ < button
483+ type = "button"
484+ className = "group flex items-center gap-1.5 text-[10px] uppercase tracking-[0.12em] text-muted-foreground/65 hover:text-muted-foreground/90 transition-colors duration-150"
485+ onClick = { ( ) => onToggleFileSection ( turnSummary . turnId ) }
486+ >
487+ < ChevronRightIcon
488+ aria-hidden = "true"
489+ className = { cn (
490+ "size-3 shrink-0 transition-transform duration-150" ,
491+ ! isFileSectionCollapsed && "rotate-90" ,
492+ ) }
493+ />
470494 < span > Changed files ({ changedFileCountLabel } )</ span >
471495 { hasNonZeroStat ( summaryStat ) && (
472496 < >
@@ -477,16 +501,18 @@ export const MessagesTimeline = memo(function MessagesTimeline({
477501 />
478502 </ >
479503 ) }
480- </ p >
504+ </ button >
481505 < div className = "flex items-center gap-1.5" >
482- < Button
483- type = "button"
484- size = "xs"
485- variant = "outline"
486- onClick = { ( ) => onToggleAllDirectories ( turnSummary . turnId ) }
487- >
488- { allDirectoriesExpanded ? "Collapse all" : "Expand all" }
489- </ Button >
506+ { ! isFileSectionCollapsed && (
507+ < Button
508+ type = "button"
509+ size = "xs"
510+ variant = "outline"
511+ onClick = { ( ) => onToggleAllDirectories ( turnSummary . turnId ) }
512+ >
513+ { allDirectoriesExpanded ? "Collapse all" : "Expand all" }
514+ </ Button >
515+ ) }
490516 < Button
491517 type = "button"
492518 size = "xs"
@@ -499,14 +525,18 @@ export const MessagesTimeline = memo(function MessagesTimeline({
499525 </ Button >
500526 </ div >
501527 </ div >
502- < ChangedFilesTree
503- key = { `changed-files-tree:${ turnSummary . turnId } ` }
504- turnId = { turnSummary . turnId }
505- files = { checkpointFiles }
506- allDirectoriesExpanded = { allDirectoriesExpanded }
507- resolvedTheme = { resolvedTheme }
508- onOpenTurnDiff = { onOpenTurnDiff }
509- />
528+ { ! isFileSectionCollapsed && (
529+ < div className = "mt-1.5" >
530+ < ChangedFilesTree
531+ key = { `changed-files-tree:${ turnSummary . turnId } ` }
532+ turnId = { turnSummary . turnId }
533+ files = { checkpointFiles }
534+ allDirectoriesExpanded = { allDirectoriesExpanded }
535+ resolvedTheme = { resolvedTheme }
536+ onOpenTurnDiff = { onOpenTurnDiff }
537+ />
538+ </ div >
539+ ) }
510540 </ div >
511541 ) ;
512542 } ) ( ) }
0 commit comments