Play screen UX: sticky header + fix streaming autoscroll

- Pin the play header (Plot/Memory/Scripts/Insights toggles) just below
  the top nav so they stay reachable without scrolling back up to the
  first message.
- Fix streaming autoscroll: snap to the real document bottom instantly
  instead of smooth-scrolling to storyEndRef. That ref sits above the
  sticky composer, so block:'end' stopped short — hiding the latest line
  behind the input bar and yanking the reader back up when they scrolled
  down. Smooth behavior also never settled at per-token speed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEpWMjnfPqzZ13nPMoGhs5
This commit is contained in:
parththakkar106
2026-07-20 16:57:16 +05:30
co-authored by Claude Opus 4.8
parent 0971d3feda
commit 8188ed3999
2 changed files with 17 additions and 1 deletions
+12
View File
@@ -288,6 +288,18 @@ button:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: n
.play-page { display: flex; flex-direction: column; min-height: calc(100vh - 56px); } .play-page { display: flex; flex-direction: column; min-height: calc(100vh - 56px); }
/* Keep the Plot/Memory/Scripts/Insights toggles reachable while the story
scrolls — pin the header just below the 56px top nav. */
.play-page .page-header {
position: sticky;
top: 56px;
z-index: 5;
background: var(--bg);
margin-bottom: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--border);
}
.story { .story {
flex: 1; flex: 1;
font-family: var(--font-story); font-family: var(--font-story);
+5 -1
View File
@@ -444,8 +444,12 @@ export default function Play() {
}, []) }, [])
useEffect(() => { useEffect(() => {
// Snap to the real document bottom (below the sticky composer), not to
// storyEndRef — that ref sits above the composer, so block:'end' would
// stop short and fight a reader scrolling down. Instant, not smooth: at
// streaming speed a queued smooth animation never settles.
if (pinnedRef.current) { if (pinnedRef.current) {
storyEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' }) window.scrollTo({ top: document.documentElement.scrollHeight })
} }
}, [actions, streaming, reasoningStream]) }, [actions, streaming, reasoningStream])