From 38d3b1d458cedb65c741b4a14e26b11d2c8b28ea Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 31 May 2026 09:18:21 -0700 Subject: [PATCH] perf: move mobile session timer cleanup to root ref --- .../app/h/[hostId]/session/[worktreeId].tsx | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/mobile/app/h/[hostId]/session/[worktreeId].tsx b/mobile/app/h/[hostId]/session/[worktreeId].tsx index 6c214f1d6..fb2b78b76 100644 --- a/mobile/app/h/[hostId]/session/[worktreeId].tsx +++ b/mobile/app/h/[hostId]/session/[worktreeId].tsx @@ -1168,17 +1168,6 @@ export default function SessionScreen() { [clearToastHideTimer] ) - useEffect(() => { - return () => { - // Why: toast timers can outlive quick route changes; bump the sequence - // so pending animation callbacks cannot clear a newer/unmounted surface. - toastSeqRef.current += 1 - clearToastHideTimer() - clearDelayedActionTimers() - clearTerminalLiveInputFocusTimer(liveInputFocusTimerRef) - } - }, [clearDelayedActionTimers, clearToastHideTimer]) - const dictation = useMobileDictation({ client, enabled: canSend, @@ -2977,9 +2966,21 @@ export default function SessionScreen() { }, [stopAccessoryRepeat] ) - useEffect(() => { - return () => stopAccessoryRepeat() - }, [stopAccessoryRepeat]) + const setMobileSessionRootRef = useCallback( + (node: View | null): void => { + if (node !== null) { + return + } + // Why: route-level timers can outlive quick session changes; clear them + // from the root lifecycle without passive cleanup-only Effects. + toastSeqRef.current += 1 + clearToastHideTimer() + clearDelayedActionTimers() + clearTerminalLiveInputFocusTimer(liveInputFocusTimerRef) + stopAccessoryRepeat() + }, + [clearDelayedActionTimers, clearToastHideTimer, stopAccessoryRepeat] + ) const handleSelectionMode = useCallback((handle: string, active: boolean) => { if (handle !== activeHandleRef.current) return @@ -3662,7 +3663,7 @@ export default function SessionScreen() { : [] return ( - +