@@ -6,19 +6,19 @@ import { vscode } from "@/utils/vscode"
66
77import { useAppTranslation } from "@src/i18n/TranslationContext"
88import { useExtensionState } from "@src/context/ExtensionStateContext"
9+ import { SuggestionItem } from "@roo-code/types"
910
10- interface SuggestionItem {
11- answer : string
12- mode ?: string
13- }
11+ const DEFAULT_FOLLOWUP_TIMEOUT_MS = 60000
12+ const COUNTDOWN_INTERVAL_MS = 1000
1413
1514interface FollowUpSuggestProps {
1615 suggestions ?: ( string | SuggestionItem ) [ ]
1716 onSuggestionClick ?: ( answer : string , event ?: React . MouseEvent ) => void
1817 ts : number
18+ onUnmount ?: ( ) => void
1919}
2020
21- export const FollowUpSuggest = ( { suggestions = [ ] , onSuggestionClick, ts = 1 } : FollowUpSuggestProps ) => {
21+ export const FollowUpSuggest = ( { suggestions = [ ] , onSuggestionClick, ts = 1 , onUnmount } : FollowUpSuggestProps ) => {
2222 const { autoApprovalEnabled, alwaysAllowFollowupQuestions, followupAutoApproveTimeoutMs } = useExtensionState ( )
2323 const [ countdown , setCountdown ] = useState < number | null > ( null )
2424 const [ suggestionSelected , setSuggestionSelected ] = useState ( false )
@@ -32,7 +32,7 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
3232 const timeoutMs =
3333 typeof followupAutoApproveTimeoutMs === "number" && ! isNaN ( followupAutoApproveTimeoutMs )
3434 ? followupAutoApproveTimeoutMs
35- : 10000
35+ : DEFAULT_FOLLOWUP_TIMEOUT_MS
3636
3737 // Convert milliseconds to seconds for the countdown
3838 setCountdown ( Math . floor ( timeoutMs / 1000 ) )
@@ -46,10 +46,15 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
4646 }
4747 return prevCountdown - 1
4848 } )
49- } , 1000 )
49+ } , COUNTDOWN_INTERVAL_MS )
5050
51- // Clean up interval on unmount
52- return ( ) => clearInterval ( intervalId )
51+ // Clean up interval on unmount and notify parent component
52+ return ( ) => {
53+ clearInterval ( intervalId )
54+ // Notify parent component that this component is unmounting
55+ // so it can clear any related timeouts
56+ onUnmount ?.( )
57+ }
5358 } else {
5459 setCountdown ( null )
5560 }
@@ -76,11 +81,14 @@ export const FollowUpSuggest = ({ suggestions = [], onSuggestionClick, ts = 1 }:
7681 // Mark a suggestion as selected if it's not a shift-click (which just copies to input)
7782 if ( ! event . shiftKey ) {
7883 setSuggestionSelected ( true )
84+ // Also notify parent component to cancel auto-approval timeout
85+ // This prevents race conditions between visual countdown and actual timeout
86+ onUnmount ?.( )
7987 }
8088
8189 onSuggestionClick ?.( suggestionText , event )
8290 } ,
83- [ onSuggestionClick ] ,
91+ [ onSuggestionClick , onUnmount ] ,
8492 )
8593
8694 // Don't render if there are no suggestions or no click handler.
0 commit comments