Skip to content

Commit 9777a01

Browse files
committed
fix: not using deep compare effect
1 parent dc61677 commit 9777a01

1 file changed

Lines changed: 176 additions & 176 deletions

File tree

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 176 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -160,182 +160,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
160160
vscode.postMessage({ type: "playTts", text })
161161
}
162162

163-
useDeepCompareEffect(() => {
164-
// if last message is an ask, show user ask UI
165-
// if user finished a task, then start a new task with a new conversation history since in this moment that the extension is waiting for user response, the user could close the extension and the conversation history would be lost.
166-
// basically as long as a task is active, the conversation history will be persisted
167-
if (lastMessage) {
168-
switch (lastMessage.type) {
169-
case "ask":
170-
const isPartial = lastMessage.partial === true
171-
switch (lastMessage.ask) {
172-
case "api_req_failed":
173-
playSound("progress_loop")
174-
setTextAreaDisabled(true)
175-
setClineAsk("api_req_failed")
176-
setEnableButtons(true)
177-
setPrimaryButtonText(t("chat:retry.title"))
178-
setSecondaryButtonText(t("chat:startNewTask.title"))
179-
break
180-
case "mistake_limit_reached":
181-
playSound("progress_loop")
182-
setTextAreaDisabled(false)
183-
setClineAsk("mistake_limit_reached")
184-
setEnableButtons(true)
185-
setPrimaryButtonText(t("chat:proceedAnyways.title"))
186-
setSecondaryButtonText(t("chat:startNewTask.title"))
187-
break
188-
case "followup":
189-
if (!isPartial) {
190-
playSound("notification")
191-
}
192-
setTextAreaDisabled(isPartial)
193-
setClineAsk("followup")
194-
// setting enable buttons to `false` would trigger a focus grab when
195-
// the text area is enabled which is undesirable.
196-
// We have no buttons for this tool, so no problem having them "enabled"
197-
// to workaround this issue. See #1358.
198-
setEnableButtons(true)
199-
setPrimaryButtonText(undefined)
200-
setSecondaryButtonText(undefined)
201-
break
202-
case "tool":
203-
if (!isAutoApproved(lastMessage) && !isPartial) {
204-
playSound("notification")
205-
}
206-
setTextAreaDisabled(isPartial)
207-
setClineAsk("tool")
208-
setEnableButtons(!isPartial)
209-
const tool = JSON.parse(lastMessage.text || "{}") as ClineSayTool
210-
switch (tool.tool) {
211-
case "editedExistingFile":
212-
case "appliedDiff":
213-
case "newFileCreated":
214-
case "insertContent":
215-
setPrimaryButtonText(t("chat:save.title"))
216-
setSecondaryButtonText(t("chat:reject.title"))
217-
break
218-
case "finishTask":
219-
setPrimaryButtonText(t("chat:completeSubtaskAndReturn"))
220-
setSecondaryButtonText(undefined)
221-
break
222-
default:
223-
setPrimaryButtonText(t("chat:approve.title"))
224-
setSecondaryButtonText(t("chat:reject.title"))
225-
break
226-
}
227-
break
228-
case "browser_action_launch":
229-
if (!isAutoApproved(lastMessage) && !isPartial) {
230-
playSound("notification")
231-
}
232-
setTextAreaDisabled(isPartial)
233-
setClineAsk("browser_action_launch")
234-
setEnableButtons(!isPartial)
235-
setPrimaryButtonText(t("chat:approve.title"))
236-
setSecondaryButtonText(t("chat:reject.title"))
237-
break
238-
case "command":
239-
if (!isAutoApproved(lastMessage) && !isPartial) {
240-
playSound("notification")
241-
}
242-
setTextAreaDisabled(isPartial)
243-
setClineAsk("command")
244-
setEnableButtons(!isPartial)
245-
setPrimaryButtonText(t("chat:runCommand.title"))
246-
setSecondaryButtonText(t("chat:reject.title"))
247-
break
248-
case "command_output":
249-
setTextAreaDisabled(false)
250-
setClineAsk("command_output")
251-
setEnableButtons(true)
252-
setPrimaryButtonText(t("chat:proceedWhileRunning.title"))
253-
setSecondaryButtonText(t("chat:killCommand.title"))
254-
break
255-
case "use_mcp_server":
256-
if (!isAutoApproved(lastMessage) && !isPartial) {
257-
playSound("notification")
258-
}
259-
setTextAreaDisabled(isPartial)
260-
setClineAsk("use_mcp_server")
261-
setEnableButtons(!isPartial)
262-
setPrimaryButtonText(t("chat:approve.title"))
263-
setSecondaryButtonText(t("chat:reject.title"))
264-
break
265-
case "completion_result":
266-
// extension waiting for feedback. but we can just present a new task button
267-
if (!isPartial) {
268-
playSound("celebration")
269-
}
270-
setTextAreaDisabled(isPartial)
271-
setClineAsk("completion_result")
272-
setEnableButtons(!isPartial)
273-
setPrimaryButtonText(t("chat:startNewTask.title"))
274-
setSecondaryButtonText(undefined)
275-
break
276-
case "resume_task":
277-
if (!isAutoApproved(lastMessage) && !isPartial) {
278-
playSound("notification")
279-
}
280-
setTextAreaDisabled(false)
281-
setClineAsk("resume_task")
282-
setEnableButtons(true)
283-
setPrimaryButtonText(t("chat:resumeTask.title"))
284-
setSecondaryButtonText(t("chat:terminate.title"))
285-
setDidClickCancel(false) // special case where we reset the cancel button state
286-
break
287-
case "resume_completed_task":
288-
if (!isPartial) {
289-
playSound("celebration")
290-
}
291-
setTextAreaDisabled(false)
292-
setClineAsk("resume_completed_task")
293-
setEnableButtons(true)
294-
setPrimaryButtonText(t("chat:startNewTask.title"))
295-
setSecondaryButtonText(undefined)
296-
setDidClickCancel(false)
297-
break
298-
}
299-
break
300-
case "say":
301-
// Don't want to reset since there could be a "say" after
302-
// an "ask" while ask is waiting for response.
303-
switch (lastMessage.say) {
304-
case "api_req_retry_delayed":
305-
setTextAreaDisabled(true)
306-
break
307-
case "api_req_started":
308-
if (secondLastMessage?.ask === "command_output") {
309-
// If the last ask is a command_output, and we
310-
// receive an api_req_started, then that means
311-
// the command has finished and we don't need
312-
// input from the user anymore (in every other
313-
// case, the user has to interact with input
314-
// field or buttons to continue, which does the
315-
// following automatically).
316-
setInputValue("")
317-
setTextAreaDisabled(true)
318-
setSelectedImages([])
319-
setClineAsk(undefined)
320-
setEnableButtons(false)
321-
}
322-
break
323-
case "api_req_finished":
324-
case "error":
325-
case "text":
326-
case "browser_action":
327-
case "browser_action_result":
328-
case "command_output":
329-
case "mcp_server_request_started":
330-
case "mcp_server_response":
331-
case "completion_result":
332-
break
333-
}
334-
break
335-
}
336-
}
337-
}, [lastMessage, secondLastMessage])
338-
339163
useEffect(() => {
340164
if (messages.length === 0) {
341165
setTextAreaDisabled(false)
@@ -850,6 +674,182 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
850674
],
851675
)
852676

677+
useEffect(() => {
678+
// if last message is an ask, show user ask UI
679+
// if user finished a task, then start a new task with a new conversation history since in this moment that the extension is waiting for user response, the user could close the extension and the conversation history would be lost.
680+
// basically as long as a task is active, the conversation history will be persisted
681+
if (lastMessage) {
682+
switch (lastMessage.type) {
683+
case "ask":
684+
const isPartial = lastMessage.partial === true
685+
switch (lastMessage.ask) {
686+
case "api_req_failed":
687+
playSound("progress_loop")
688+
setTextAreaDisabled(true)
689+
setClineAsk("api_req_failed")
690+
setEnableButtons(true)
691+
setPrimaryButtonText(t("chat:retry.title"))
692+
setSecondaryButtonText(t("chat:startNewTask.title"))
693+
break
694+
case "mistake_limit_reached":
695+
playSound("progress_loop")
696+
setTextAreaDisabled(false)
697+
setClineAsk("mistake_limit_reached")
698+
setEnableButtons(true)
699+
setPrimaryButtonText(t("chat:proceedAnyways.title"))
700+
setSecondaryButtonText(t("chat:startNewTask.title"))
701+
break
702+
case "followup":
703+
if (!isPartial) {
704+
playSound("notification")
705+
}
706+
setTextAreaDisabled(isPartial)
707+
setClineAsk("followup")
708+
// setting enable buttons to `false` would trigger a focus grab when
709+
// the text area is enabled which is undesirable.
710+
// We have no buttons for this tool, so no problem having them "enabled"
711+
// to workaround this issue. See #1358.
712+
setEnableButtons(true)
713+
setPrimaryButtonText(undefined)
714+
setSecondaryButtonText(undefined)
715+
break
716+
case "tool":
717+
if (!isAutoApproved(lastMessage) && !isPartial) {
718+
playSound("notification")
719+
}
720+
setTextAreaDisabled(isPartial)
721+
setClineAsk("tool")
722+
setEnableButtons(!isPartial)
723+
const tool = JSON.parse(lastMessage.text || "{}") as ClineSayTool
724+
switch (tool.tool) {
725+
case "editedExistingFile":
726+
case "appliedDiff":
727+
case "newFileCreated":
728+
case "insertContent":
729+
setPrimaryButtonText(t("chat:save.title"))
730+
setSecondaryButtonText(t("chat:reject.title"))
731+
break
732+
case "finishTask":
733+
setPrimaryButtonText(t("chat:completeSubtaskAndReturn"))
734+
setSecondaryButtonText(undefined)
735+
break
736+
default:
737+
setPrimaryButtonText(t("chat:approve.title"))
738+
setSecondaryButtonText(t("chat:reject.title"))
739+
break
740+
}
741+
break
742+
case "browser_action_launch":
743+
if (!isAutoApproved(lastMessage) && !isPartial) {
744+
playSound("notification")
745+
}
746+
setTextAreaDisabled(isPartial)
747+
setClineAsk("browser_action_launch")
748+
setEnableButtons(!isPartial)
749+
setPrimaryButtonText(t("chat:approve.title"))
750+
setSecondaryButtonText(t("chat:reject.title"))
751+
break
752+
case "command":
753+
if (!isAutoApproved(lastMessage) && !isPartial) {
754+
playSound("notification")
755+
}
756+
setTextAreaDisabled(isPartial)
757+
setClineAsk("command")
758+
setEnableButtons(!isPartial)
759+
setPrimaryButtonText(t("chat:runCommand.title"))
760+
setSecondaryButtonText(t("chat:reject.title"))
761+
break
762+
case "command_output":
763+
setTextAreaDisabled(false)
764+
setClineAsk("command_output")
765+
setEnableButtons(true)
766+
setPrimaryButtonText(t("chat:proceedWhileRunning.title"))
767+
setSecondaryButtonText(t("chat:killCommand.title"))
768+
break
769+
case "use_mcp_server":
770+
if (!isAutoApproved(lastMessage) && !isPartial) {
771+
playSound("notification")
772+
}
773+
setTextAreaDisabled(isPartial)
774+
setClineAsk("use_mcp_server")
775+
setEnableButtons(!isPartial)
776+
setPrimaryButtonText(t("chat:approve.title"))
777+
setSecondaryButtonText(t("chat:reject.title"))
778+
break
779+
case "completion_result":
780+
// extension waiting for feedback. but we can just present a new task button
781+
if (!isPartial) {
782+
playSound("celebration")
783+
}
784+
setTextAreaDisabled(isPartial)
785+
setClineAsk("completion_result")
786+
setEnableButtons(!isPartial)
787+
setPrimaryButtonText(t("chat:startNewTask.title"))
788+
setSecondaryButtonText(undefined)
789+
break
790+
case "resume_task":
791+
if (!isAutoApproved(lastMessage) && !isPartial) {
792+
playSound("notification")
793+
}
794+
setTextAreaDisabled(false)
795+
setClineAsk("resume_task")
796+
setEnableButtons(true)
797+
setPrimaryButtonText(t("chat:resumeTask.title"))
798+
setSecondaryButtonText(t("chat:terminate.title"))
799+
setDidClickCancel(false) // special case where we reset the cancel button state
800+
break
801+
case "resume_completed_task":
802+
if (!isPartial) {
803+
playSound("celebration")
804+
}
805+
setTextAreaDisabled(false)
806+
setClineAsk("resume_completed_task")
807+
setEnableButtons(true)
808+
setPrimaryButtonText(t("chat:startNewTask.title"))
809+
setSecondaryButtonText(undefined)
810+
setDidClickCancel(false)
811+
break
812+
}
813+
break
814+
case "say":
815+
// Don't want to reset since there could be a "say" after
816+
// an "ask" while ask is waiting for response.
817+
switch (lastMessage.say) {
818+
case "api_req_retry_delayed":
819+
setTextAreaDisabled(true)
820+
break
821+
case "api_req_started":
822+
if (secondLastMessage?.ask === "command_output") {
823+
// If the last ask is a command_output, and we
824+
// receive an api_req_started, then that means
825+
// the command has finished and we don't need
826+
// input from the user anymore (in every other
827+
// case, the user has to interact with input
828+
// field or buttons to continue, which does the
829+
// following automatically).
830+
setInputValue("")
831+
setTextAreaDisabled(true)
832+
setSelectedImages([])
833+
setClineAsk(undefined)
834+
setEnableButtons(false)
835+
}
836+
break
837+
case "api_req_finished":
838+
case "error":
839+
case "text":
840+
case "browser_action":
841+
case "browser_action_result":
842+
case "command_output":
843+
case "mcp_server_request_started":
844+
case "mcp_server_response":
845+
case "completion_result":
846+
break
847+
}
848+
break
849+
}
850+
}
851+
}, [lastMessage, secondLastMessage, isAutoApproved, t])
852+
853853
useEffect(() => {
854854
// This ensures the first message is not read, future user messages are
855855
// labeled as `user_feedback`.

0 commit comments

Comments
 (0)