Skip to content

Commit 657b7fc

Browse files
frenchie4111claude
andauthored
fix(json-chat): restore Chat-mode auto-scroll on streaming + send (#89)
PR #84 added the entriesHydrated gate to suppress the empty-state flash, but the gating made the entire ternary return null on a fresh chat mount (entries=[], !busy, entriesHydrated=false). The scroll container was left with no firstElementChild, so the useLayoutEffect that attaches the ResizeObserver — mounted once with empty deps — found nothing to observe and never re-ran after entries hydrated. From that point on streaming token deltas grew the content but never triggered the snap-to-bottom. Wrap the conditional in a stable min-h-full flex-col div so the RO always has a firstElementChild. The empty-state's previous min-h-full referenced the scroll container; with a wrapper in between, switch it to flex-1 so it fills the wrapper's column and the sparkle card stays centered. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0befb21 commit 657b7fc

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

src/renderer/components/JsonModeChat.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,13 @@ export function JsonModeChat({ sessionId, worktreePath, mode = 'awake' }: JsonMo
16441644
className="flex-1 overflow-y-auto overflow-x-hidden outline-none"
16451645
style={{ overflowAnchor: 'none' }}
16461646
>
1647+
{/* Stable wrapper so the auto-scroll ResizeObserver (mounted once
1648+
with empty deps) always has a firstElementChild to observe.
1649+
Without it, a fresh chat mounts with entriesHydrated=false and
1650+
the empty-state ternary returns null, leaving the scroll
1651+
container childless — the RO is never attached and streaming
1652+
tokens after entries hydrate don't snap to bottom. */}
1653+
<div className="min-h-full flex flex-col">
16471654
{entries.length === 0 && orphanApprovals.length === 0 && !busy ? (
16481655
// Empty-state is only safe to show once we've confirmed there's
16491656
// nothing to display. The wire snapshot ships entries stripped
@@ -1653,7 +1660,7 @@ export function JsonModeChat({ sessionId, worktreePath, mode = 'awake' }: JsonMo
16531660
// Render blank during the fetch; a spinner's appear-then-
16541661
// disappear would itself be a flash.
16551662
entriesHydrated ? (
1656-
<div className="min-h-full flex flex-col items-center justify-center text-center px-4 select-none">
1663+
<div className="flex-1 flex flex-col items-center justify-center text-center px-4 select-none">
16571664
<div className="relative mb-6">
16581665
<div
16591666
className="absolute inset-0 rounded-full blur-2xl opacity-30 brand-gradient-bg"
@@ -1718,6 +1725,7 @@ export function JsonModeChat({ sessionId, worktreePath, mode = 'awake' }: JsonMo
17181725
})()}
17191726
</div>
17201727
)}
1728+
</div>
17211729
</div>
17221730
{showJumpToBottom && (
17231731
<button

0 commit comments

Comments
 (0)