authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-08-25 00:01:33-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-25 00:01:33-07:00
loge6d487e4f5d3cd049dbb373c7ca74192302443ae
tree1438ac835cfd6e39cf09049002177a7436c05f27
parentafc8342801d487d96732fdad25454f0c1fe96a3b
signature Signed by PGP key B5690EEEBB952194

fix(web): delay thread shortcut hints by 200 ms (#8172)


2 files changed, 8 insertions(+), 5 deletions(-)

apps/web/src/components/Sidebar.logic.ts+1-1
...@@ -15,7 +15,7 @@ import { isLatestTurnSettled } from "../session-logic";...@@ -15,7 +15,7 @@ import { isLatestTurnSettled } from "../session-logic";
15import { resolveServerBackedAppStageLabel } from "../branding.logic";15import { resolveServerBackedAppStageLabel } from "../branding.logic";
1616
17export const THREAD_SELECTION_SAFE_SELECTOR = "[data-thread-item], [data-thread-selection-safe]";17export const THREAD_SELECTION_SAFE_SELECTOR = "[data-thread-item], [data-thread-selection-safe]";
18export const THREAD_JUMP_HINT_SHOW_DELAY_MS = 100;18export const THREAD_JUMP_HINT_SHOW_DELAY_MS = 200;
19// Visible sidebar rows are prewarmed into the thread-detail cache so opening a19// Visible sidebar rows are prewarmed into the thread-detail cache so opening a
20// nearby thread usually reuses an already-hot subscription. Each prewarmed20// nearby thread usually reuses an already-hot subscription. Each prewarmed
21// thread holds a live, fully hydrated detail subscription (all messages and21// thread holds a live, fully hydrated detail subscription (all messages and
apps/web/src/components/Sidebar.tsx+7-4
...@@ -142,6 +142,7 @@ import {...@@ -142,6 +142,7 @@ import {
142 sortPinnedThreadsForSidebar,142 sortPinnedThreadsForSidebar,
143 sortSettledThreadsForSidebar,143 sortSettledThreadsForSidebar,
144 sortThreadsForSidebar,144 sortThreadsForSidebar,
145 useThreadJumpHintVisibility,
145} from "./Sidebar.logic";146} from "./Sidebar.logic";
146import { resolveLocalCheckoutBranchMismatch } from "./BranchToolbar.logic";147import { resolveLocalCheckoutBranchMismatch } from "./BranchToolbar.logic";
147import {148import {
...@@ -2308,7 +2309,7 @@ export default function Sidebar() {...@@ -2308,7 +2309,7 @@ export default function Sidebar() {
2308 }2309 }
2309 return mapping;2310 return mapping;
2310 }, [keybindings, orderedThreadKeys]);2311 }, [keybindings, orderedThreadKeys]);
2311 const [showJumpHints, setShowJumpHints] = useState(false);2312 const { showThreadJumpHints, updateThreadJumpHintsVisibility } = useThreadJumpHintVisibility();
23122313
2313 // Settled threads are live shells, so opening one is plain navigation:2314 // Settled threads are live shells, so opening one is plain navigation:
2314 // history stays readable without un-settling, and sending a message or2315 // history stays readable without un-settling, and sending a message or
...@@ -3342,8 +3343,8 @@ export default function Sidebar() {...@@ -3342,8 +3343,8 @@ export default function Sidebar() {
3342 },3343 },
3343 );3344 );
3344 useEffect(() => {3345 useEffect(() => {
3345 setShowJumpHints(shouldShowJumpHintsNow);3346 updateThreadJumpHintsVisibility(shouldShowJumpHintsNow);
3346 }, [shouldShowJumpHintsNow]);3347 }, [shouldShowJumpHintsNow, updateThreadJumpHintsVisibility]);
33473348
3348 const attachListAutoAnimateRef = useCallback((node: HTMLUListElement | null) => {3349 const attachListAutoAnimateRef = useCallback((node: HTMLUListElement | null) => {
3349 if (!node) return;3350 if (!node) return;
...@@ -3721,7 +3722,9 @@ export default function Sidebar() {...@@ -3721,7 +3722,9 @@ export default function Sidebar() {
3721 wokeAt={threadWokeAt(thread, { now: snoozeNow })}3722 wokeAt={threadWokeAt(thread, { now: snoozeNow })}
3722 isActive={routeThreadKey === threadKey}3723 isActive={routeThreadKey === threadKey}
3723 openPullRequestsInRightPanel={routeThreadRef !== null}3724 openPullRequestsInRightPanel={routeThreadRef !== null}
3724 jumpLabel={showJumpHints ? (jumpLabelByKey.get(threadKey) ?? null) : null}3725 jumpLabel={
3726 showThreadJumpHints ? (jumpLabelByKey.get(threadKey) ?? null) : null
3727 }
3725 currentEnvironmentId={primaryEnvironmentId}3728 currentEnvironmentId={primaryEnvironmentId}
3726 environmentLabel={environmentLabelById.get(thread.environmentId) ?? null}3729 environmentLabel={environmentLabelById.get(thread.environmentId) ?? null}
3727 projectCwd={3730 projectCwd={