@@ -1363,6 +1363,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
13631363 vscode . postMessage ( { type : "condenseTaskContextRequest" , text : taskId } )
13641364 }
13651365
1366+ const areButtonsVisible = showScrollToBottom || primaryButtonText || secondaryButtonText || isStreaming
1367+
13661368 return (
13671369 < div className = { isHidden ? "hidden" : "fixed top-0 left-0 right-0 bottom-0 flex flex-col overflow-hidden" } >
13681370 { showAnnouncement && < Announcement hideAnnouncement = { hideAnnouncement } /> }
@@ -1447,7 +1449,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
14471449 // but becomes scrollable when the viewport is too small
14481450 */ }
14491451 { ! task && (
1450- < div className = "mb-[-2px] flex-initial min-h-0" >
1452+ < div className = "mb-1 flex-initial min-h-0" >
14511453 < AutoApproveMenu />
14521454 </ div >
14531455 ) }
@@ -1458,7 +1460,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
14581460 < Virtuoso
14591461 ref = { virtuosoRef }
14601462 key = { task . ts } // trick to make sure virtuoso re-renders when task changes, and we use initialTopMostItemIndex to start at the bottom
1461- className = "scrollable grow overflow-y-scroll mb-[5px] "
1463+ className = "scrollable grow overflow-y-scroll mb-1 "
14621464 // increasing top by 3_000 to prevent jumping around when user collapses a row
14631465 increaseViewportBy = { { top : 3_000 , bottom : Number . MAX_SAFE_INTEGER } } // hack to make sure the last message is always rendered to get truly perfect scroll to bottom animation when new messages are added (Number.MAX_SAFE_INTEGER is safe for arithmetic operations, which is all virtuoso uses this value for in src/sizeRangeSystem.ts)
14641466 data = { groupedMessages } // messages is the raw format returned by extension, modifiedMessages is the manipulated structure that combines certain messages of related type, and visibleMessages is the filtered structure that removes messages that should not be rendered
@@ -1474,83 +1476,87 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
14741476 initialTopMostItemIndex = { groupedMessages . length - 1 }
14751477 />
14761478 </ div >
1477- < AutoApproveMenu />
1478- { showScrollToBottom ? (
1479- < div className = "flex px-[15px] pt-[10px]" >
1480- < StandardTooltip content = { t ( "chat:scrollToBottom" ) } >
1481- < div
1482- className = "bg-[color-mix(in_srgb,_var(--vscode-toolbar-hoverBackground)_55%,_transparent)] rounded-[3px] overflow-hidden cursor-pointer flex justify-center items-center flex-1 h-[25px] hover:bg-[color-mix(in_srgb,_var(--vscode-toolbar-hoverBackground)_90%,_transparent)] active:bg-[color-mix(in_srgb,_var(--vscode-toolbar-hoverBackground)_70%,_transparent)]"
1483- onClick = { ( ) => {
1484- scrollToBottomSmooth ( )
1485- disableAutoScrollRef . current = false
1486- } } >
1487- < span className = "codicon codicon-chevron-down text-[18px]" > </ span >
1488- </ div >
1489- </ StandardTooltip >
1490- </ div >
1491- ) : (
1479+ < div className = { `flex-initial min-h-0 ${ ! areButtonsVisible ? "mb-1" : "" } ` } >
1480+ < AutoApproveMenu />
1481+ </ div >
1482+ { areButtonsVisible && (
14921483 < div
1493- className = { `flex ${
1494- primaryButtonText || secondaryButtonText || isStreaming ? "px-[15px] pt-[10px]" : "p-0"
1495- } ${
1496- primaryButtonText || secondaryButtonText || isStreaming
1497- ? enableButtons || ( isStreaming && ! didClickCancel )
1484+ className = { `flex h-9 items-center mb-1 px-[15px] ${
1485+ showScrollToBottom
1486+ ? "opacity-100"
1487+ : enableButtons || ( isStreaming && ! didClickCancel )
14981488 ? "opacity-100"
14991489 : "opacity-50"
1500- : "opacity-0"
15011490 } `} >
1502- { primaryButtonText && ! isStreaming && (
1503- < StandardTooltip
1504- content = {
1505- primaryButtonText === t ( "chat:retry.title" )
1506- ? t ( "chat:retry.tooltip" )
1507- : primaryButtonText === t ( "chat:save.title" )
1508- ? t ( "chat:save.tooltip" )
1509- : primaryButtonText === t ( "chat:approve.title" )
1510- ? t ( "chat:approve.tooltip" )
1511- : primaryButtonText === t ( "chat:runCommand.title" )
1512- ? t ( "chat:runCommand.tooltip" )
1513- : primaryButtonText === t ( "chat:startNewTask.title" )
1514- ? t ( "chat:startNewTask.tooltip" )
1515- : primaryButtonText === t ( "chat:resumeTask.title" )
1516- ? t ( "chat:resumeTask.tooltip" )
1517- : primaryButtonText === t ( "chat:proceedAnyways.title" )
1518- ? t ( "chat:proceedAnyways.tooltip" )
1519- : primaryButtonText ===
1520- t ( "chat:proceedWhileRunning.title" )
1521- ? t ( "chat:proceedWhileRunning.tooltip" )
1522- : undefined
1523- } >
1524- < VSCodeButton
1525- appearance = "primary"
1526- disabled = { ! enableButtons }
1527- className = { secondaryButtonText ? "flex-1 mr-[6px]" : "flex-[2] mr-0" }
1528- onClick = { ( ) => handlePrimaryButtonClick ( inputValue , selectedImages ) } >
1529- { primaryButtonText }
1530- </ VSCodeButton >
1531- </ StandardTooltip >
1532- ) }
1533- { ( secondaryButtonText || isStreaming ) && (
1534- < StandardTooltip
1535- content = {
1536- isStreaming
1537- ? t ( "chat:cancel.tooltip" )
1538- : secondaryButtonText === t ( "chat:startNewTask.title" )
1539- ? t ( "chat:startNewTask.tooltip" )
1540- : secondaryButtonText === t ( "chat:reject.title" )
1541- ? t ( "chat:reject.tooltip" )
1542- : secondaryButtonText === t ( "chat:terminate.title" )
1543- ? t ( "chat:terminate.tooltip" )
1544- : undefined
1545- } >
1491+ { showScrollToBottom ? (
1492+ < StandardTooltip content = { t ( "chat:scrollToBottom" ) } >
15461493 < VSCodeButton
15471494 appearance = "secondary"
1548- disabled = { ! enableButtons && ! ( isStreaming && ! didClickCancel ) }
1549- className = { isStreaming ? "flex-[2] ml-0" : "flex-1 ml-[6px]" }
1550- onClick = { ( ) => handleSecondaryButtonClick ( inputValue , selectedImages ) } >
1551- { isStreaming ? t ( "chat:cancel.title" ) : secondaryButtonText }
1495+ className = "flex-[2]"
1496+ onClick = { ( ) => {
1497+ scrollToBottomSmooth ( )
1498+ disableAutoScrollRef . current = false
1499+ } } >
1500+ < span className = "codicon codicon-chevron-down" > </ span >
15521501 </ VSCodeButton >
15531502 </ StandardTooltip >
1503+ ) : (
1504+ < >
1505+ { primaryButtonText && ! isStreaming && (
1506+ < StandardTooltip
1507+ content = {
1508+ primaryButtonText === t ( "chat:retry.title" )
1509+ ? t ( "chat:retry.tooltip" )
1510+ : primaryButtonText === t ( "chat:save.title" )
1511+ ? t ( "chat:save.tooltip" )
1512+ : primaryButtonText === t ( "chat:approve.title" )
1513+ ? t ( "chat:approve.tooltip" )
1514+ : primaryButtonText === t ( "chat:runCommand.title" )
1515+ ? t ( "chat:runCommand.tooltip" )
1516+ : primaryButtonText === t ( "chat:startNewTask.title" )
1517+ ? t ( "chat:startNewTask.tooltip" )
1518+ : primaryButtonText === t ( "chat:resumeTask.title" )
1519+ ? t ( "chat:resumeTask.tooltip" )
1520+ : primaryButtonText ===
1521+ t ( "chat:proceedAnyways.title" )
1522+ ? t ( "chat:proceedAnyways.tooltip" )
1523+ : primaryButtonText ===
1524+ t ( "chat:proceedWhileRunning.title" )
1525+ ? t ( "chat:proceedWhileRunning.tooltip" )
1526+ : undefined
1527+ } >
1528+ < VSCodeButton
1529+ appearance = "primary"
1530+ disabled = { ! enableButtons }
1531+ className = { secondaryButtonText ? "flex-1 mr-[6px]" : "flex-[2] mr-0" }
1532+ onClick = { ( ) => handlePrimaryButtonClick ( inputValue , selectedImages ) } >
1533+ { primaryButtonText }
1534+ </ VSCodeButton >
1535+ </ StandardTooltip >
1536+ ) }
1537+ { ( secondaryButtonText || isStreaming ) && (
1538+ < StandardTooltip
1539+ content = {
1540+ isStreaming
1541+ ? t ( "chat:cancel.tooltip" )
1542+ : secondaryButtonText === t ( "chat:startNewTask.title" )
1543+ ? t ( "chat:startNewTask.tooltip" )
1544+ : secondaryButtonText === t ( "chat:reject.title" )
1545+ ? t ( "chat:reject.tooltip" )
1546+ : secondaryButtonText === t ( "chat:terminate.title" )
1547+ ? t ( "chat:terminate.tooltip" )
1548+ : undefined
1549+ } >
1550+ < VSCodeButton
1551+ appearance = "secondary"
1552+ disabled = { ! enableButtons && ! ( isStreaming && ! didClickCancel ) }
1553+ className = { isStreaming ? "flex-[2] ml-0" : "flex-1 ml-[6px]" }
1554+ onClick = { ( ) => handleSecondaryButtonClick ( inputValue , selectedImages ) } >
1555+ { isStreaming ? t ( "chat:cancel.title" ) : secondaryButtonText }
1556+ </ VSCodeButton >
1557+ </ StandardTooltip >
1558+ ) }
1559+ </ >
15541560 ) }
15551561 </ div >
15561562 ) }
0 commit comments