@@ -179,6 +179,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
179179 const [ showCheckpointWarning , setShowCheckpointWarning ] = useState < boolean > ( false )
180180 const [ isCondensing , setIsCondensing ] = useState < boolean > ( false )
181181 const [ showAnnouncementModal , setShowAnnouncementModal ] = useState ( false )
182+ const [ isModeSwitching , setIsModeSwitching ] = useState < boolean > ( false )
182183 const everVisibleMessagesTsRef = useRef < LRUCache < number , boolean > > (
183184 new LRUCache ( {
184185 max : 100 ,
@@ -1456,6 +1457,14 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
14561457 // Function to switch to a specific mode
14571458 const switchToMode = useCallback (
14581459 ( modeSlug : string ) : void => {
1460+ // Prevent concurrent mode switches
1461+ if ( isModeSwitching ) {
1462+ return
1463+ }
1464+
1465+ // Set flag to prevent concurrent switches
1466+ setIsModeSwitching ( true )
1467+
14591468 // Update local state and notify extension to sync mode change
14601469 setMode ( modeSlug )
14611470
@@ -1464,8 +1473,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
14641473 type : "mode" ,
14651474 text : modeSlug ,
14661475 } )
1476+
1477+ // Reset the flag after a short delay to allow the mode switch to complete
1478+ setTimeout ( ( ) => {
1479+ setIsModeSwitching ( false )
1480+ } , 300 )
14671481 } ,
1468- [ setMode ] ,
1482+ [ setMode , isModeSwitching ] ,
14691483 )
14701484
14711485 const handleSuggestionClickInRow = useCallback (
@@ -1714,23 +1728,31 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
17141728 tSettings ,
17151729 ] )
17161730
1717- // Function to handle mode switching
1718- const switchToNextMode = useCallback ( ( ) => {
1719- const allModes = getAllModes ( customModes )
1720- const currentModeIndex = allModes . findIndex ( ( m ) => m . slug === mode )
1721- const nextModeIndex = ( currentModeIndex + 1 ) % allModes . length
1722- // Update local state and notify extension to sync mode change
1723- switchToMode ( allModes [ nextModeIndex ] . slug )
1724- } , [ mode , customModes , switchToMode ] )
1725-
1726- // Function to handle switching to previous mode
1727- const switchToPreviousMode = useCallback ( ( ) => {
1728- const allModes = getAllModes ( customModes )
1729- const currentModeIndex = allModes . findIndex ( ( m ) => m . slug === mode )
1730- const previousModeIndex = ( currentModeIndex - 1 + allModes . length ) % allModes . length
1731- // Update local state and notify extension to sync mode change
1732- switchToMode ( allModes [ previousModeIndex ] . slug )
1733- } , [ mode , customModes , switchToMode ] )
1731+ // Function to handle mode switching with debouncing
1732+ const switchToNextMode = useMemo (
1733+ ( ) =>
1734+ debounce ( ( ) => {
1735+ const allModes = getAllModes ( customModes )
1736+ const currentModeIndex = allModes . findIndex ( ( m ) => m . slug === mode )
1737+ const nextModeIndex = ( currentModeIndex + 1 ) % allModes . length
1738+ // Update local state and notify extension to sync mode change
1739+ switchToMode ( allModes [ nextModeIndex ] . slug )
1740+ } , 150 ) ,
1741+ [ mode , customModes , switchToMode ] ,
1742+ )
1743+
1744+ // Function to handle switching to previous mode with debouncing
1745+ const switchToPreviousMode = useMemo (
1746+ ( ) =>
1747+ debounce ( ( ) => {
1748+ const allModes = getAllModes ( customModes )
1749+ const currentModeIndex = allModes . findIndex ( ( m ) => m . slug === mode )
1750+ const previousModeIndex = ( currentModeIndex - 1 + allModes . length ) % allModes . length
1751+ // Update local state and notify extension to sync mode change
1752+ switchToMode ( allModes [ previousModeIndex ] . slug )
1753+ } , 150 ) ,
1754+ [ mode , customModes , switchToMode ] ,
1755+ )
17341756
17351757 // Add keyboard event handler
17361758 const handleKeyDown = useCallback (
@@ -1752,13 +1774,20 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
17521774 [ switchToNextMode , switchToPreviousMode ] ,
17531775 )
17541776
1755- // Add event listener
1777+ // Add event listener and cleanup debounced functions
17561778 useEffect ( ( ) => {
17571779 window . addEventListener ( "keydown" , handleKeyDown )
17581780 return ( ) => {
17591781 window . removeEventListener ( "keydown" , handleKeyDown )
1782+ // Cancel any pending debounced calls when unmounting
1783+ if ( typeof ( switchToNextMode as any ) . cancel === "function" ) {
1784+ ; ( switchToNextMode as any ) . cancel ( )
1785+ }
1786+ if ( typeof ( switchToPreviousMode as any ) . cancel === "function" ) {
1787+ ; ( switchToPreviousMode as any ) . cancel ( )
1788+ }
17601789 }
1761- } , [ handleKeyDown ] )
1790+ } , [ handleKeyDown , switchToNextMode , switchToPreviousMode ] )
17621791
17631792 useImperativeHandle ( ref , ( ) => ( {
17641793 acceptInput : ( ) => {
0 commit comments