Skip to content

Commit 2516c1f

Browse files
xyOz-devcte
authored andcommitted
memory cleanup (#4190)
* memory cleaanup * forgot to run linter
1 parent ca605df commit 2516c1f

File tree

1 file changed

+50
-31
lines changed

1 file changed

+50
-31
lines changed

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

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
88
import useSound from "use-sound"
99
import { LRUCache } from "lru-cache"
1010

11+
import { useDebounceEffect } from "@src/utils/useDebounceEffect"
12+
1113
import type { ClineAsk, ClineMessage } from "@roo-code/types"
1214

1315
import { ClineSayBrowserAction, ClineSayTool, ExtensionMessage } from "@roo/ExtensionMessage"
@@ -154,6 +156,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
154156
ttl: 1000 * 60 * 15, // 15 minutes TTL for long-running tasks
155157
}),
156158
)
159+
const autoApproveTimeoutRef = useRef<NodeJS.Timeout | null>(null)
157160

158161
const clineAskRef = useRef(clineAsk)
159162
useEffect(() => {
@@ -408,6 +411,12 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
408411
everVisibleMessagesTsRef.current.clear() // Clear for new task
409412
}, [task?.ts])
410413

414+
useEffect(() => {
415+
if (isHidden) {
416+
everVisibleMessagesTsRef.current.clear()
417+
}
418+
}, [isHidden])
419+
411420
useEffect(() => () => everVisibleMessagesTsRef.current.clear(), [])
412421

413422
useEffect(() => {
@@ -714,17 +723,15 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
714723
// NOTE: the VSCode window needs to be focused for this to work.
715724
useMount(() => textAreaRef.current?.focus())
716725

717-
useEffect(() => {
718-
const timer = setTimeout(() => {
726+
useDebounceEffect(
727+
() => {
719728
if (!isHidden && !sendingDisabled && !enableButtons) {
720729
textAreaRef.current?.focus()
721730
}
722-
}, 50)
723-
724-
return () => {
725-
clearTimeout(timer)
726-
}
727-
}, [isHidden, sendingDisabled, enableButtons])
731+
},
732+
50,
733+
[isHidden, sendingDisabled, enableButtons]
734+
)
728735

729736
const visibleMessages = useMemo(() => {
730737
const newVisibleMessages = modifiedMessages.filter((message) => {
@@ -1086,6 +1093,14 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
10861093
[],
10871094
)
10881095

1096+
useEffect(() => {
1097+
return () => {
1098+
if (scrollToBottomSmooth && typeof (scrollToBottomSmooth as any).cancel === 'function') {
1099+
(scrollToBottomSmooth as any).cancel()
1100+
}
1101+
}
1102+
}, [scrollToBottomSmooth])
1103+
10891104
const scrollToBottomAuto = useCallback(() => {
10901105
virtuosoRef.current?.scrollTo({
10911106
top: Number.MAX_SAFE_INTEGER,
@@ -1124,13 +1139,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
11241139
)
11251140

11261141
useEffect(() => {
1127-
let timerId: NodeJS.Timeout | undefined
1142+
let timer: NodeJS.Timeout | undefined
11281143
if (!disableAutoScrollRef.current) {
1129-
timerId = setTimeout(() => scrollToBottomSmooth(), 50)
1144+
timer = setTimeout(() => scrollToBottomSmooth(), 50)
11301145
}
11311146
return () => {
1132-
if (timerId) {
1133-
clearTimeout(timerId)
1147+
if (timer) {
1148+
clearTimeout(timer)
11341149
}
11351150
}
11361151
}, [groupedMessages.length, scrollToBottomSmooth])
@@ -1151,21 +1166,23 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
11511166
// Effect to handle showing the checkpoint warning after a delay
11521167
useEffect(() => {
11531168
// Only show the warning when there's a task but no visible messages yet
1154-
if (task && modifiedMessages.length === 0 && !isStreaming) {
1169+
if (task && modifiedMessages.length === 0 && !isStreaming && !isHidden) {
11551170
const timer = setTimeout(() => {
11561171
setShowCheckpointWarning(true)
11571172
}, 5000) // 5 seconds
11581173

11591174
return () => clearTimeout(timer)
1175+
} else {
1176+
setShowCheckpointWarning(false)
11601177
}
1161-
}, [task, modifiedMessages.length, isStreaming])
1178+
}, [task, modifiedMessages.length, isStreaming, isHidden])
11621179

11631180
// Effect to hide the checkpoint warning when messages appear
11641181
useEffect(() => {
1165-
if (modifiedMessages.length > 0 || isStreaming) {
1182+
if (modifiedMessages.length > 0 || isStreaming || isHidden) {
11661183
setShowCheckpointWarning(false)
11671184
}
1168-
}, [modifiedMessages.length, isStreaming])
1185+
}, [modifiedMessages.length, isStreaming, isHidden])
11691186

11701187
const placeholderText = task ? t("chat:typeMessage") : t("chat:typeTask")
11711188

@@ -1239,38 +1256,40 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
12391256
)
12401257

12411258
useEffect(() => {
1242-
// Only proceed if we have an ask and buttons are enabled.
1259+
if (autoApproveTimeoutRef.current) {
1260+
clearTimeout(autoApproveTimeoutRef.current)
1261+
autoApproveTimeoutRef.current = null
1262+
}
1263+
12431264
if (!clineAsk || !enableButtons) {
12441265
return
12451266
}
12461267

12471268
const autoApprove = async () => {
12481269
if (lastMessage?.ask && isAutoApproved(lastMessage)) {
1249-
// Note that `isAutoApproved` can only return true if
1250-
// lastMessage is an ask of type "browser_action_launch",
1251-
// "use_mcp_server", "command", or "tool".
1252-
1253-
// Add delay for write operations.
12541270
if (lastMessage.ask === "tool" && isWriteToolAction(lastMessage)) {
1255-
await new Promise((resolve) => setTimeout(resolve, writeDelayMs))
1256-
if (!isMountedRef.current) {
1257-
return
1258-
}
1271+
await new Promise<void>((resolve) => {
1272+
autoApproveTimeoutRef.current = setTimeout(resolve, writeDelayMs)
1273+
})
12591274
}
12601275

1261-
vscode.postMessage({ type: "askResponse", askResponse: "yesButtonClicked" })
1276+
if (autoApproveTimeoutRef.current === null || autoApproveTimeoutRef.current) {
1277+
vscode.postMessage({ type: "askResponse", askResponse: "yesButtonClicked" })
12621278

1263-
// This is copied from `handlePrimaryButtonClick`, which we used
1264-
// to call from `autoApprove`. I'm not sure how many of these
1265-
// things are actually needed.
1266-
if (isMountedRef.current) {
12671279
setSendingDisabled(true)
12681280
setClineAsk(undefined)
12691281
setEnableButtons(false)
12701282
}
12711283
}
12721284
}
12731285
autoApprove()
1286+
1287+
return () => {
1288+
if (autoApproveTimeoutRef.current) {
1289+
clearTimeout(autoApproveTimeoutRef.current)
1290+
autoApproveTimeoutRef.current = null
1291+
}
1292+
}
12741293
}, [
12751294
clineAsk,
12761295
enableButtons,

0 commit comments

Comments
 (0)