@@ -60,6 +60,13 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
6060 customModes,
6161 } = useExtensionState ( )
6262
63+ // Use a local state to track the visually active mode
64+ // This prevents flickering when switching modes rapidly by:
65+ // 1. Updating the UI immediately when a mode is clicked
66+ // 2. Not syncing with the backend mode state (which would cause flickering)
67+ // 3. Still sending the mode change to the backend for persistence
68+ const [ visualMode , setVisualMode ] = useState ( mode )
69+
6370 // Memoize modes to preserve array order
6471 const modes = useMemo ( ( ) => getAllModes ( customModes ) , [ customModes ] )
6572
@@ -126,22 +133,25 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
126133 // Handle mode switching with explicit state initialization
127134 const handleModeSwitch = useCallback (
128135 ( modeConfig : ModeConfig ) => {
129- if ( modeConfig . slug === mode ) return // Prevent unnecessary updates
136+ if ( modeConfig . slug === visualMode ) return // Prevent unnecessary updates
137+
138+ // Immediately update visual state for instant feedback
139+ setVisualMode ( modeConfig . slug )
130140
131- // First switch the mode
141+ // Then send the mode change message to the backend
132142 switchMode ( modeConfig . slug )
133143
134144 // Exit tools edit mode when switching modes
135145 setIsToolsEditMode ( false )
136146 } ,
137- [ mode , switchMode , setIsToolsEditMode ] ,
147+ [ visualMode , switchMode , setIsToolsEditMode ] ,
138148 )
139149
140150 // Helper function to get current mode's config
141151 const getCurrentMode = useCallback ( ( ) : ModeConfig | undefined => {
142- const findMode = ( m : ModeConfig ) : boolean => m . slug === mode
152+ const findMode = ( m : ModeConfig ) : boolean => m . slug === visualMode
143153 return customModes ?. find ( findMode ) || modes . find ( findMode )
144- } , [ mode , customModes , modes ] )
154+ } , [ visualMode , customModes , modes ] )
145155
146156 // Helper function to safely access mode properties
147157 const getModeProperty = < T extends keyof ModeConfig > (
@@ -472,7 +482,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
472482
473483 < div className = "flex gap-2 items-center mb-3 flex-wrap py-1" >
474484 { modes . map ( ( modeConfig ) => {
475- const isActive = mode === modeConfig . slug
485+ const isActive = visualMode === modeConfig . slug
476486 return (
477487 < button
478488 key = { modeConfig . slug }
@@ -493,20 +503,20 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
493503
494504 < div style = { { marginBottom : "20px" } } >
495505 { /* Only show name and delete for custom modes */ }
496- { mode && findModeBySlug ( mode , customModes ) && (
506+ { visualMode && findModeBySlug ( visualMode , customModes ) && (
497507 < div className = "flex gap-3 mb-4" >
498508 < div className = "flex-1" >
499509 < div className = "font-bold mb-1" > { t ( "prompts:createModeDialog.name.label" ) } </ div >
500510 < div className = "flex gap-2" >
501511 < VSCodeTextField
502- value = { getModeProperty ( findModeBySlug ( mode , customModes ) , "name" ) ?? "" }
512+ value = { getModeProperty ( findModeBySlug ( visualMode , customModes ) , "name" ) ?? "" }
503513 onChange = { ( e : Event | React . FormEvent < HTMLElement > ) => {
504514 const target =
505515 ( e as CustomEvent ) ?. detail ?. target ||
506516 ( ( e as any ) . target as HTMLInputElement )
507- const customMode = findModeBySlug ( mode , customModes )
517+ const customMode = findModeBySlug ( visualMode , customModes )
508518 if ( customMode ) {
509- updateCustomMode ( mode , {
519+ updateCustomMode ( visualMode , {
510520 ...customMode ,
511521 name : target . value ,
512522 source : customMode . source || "global" ,
@@ -522,7 +532,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
522532 onClick = { ( ) => {
523533 vscode . postMessage ( {
524534 type : "deleteCustomMode" ,
525- slug : mode ,
535+ slug : visualMode ,
526536 } )
527537 } } >
528538 < span className = "codicon codicon-trash" > </ span >
@@ -534,7 +544,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
534544 < div style = { { marginBottom : "16px" } } >
535545 < div className = "flex justify-between items-center mb-1" >
536546 < div className = "font-bold" > { t ( "prompts:roleDefinition.title" ) } </ div >
537- { ! findModeBySlug ( mode , customModes ) && (
547+ { ! findModeBySlug ( visualMode , customModes ) && (
538548 < Button
539549 variant = "ghost"
540550 size = "icon"
@@ -555,25 +565,25 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
555565 </ div >
556566 < VSCodeTextArea
557567 value = { ( ( ) => {
558- const customMode = findModeBySlug ( mode , customModes )
559- const prompt = customModePrompts ?. [ mode ] as PromptComponent
560- return customMode ?. roleDefinition ?? prompt ?. roleDefinition ?? getRoleDefinition ( mode )
568+ const customMode = findModeBySlug ( visualMode , customModes )
569+ const prompt = customModePrompts ?. [ visualMode ] as PromptComponent
570+ return customMode ?. roleDefinition ?? prompt ?. roleDefinition ?? getRoleDefinition ( visualMode )
561571 } ) ( ) }
562572 onChange = { ( e ) => {
563573 const value =
564574 ( e as CustomEvent ) ?. detail ?. target ?. value ||
565575 ( ( e as any ) . target as HTMLTextAreaElement ) . value
566- const customMode = findModeBySlug ( mode , customModes )
576+ const customMode = findModeBySlug ( visualMode , customModes )
567577 if ( customMode ) {
568578 // For custom modes, update the JSON file
569- updateCustomMode ( mode , {
579+ updateCustomMode ( visualMode , {
570580 ...customMode ,
571581 roleDefinition : value . trim ( ) || "" ,
572582 source : customMode . source || "global" ,
573583 } )
574584 } else {
575585 // For built-in modes, update the prompts
576- updateAgentPrompt ( mode , {
586+ updateAgentPrompt ( visualMode , {
577587 roleDefinition : value . trim ( ) || undefined ,
578588 } )
579589 }
@@ -617,7 +627,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
617627 < div className = "mb-4" >
618628 < div className = "flex justify-between items-center mb-1" >
619629 < div className = "font-bold" > { t ( "prompts:tools.title" ) } </ div >
620- { findModeBySlug ( mode , customModes ) && (
630+ { findModeBySlug ( visualMode , customModes ) && (
621631 < Button
622632 variant = "ghost"
623633 size = "icon"
@@ -632,16 +642,16 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
632642 </ Button >
633643 ) }
634644 </ div >
635- { ! findModeBySlug ( mode , customModes ) && (
645+ { ! findModeBySlug ( visualMode , customModes ) && (
636646 < div className = "text-sm text-vscode-descriptionForeground mb-2" >
637647 { t ( "prompts:tools.builtInModesText" ) }
638648 </ div >
639649 ) }
640- { isToolsEditMode && findModeBySlug ( mode , customModes ) ? (
650+ { isToolsEditMode && findModeBySlug ( visualMode , customModes ) ? (
641651 < div className = "grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-2" >
642652 { availableGroups . map ( ( group ) => {
643653 const currentMode = getCurrentMode ( )
644- const isCustomMode = findModeBySlug ( mode , customModes )
654+ const isCustomMode = findModeBySlug ( visualMode , customModes )
645655 const customMode = isCustomMode
646656 const isGroupEnabled = isCustomMode
647657 ? customMode ?. groups ?. some ( ( g ) => getGroupName ( g ) === group )
@@ -710,7 +720,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
710720 marginBottom : "4px" ,
711721 } } >
712722 < div style = { { fontWeight : "bold" } } > { t ( "prompts:customInstructions.title" ) } </ div >
713- { ! findModeBySlug ( mode , customModes ) && (
723+ { ! findModeBySlug ( visualMode , customModes ) && (
714724 < Button
715725 variant = "ghost"
716726 size = "icon"
@@ -738,8 +748,8 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
738748 </ div >
739749 < VSCodeTextArea
740750 value = { ( ( ) => {
741- const customMode = findModeBySlug ( mode , customModes )
742- const prompt = customModePrompts ?. [ mode ] as PromptComponent
751+ const customMode = findModeBySlug ( visualMode , customModes )
752+ const prompt = customModePrompts ?. [ visualMode ] as PromptComponent
743753 return (
744754 customMode ?. customInstructions ??
745755 prompt ?. customInstructions ??
@@ -750,18 +760,18 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
750760 const value =
751761 ( e as CustomEvent ) ?. detail ?. target ?. value ||
752762 ( ( e as any ) . target as HTMLTextAreaElement ) . value
753- const customMode = findModeBySlug ( mode , customModes )
763+ const customMode = findModeBySlug ( visualMode , customModes )
754764 if ( customMode ) {
755765 // For custom modes, update the JSON file
756- updateCustomMode ( mode , {
766+ updateCustomMode ( visualMode , {
757767 ...customMode ,
758768 customInstructions : value . trim ( ) || undefined ,
759769 source : customMode . source || "global" ,
760770 } )
761771 } else {
762772 // For built-in modes, update the prompts
763- const existingPrompt = customModePrompts ?. [ mode ] as PromptComponent
764- updateAgentPrompt ( mode , {
773+ const existingPrompt = customModePrompts ?. [ visualMode ] as PromptComponent
774+ updateAgentPrompt ( visualMode , {
765775 ...existingPrompt ,
766776 customInstructions : value . trim ( ) ,
767777 } )
0 commit comments