1- import { useCallback } from "react"
1+ import { useCallback , useEffect , useState } from "react"
22import { Edit } from "lucide-react"
33
44import { Button , StandardTooltip } from "@/components/ui"
55import { vscode } from "@/utils/vscode"
66
77import { useAppTranslation } from "@src/i18n/TranslationContext"
8+ import { useExtensionState } from "@src/context/ExtensionStateContext"
89
910interface SuggestionItem {
1011 answer : string
@@ -18,7 +19,47 @@ interface FollowUpSuggestProps {
1819}
1920
2021export const FollowUpSuggest = ( { suggestions = [ ] , onSuggestionClick, ts = 1 } : FollowUpSuggestProps ) => {
22+ const { autoApprovalEnabled, alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs } = useExtensionState ( )
23+ const [ countdown , setCountdown ] = useState < number | null > ( null )
24+ const [ suggestionSelected , setSuggestionSelected ] = useState ( false )
2125 const { t } = useAppTranslation ( )
26+
27+ // Start countdown timer when auto-approval is enabled for follow-up questions
28+ useEffect ( ( ) => {
29+ // Only start countdown if auto-approval is enabled for follow-up questions and no suggestion has been selected
30+ if ( autoApprovalEnabled && alwaysAllowFollowupQuestions && suggestions . length > 0 && ! suggestionSelected ) {
31+ // Start with the configured timeout in seconds
32+ const timeoutMs =
33+ typeof followupAutoApproveTimeoutMs === "number" && ! isNaN ( followupAutoApproveTimeoutMs )
34+ ? followupAutoApproveTimeoutMs
35+ : 10000
36+
37+ // Convert milliseconds to seconds for the countdown
38+ setCountdown ( Math . floor ( timeoutMs / 1000 ) )
39+
40+ // Update countdown every second
41+ const intervalId = setInterval ( ( ) => {
42+ setCountdown ( ( prevCountdown ) => {
43+ if ( prevCountdown === null || prevCountdown <= 1 ) {
44+ clearInterval ( intervalId )
45+ return null
46+ }
47+ return prevCountdown - 1
48+ } )
49+ } , 1000 )
50+
51+ // Clean up interval on unmount
52+ return ( ) => clearInterval ( intervalId )
53+ } else {
54+ setCountdown ( null )
55+ }
56+ } , [
57+ autoApprovalEnabled ,
58+ alwaysAllowFollowupQuestions ,
59+ suggestions ,
60+ followupAutoApproveTimeoutMs ,
61+ suggestionSelected ,
62+ ] )
2263 const handleSuggestionClick = useCallback (
2364 ( suggestion : string | SuggestionItem , event : React . MouseEvent ) => {
2465 const suggestionText = typeof suggestion === "string" ? suggestion : suggestion . answer
@@ -32,6 +73,11 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
3273 } )
3374 }
3475
76+ // Mark a suggestion as selected if it's not a shift-click (which just copies to input)
77+ if ( ! event . shiftKey ) {
78+ setSuggestionSelected ( true )
79+ }
80+
3581 onSuggestionClick ?.( suggestionText , event )
3682 } ,
3783 [ onSuggestionClick ] ,
@@ -44,9 +90,10 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
4490
4591 return (
4692 < div className = "flex mb-2 flex-col h-full gap-2" >
47- { suggestions . map ( ( suggestion ) => {
93+ { suggestions . map ( ( suggestion , index ) => {
4894 const suggestionText = typeof suggestion === "string" ? suggestion : suggestion . answer
4995 const mode = typeof suggestion === "object" ? suggestion . mode : undefined
96+ const isFirstSuggestion = index === 0
5097
5198 return (
5299 < div key = { `${ suggestionText } -${ ts } ` } className = "w-full relative group" >
@@ -56,6 +103,13 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
56103 onClick = { ( event ) => handleSuggestionClick ( suggestion , event ) }
57104 aria-label = { suggestionText } >
58105 { suggestionText }
106+ { isFirstSuggestion && countdown !== null && ! suggestionSelected && (
107+ < span
108+ className = "ml-2 px-1.5 py-0.5 text-xs rounded-full bg-vscode-badge-background text-vscode-badge-foreground"
109+ title = { t ( "chat:followUpSuggest.autoSelectCountdown" , { count : countdown } ) } >
110+ { countdown } s
111+ </ span >
112+ ) }
59113 </ Button >
60114 { mode && (
61115 < div className = "absolute bottom-0 right-0 text-[10px] bg-vscode-badge-background text-vscode-badge-foreground px-1 py-0.5 border border-vscode-badge-background flex items-center gap-0.5" >
0 commit comments