fix: put unread separator above system messages and stop scrolling the host page on scroll to a message - #3305
Conversation
β¦ge scroll System messages count as unread (the server includes them in unread_messages) and jumpToFirstUnreadMessage can target one, but the unread separator skipped them and was rendered below the system message. The separator is now placed before the first unread message regardless of its type, in both MessageList and VirtualizedMessageList, so it always matches the jump target. Jumping to a highlighted message (first unread, quoted message) used Element.scrollIntoView, which also scrolls every scrollable ancestor. When the chat is embedded in a scrollable host page, the page moved. The list is now scrolled directly with scrollTo, centering the target. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Settings > General > Page layout > "Embedded in page" (or ?embedded_layout=1) renders the chat as a fixed-height widget between host-page content taller than the viewport, so the window scrolls too. Any scroll the SDK performs on an ancestor then shows up as the host page moving, which is how customers embedding the chat experience it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the βοΈ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Size Change: +375 B (+0.03%) Total Size: 1.09 MB π¦ View Changed
βΉοΈ View Unchanged
|
Codecov Reportβ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## release-v14 #3305 +/- ##
==============================================
Coverage ? 85.53%
==============================================
Files ? 512
Lines ? 16198
Branches ? 5127
==============================================
Hits ? 13855
Misses ? 2343
Partials ? 0 β View full report in Codecov by Harness. π New features to boost your workflow:
|
The composer focuses its textarea on mount (the `focus` prop) and when
attachments or the quoted message change. These focuses are not
triggered by the user, and a plain focus() scrolls every scrollable
ancestor to bring the textarea into view, so a chat embedded in a
scrollable page moved the page to the composer when a channel opened.
Both focus calls now pass { preventScroll: true }.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
## [14.12.1](v14.12.0...v14.12.1) (2026-09-30) ### Bug Fixes * put unread separator above system messages and stop scrolling the host page on scroll to a message ([#3305](#3305)) ([b470bef](b470bef))
|
π This PR is included in version 14.12.1 π The release is available on: Your semantic-release bot π¦π |
π― Goal
Closes REACT-1198 (https://linear.app/stream/issue/REACT-1198/jump-to-unread-lands-on-system-message-with-separator-below-it-and)
Reported by a customer on 14.10.0 (Zendesk 83846). If a system message (e.g. "X was added to the chat") follows the last read message, clicking the "N unread" notification had two problems:
π Implementation details
Separator placement (
renderMessages.tsx,VirtualizedMessageListComponents.tsx)unread_messages, andjumpToFirstUnreadMessagetargets the message right afterlast_read_message_id, whatever its type. The separator logic skipped system messages, so it ended up below them.List-only scrolling (
MessageList.tsx)element.scrollIntoView({ block: 'center' }), which scrolls every scrollable ancestor, including the host page.listElement.scrollTo, centering the target (newgetCenteredScrollTophelper). The existing settle pass reuses the same helper.Example app (separate commit)
?embedded_layout=1.Tests
MessageListandVirtualizedMessageList.scrollToand noscrollIntoView.yarn typesand eslint are clean.Checked in a browser (Chromium, release-v14 build, "Embedded in page" layout, channel with a system message after the last read one):
Composer autofocus (
TextareaComposer.tsx,useTextareaRef.ts)focusprop) and when attachments or the quoted message change. A plainfocus()scrolls every scrollable ancestor to bring the textarea into view, so opening a channel scrolled the host page down to the composer (0 β 689px).{ preventScroll: true }. Focus calls that follow a click inside the composer (command chip, menus, suggestions) are unchanged, since the element is already on screen.MessageInput.test.tsx: automatic focus passespreventScroll. With the embedded layout, the page now stays at 0 on load and the textarea is still focused.π¨ UI Changes
Only the separator position changes: it now sits above a system message that is the first unread message, instead of below it. The example app gains the "Embedded in page" layout option.