@@ -75,6 +75,10 @@ interface ChatRowProps {
7575 onFollowUpUnmount ?: ( ) => void
7676 isFollowUpAnswered ?: boolean
7777 editable ?: boolean
78+ // External edit controls to avoid losing state during virtualization re-mounts
79+ editingTs ?: number | null
80+ onStartEditing ?: ( ts : number ) => void
81+ onCancelEditing ?: ( ) => void
7882}
7983
8084// eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -127,12 +131,15 @@ export const ChatRowContent = ({
127131 onBatchFileResponse,
128132 isFollowUpAnswered,
129133 editable,
134+ editingTs,
135+ onStartEditing,
136+ onCancelEditing,
130137} : ChatRowContentProps ) => {
131138 const { t } = useTranslation ( )
132139
133140 const { mcpServers, alwaysAllowMcp, currentCheckpoint, mode, apiConfiguration } = useExtensionState ( )
134141 const { info : model } = useSelectedModel ( apiConfiguration )
135- const [ isEditing , setIsEditing ] = useState ( false )
142+ const isEditing = ( editingTs ?? null ) === message . ts
136143 const [ editedContent , setEditedContent ] = useState ( "" )
137144 const [ editMode , setEditMode ] = useState < Mode > ( mode || "code" )
138145 const [ editImages , setEditImages ] = useState < string [ ] > ( [ ] )
@@ -170,13 +177,13 @@ export const ChatRowContent = ({
170177 // no-op
171178 }
172179
173- setIsEditing ( true )
180+ onStartEditing ?. ( message . ts )
174181 setEditedContent ( message . text || "" )
175182 setEditImages ( message . images || [ ] )
176183 setEditMode ( mode || "code" )
177184 // Edit mode is now handled entirely in the frontend
178185 // No need to notify the backend
179- } , [ message . text , message . images , mode ] )
186+ } , [ message . ts , message . text , message . images , mode , onStartEditing ] )
180187
181188 // Ensure the edit textarea is focused and scrolled into view when entering edit mode.
182189 // Uses a short delay and a few animation frames to allow virtualization reflow before scrolling.
@@ -256,23 +263,24 @@ export const ChatRowContent = ({
256263
257264 // Handle cancel edit
258265 const handleCancelEdit = useCallback ( ( ) => {
259- setIsEditing ( false )
266+ onCancelEditing ?. ( )
260267 setEditedContent ( message . text || "" )
261268 setEditImages ( message . images || [ ] )
262269 setEditMode ( mode || "code" )
263- } , [ message . text , message . images , mode ] )
270+ } , [ message . text , message . images , mode , onCancelEditing ] )
264271
265272 // Handle save edit
266273 const handleSaveEdit = useCallback ( ( ) => {
267- setIsEditing ( false )
268274 // Send edited message to backend
269275 vscode . postMessage ( {
270276 type : "submitEditedMessage" ,
271277 value : message . ts ,
272278 editedMessageContent : editedContent ,
273279 images : editImages ,
274280 } )
275- } , [ message . ts , editedContent , editImages ] )
281+ // Exit edit mode
282+ onCancelEditing ?.( )
283+ } , [ message . ts , editedContent , editImages , onCancelEditing ] )
276284
277285 // Handle image selection for editing
278286 const handleSelectImages = useCallback ( ( ) => {
0 commit comments