WIP: PWA chat: anchor the user's message to the top of the viewport so the reply fills the screen below it #605

Draft
toasterson wants to merge 4 commits from claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th into main
Owner

Anima work item 019ff173-ddf7-74f3-9097-39e51ac67917.

anima-pwa/src/components/chat/ChatScroller.tsx only pins to the BOTTOM. When you send a message the view stays glued to the last pixel, so a long agent turn streams past you from the bottom edge and you are always reading the tail. The familiar behaviour — and the one the design implies — is that your own message jumps to the TOP of the viewport and the response then fills the empty screen beneath it, so you read the answer from its beginning.

REFERENCE PATTERN (do not copy the dep, copy the idea): shadcn-ui/chatbot-template marks each scroller item with scrollAnchor={message.role === "user"} and gives the content wrapper min-h-full, so a short turn still stretches to a full viewport and the anchored message can actually reach the top.

WHAT TO BUILD

  • A per-item opt-in anchor. Sending a user message scrolls that item's top edge to the top of the scroll container.
  • The content wrapper inside ChatScroller gets a minimum height of the viewport so a one-line reply still leaves the anchored message at the top instead of springing back.
  • Once the anchored turn's content grows past the viewport, normal bottom-stick resumes — the user should end up following the stream as usual, not stranded at an anchor.

CONSTRAINTS

  • ChatScroller's existing handleScroll distinguishes our own programmatic pin's echo from a real user scroll (pinnedAt, animating, stick refs). An anchor scroll is ALSO programmatic and MUST NOT be read as the user detaching, or follow will silently disengage mid-turn. Extend that same discrimination; do not bolt on a second uncoordinated scroll path.
  • Keep the existing useStick() context shape. ScrollToBottomButton consumes it and must keep working, including its unread-count re-arming behaviour.
  • No new dependency. We deliberately hand-rolled this instead of taking use-stick-to-bottom.

VERIFY

  • Extend ChatScroller.test.tsx: an anchored item scrolls to top; the anchor scroll does not clear the stick flag; bottom-stick resumes once content exceeds the viewport. jsdom has no scrollTo on elements — the existing tests already work around this, follow that approach.
  • Manually smoke on /prototype/chat (the specimen board at src/pages/ChatPrototype/) with a simulated turn, and on a real thread.
  • Do not land this concurrently with the content-visibility item — both touch ChatScroller.tsx.
Anima work item `019ff173-ddf7-74f3-9097-39e51ac67917`. `anima-pwa/src/components/chat/ChatScroller.tsx` only pins to the BOTTOM. When you send a message the view stays glued to the last pixel, so a long agent turn streams past you from the bottom edge and you are always reading the tail. The familiar behaviour — and the one the design implies — is that your own message jumps to the TOP of the viewport and the response then fills the empty screen beneath it, so you read the answer from its beginning. REFERENCE PATTERN (do not copy the dep, copy the idea): `shadcn-ui/chatbot-template` marks each scroller item with `scrollAnchor={message.role === "user"}` and gives the content wrapper `min-h-full`, so a short turn still stretches to a full viewport and the anchored message can actually reach the top. WHAT TO BUILD - A per-item opt-in anchor. Sending a user message scrolls that item's top edge to the top of the scroll container. - The content wrapper inside `ChatScroller` gets a minimum height of the viewport so a one-line reply still leaves the anchored message at the top instead of springing back. - Once the anchored turn's content grows past the viewport, normal bottom-stick resumes — the user should end up following the stream as usual, not stranded at an anchor. CONSTRAINTS - `ChatScroller`'s existing `handleScroll` distinguishes our own programmatic pin's echo from a real user scroll (`pinnedAt`, `animating`, `stick` refs). An anchor scroll is ALSO programmatic and MUST NOT be read as the user detaching, or follow will silently disengage mid-turn. Extend that same discrimination; do not bolt on a second uncoordinated scroll path. - Keep the existing `useStick()` context shape. `ScrollToBottomButton` consumes it and must keep working, including its unread-count re-arming behaviour. - No new dependency. We deliberately hand-rolled this instead of taking `use-stick-to-bottom`. VERIFY - Extend `ChatScroller.test.tsx`: an anchored item scrolls to top; the anchor scroll does not clear the stick flag; bottom-stick resumes once content exceeds the viewport. jsdom has no `scrollTo` on elements — the existing tests already work around this, follow that approach. - Manually smoke on `/prototype/chat` (the specimen board at `src/pages/ChatPrototype/`) with a simulated turn, and on a real thread. - Do not land this concurrently with the `content-visibility` item — both touch `ChatScroller.tsx`.
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th:claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git rebase main
git switch main
git merge --ff-only claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git rebase main
git switch main
git merge --no-ff claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch main
git merge --squash claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch main
git merge --ff-only claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git switch main
git merge claude/wi-019ff173-pwa-chat-anchor-the-user-s-message-to-th
git push origin main
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
toasterson/Anima!605
No description provided.