From 44a5c8ab226dfc61b74ef514bb059e4b17015acb Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 30 May 2026 18:50:07 -0700 Subject: [PATCH] Fold browser find debounce into search effect (#3275) --- .../components/browser-pane/BrowserFind.tsx | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/renderer/src/components/browser-pane/BrowserFind.tsx b/src/renderer/src/components/browser-pane/BrowserFind.tsx index f0a375f4e4b..454298fccd9 100644 --- a/src/renderer/src/components/browser-pane/BrowserFind.tsx +++ b/src/renderer/src/components/browser-pane/BrowserFind.tsx @@ -14,20 +14,11 @@ export default function BrowserFind({ webviewRef }: BrowserFindProps): React.JSX.Element | null { const inputRef = useRef(null) + const wasOpenRef = useRef(isOpen) const [query, setQuery] = useState('') - const [debouncedQuery, setDebouncedQuery] = useState('') const [activeMatch, setActiveMatch] = useState(0) const [totalMatches, setTotalMatches] = useState(0) - // Why: findInPage re-highlights the active match on every call, which causes - // a visible flash as the user types. Debounce to only re-run once typing - // settles. Enter (findNext/findPrevious) still uses the live `query` so - // explicit navigation is immediate. - useEffect(() => { - const id = setTimeout(() => setDebouncedQuery(query), 200) - return () => clearTimeout(id) - }, [query]) - const safeFindInPage = useCallback( (text: string, opts?: Electron.FindInPageOptions): void => { const webview = webviewRef.current @@ -80,16 +71,29 @@ export default function BrowserFind({ }, [isOpen, safeStopFindInPage]) useEffect(() => { - if (!debouncedQuery) { + const wasOpen = wasOpenRef.current + wasOpenRef.current = isOpen + if (!isOpen) { + return + } + if (!query) { safeStopFindInPage() setActiveMatch(0) setTotalMatches(0) return } - if (isOpen) { - safeFindInPage(debouncedQuery) + + const runFind = (): void => safeFindInPage(query) + if (!wasOpen) { + runFind() + return } - }, [debouncedQuery, isOpen, safeFindInPage, safeStopFindInPage]) + // Why: findInPage re-highlights the active match on every call, which can + // flash while typing. Debounce typing changes, while reopen and Enter + // navigation still use the live query immediately. + const id = window.setTimeout(runFind, 200) + return () => window.clearTimeout(id) + }, [isOpen, query, safeFindInPage, safeStopFindInPage]) // Why: this effect captures `webviewRef.current` into a local variable, so // if the webview element were replaced while `isOpen` stays true the listener